From owner-freebsd-bugs Sun Jan 14 18:40:26 2001 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id C339137B400 for ; Sun, 14 Jan 2001 18:40:06 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.1/8.11.1) id f0F2e6w52001; Sun, 14 Jan 2001 18:40:06 -0800 (PST) (envelope-from gnats) Date: Sun, 14 Jan 2001 18:40:06 -0800 (PST) Message-Id: <200101150240.f0F2e6w52001@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: Tor.Egge@fast.no Subject: Re: bin/15070: vfprintf/cvt/__dtoa race condition in threaded programs Reply-To: Tor.Egge@fast.no Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org The following reply was made to PR bin/15070; it has been noted by GNATS. From: Tor.Egge@fast.no To: freebsd-gnats-submit@FreeBSD.ORG Cc: Subject: Re: bin/15070: vfprintf/cvt/__dtoa race condition in threaded programs Date: Mon, 15 Jan 2001 03:35:04 +0100 One workaround for the race is to serialize vfprintf() calls that use floating point conversion specifications. Index: stdio/vfprintf.c =================================================================== RCS file: /home/ncvs/src/lib/libc/stdio/vfprintf.c,v retrieving revision 1.23 diff -u -r1.23 vfprintf.c --- stdio/vfprintf.c 2001/01/06 20:48:00 1.23 +++ stdio/vfprintf.c 2001/01/06 23:15:45 @@ -261,6 +261,17 @@ #include #include "floatio.h" +/* + * Serialize calls to cvt and __dtoa() and the usage of the result + * in threaded programs. + */ + +#include "libc_private.h" +#include "spinlock.h" +static spinlock_t thread_lock = _SPINLOCK_INITIALIZER; +#define THREAD_LOCK() if (__isthreaded) _SPINLOCK(&thread_lock); +#define THREAD_UNLOCK() if (__isthreaded) _SPINUNLOCK(&thread_lock); + #define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */ #define DEFPREC 6 @@ -271,6 +282,9 @@ #define BUF 68 +#define THREAD_LOCK() +#define THREAD_UNLOCK() + #endif /* FLOATING_POINT */ #define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */ @@ -303,6 +317,7 @@ int width; /* width from format (%8d), or 0 */ int prec; /* precision from format (%.3d), or -1 */ char sign; /* sign prefix (' ', '+', '-', or \0) */ + int didlock; /* have obtained thread lock */ #ifdef FLOATING_POINT char softsign; /* temporary negative sign for floats */ double _double; /* double precision arguments %[eEfgG] */ @@ -418,6 +433,7 @@ } + didlock = 0; FLOCKFILE(fp); /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ if (cantwrite(fp)) { @@ -608,6 +624,8 @@ break; } flags |= FPT; + THREAD_LOCK(); + didlock = 1; cp = cvt(_double, prec, flags, &softsign, &expt, ch, &ndig); if (ch == 'g' || ch == 'G') { @@ -849,6 +867,10 @@ PRINT(cp, 1); PRINT(expstr, expsize); } + if (didlock != 0) { + THREAD_UNLOCK(); + didlock = 0; + } } #else PRINT(cp, size); @@ -865,6 +887,10 @@ done: FLUSH(); error: + if (didlock != 0) { + THREAD_UNLOCK(); + didlock = 0; + } if (__sferror(fp)) ret = EOF; FUNLOCKFILE(fp); Index: stdlib/strtod.c =================================================================== RCS file: /home/ncvs/src/lib/libc/stdlib/strtod.c,v retrieving revision 1.3 diff -u -r1.3 strtod.c --- stdlib/strtod.c 1996/07/12 18:55:22 1.3 +++ stdlib/strtod.c 2000/06/15 03:48:29 @@ -371,6 +371,16 @@ static Bigint *freelist[Kmax+1]; + /* + * Make Balloc/Bfree thread-safe in libc for use with + * kernel threads. + */ +#include "libc_private.h" +#include "spinlock.h" +static spinlock_t thread_lock = _SPINLOCK_INITIALIZER; +#define THREAD_LOCK() if (__isthreaded) _SPINLOCK(&thread_lock); +#define THREAD_UNLOCK() if (__isthreaded) _SPINUNLOCK(&thread_lock); + static Bigint * Balloc #ifdef KR_headers @@ -382,9 +392,12 @@ int x; Bigint *rv; + THREAD_LOCK(); if ( (rv = freelist[k]) ) { freelist[k] = rv->next; + THREAD_UNLOCK(); } else { + THREAD_UNLOCK(); x = 1 << k; rv = (Bigint *)malloc(sizeof(Bigint) + (x-1)*sizeof(long)); rv->k = k; @@ -403,8 +416,10 @@ #endif { if (v) { + THREAD_LOCK(); v->next = freelist[v->k]; freelist[v->k] = v; + THREAD_UNLOCK(); } } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message