svn commit: r202201 - stable/8/lib/libc/stdtime
John Baldwin
jhb at FreeBSD.org
Wed Jan 13 18:12:22 UTC 2010
Author: jhb
Date: Wed Jan 13 18:12:21 2010
New Revision: 202201
URL: http://svn.freebsd.org/changeset/base/202201
Log:
MFC 199607, 200797, 201270, 201669:
Use pthread_once() to initialize the thread-local storage for localtime()
and gmtime() and _once() to initialize gmt state rather than home-rolled
versions using pthread mutex locks.
Modified:
stable/8/lib/libc/stdtime/localtime.c
Directory Properties:
stable/8/lib/libc/ (props changed)
stable/8/lib/libc/stdtime/ (props changed)
Modified: stable/8/lib/libc/stdtime/localtime.c
==============================================================================
--- stable/8/lib/libc/stdtime/localtime.c Wed Jan 13 18:09:54 2010 (r202200)
+++ stable/8/lib/libc/stdtime/localtime.c Wed Jan 13 18:12:21 2010 (r202201)
@@ -235,9 +235,14 @@ static struct state gmtmem;
static char lcl_TZname[TZ_STRLEN_MAX + 1];
static int lcl_is_set;
-static int gmt_is_set;
+static pthread_once_t gmt_once = PTHREAD_ONCE_INIT;
static pthread_rwlock_t lcl_rwlock = PTHREAD_RWLOCK_INITIALIZER;
-static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_once_t gmtime_once = PTHREAD_ONCE_INIT;
+static pthread_key_t gmtime_key;
+static int gmtime_key_error;
+static pthread_once_t localtime_once = PTHREAD_ONCE_INIT;
+static pthread_key_t localtime_key;
+static int localtime_key_error;
char * tzname[2] = {
wildabbr,
@@ -1407,27 +1412,24 @@ struct tm * const tmp;
return result;
}
+static void
+localtime_key_init(void)
+{
+
+ localtime_key_error = _pthread_key_create(&localtime_key, free);
+}
+
struct tm *
localtime(timep)
const time_t * const timep;
{
- static pthread_mutex_t localtime_mutex = PTHREAD_MUTEX_INITIALIZER;
- static pthread_key_t localtime_key = -1;
struct tm *p_tm;
- int r;
if (__isthreaded != 0) {
- if (localtime_key < 0) {
- _pthread_mutex_lock(&localtime_mutex);
- if (localtime_key < 0) {
- if ((r = _pthread_key_create(&localtime_key,
- free)) != 0) {
- _pthread_mutex_unlock(&localtime_mutex);
- errno = r;
- return(NULL);
- }
- }
- _pthread_mutex_unlock(&localtime_mutex);
+ _pthread_once(&localtime_once, localtime_key_init);
+ if (localtime_key_error != 0) {
+ errno = localtime_key_error;
+ return(NULL);
}
p_tm = _pthread_getspecific(localtime_key);
if (p_tm == NULL) {
@@ -1464,6 +1466,17 @@ struct tm * tmp;
return tmp;
}
+static void
+gmt_init(void)
+{
+
+#ifdef ALL_STATE
+ gmtptr = (struct state *) malloc(sizeof *gmtptr);
+ if (gmtptr != NULL)
+#endif /* defined ALL_STATE */
+ gmtload(gmtptr);
+}
+
/*
** gmtsub is to gmtime as localsub is to localtime.
*/
@@ -1476,16 +1489,7 @@ struct tm * const tmp;
{
register struct tm * result;
- _MUTEX_LOCK(&gmt_mutex);
- if (!gmt_is_set) {
-#ifdef ALL_STATE
- gmtptr = (struct state *) malloc(sizeof *gmtptr);
- if (gmtptr != NULL)
-#endif /* defined ALL_STATE */
- gmtload(gmtptr);
- gmt_is_set = TRUE;
- }
- _MUTEX_UNLOCK(&gmt_mutex);
+ _once(&gmt_once, gmt_init);
result = timesub(timep, offset, gmtptr, tmp);
#ifdef TM_ZONE
/*
@@ -1509,27 +1513,24 @@ struct tm * const tmp;
return result;
}
+static void
+gmtime_key_init(void)
+{
+
+ gmtime_key_error = _pthread_key_create(&gmtime_key, free);
+}
+
struct tm *
gmtime(timep)
const time_t * const timep;
{
- static pthread_mutex_t gmtime_mutex = PTHREAD_MUTEX_INITIALIZER;
- static pthread_key_t gmtime_key = -1;
struct tm *p_tm;
- int r;
if (__isthreaded != 0) {
- if (gmtime_key < 0) {
- _pthread_mutex_lock(&gmtime_mutex);
- if (gmtime_key < 0) {
- if ((r = _pthread_key_create(&gmtime_key,
- free)) != 0) {
- _pthread_mutex_unlock(&gmtime_mutex);
- errno = r;
- return(NULL);
- }
- }
- _pthread_mutex_unlock(&gmtime_mutex);
+ _pthread_once(&gmtime_once, gmtime_key_init);
+ if (gmtime_key_error != 0) {
+ errno = gmtime_key_error;
+ return(NULL);
}
/*
* Changed to follow POSIX.1 threads standard, which
More information about the svn-src-stable-8
mailing list