From owner-svn-src-user@FreeBSD.ORG Wed Nov 10 01:27:48 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B53491065672; Wed, 10 Nov 2010 01:27:48 +0000 (UTC) (envelope-from davidxu@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id A1DDB8FC17; Wed, 10 Nov 2010 01:27:48 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oAA1Rm2w069671; Wed, 10 Nov 2010 01:27:48 GMT (envelope-from davidxu@svn.freebsd.org) Received: (from davidxu@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oAA1Rmrh069656; Wed, 10 Nov 2010 01:27:48 GMT (envelope-from davidxu@svn.freebsd.org) Message-Id: <201011100127.oAA1Rmrh069656@svn.freebsd.org> From: David Xu Date: Wed, 10 Nov 2010 01:27:48 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r215071 - in user/davidxu/libthr: include lib/libc lib/libc/gen lib/libc/stdio lib/libthr lib/libthr/thread X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Nov 2010 01:27:48 -0000 Author: davidxu Date: Wed Nov 10 01:27:48 2010 New Revision: 215071 URL: http://svn.freebsd.org/changeset/base/215071 Log: Convert pthread_mutex_t and pthread_cond_t to structure based instead of pointer type, this allows us to support process-shared. Modified: user/davidxu/libthr/include/pthread.h user/davidxu/libthr/lib/libc/Makefile user/davidxu/libthr/lib/libc/gen/closedir.c user/davidxu/libthr/lib/libc/gen/opendir.c user/davidxu/libthr/lib/libc/gen/readdir.c user/davidxu/libthr/lib/libc/gen/seekdir.c user/davidxu/libthr/lib/libc/gen/telldir.c user/davidxu/libthr/lib/libc/stdio/_flock_stub.c user/davidxu/libthr/lib/libc/stdio/findfp.c user/davidxu/libthr/lib/libc/stdio/local.h user/davidxu/libthr/lib/libthr/Makefile user/davidxu/libthr/lib/libthr/pthread.map user/davidxu/libthr/lib/libthr/thread/thr_cond.c user/davidxu/libthr/lib/libthr/thread/thr_init.c user/davidxu/libthr/lib/libthr/thread/thr_mutex.c user/davidxu/libthr/lib/libthr/thread/thr_private.h Modified: user/davidxu/libthr/include/pthread.h ============================================================================== --- user/davidxu/libthr/include/pthread.h Wed Nov 10 00:56:44 2010 (r215070) +++ user/davidxu/libthr/include/pthread.h Wed Nov 10 01:27:48 2010 (r215071) @@ -92,14 +92,19 @@ /* * Static once initialization values. */ -#define PTHREAD_ONCE_INIT { PTHREAD_NEEDS_INIT, NULL } +#define PTHREAD_ONCE_INIT { PTHREAD_NEEDS_INIT } /* * Static initialization values. */ -#define PTHREAD_MUTEX_INITIALIZER NULL -#define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP ((pthread_mutex_t)1) -#define PTHREAD_COND_INITIALIZER NULL +#define PTHREAD_MUTEX_INITIALIZER \ + {PTHREAD_MUTEX_DEFAULT, 0, 0, NULL, 0, 0x0010, {0, 0}, 0, 0} + +#define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \ + {PTHREAD_MUTEX_DEFAULT, 2000, 0, NULL, 0, 0x0010, {0, 0}, 0, 0} + +#define PTHREAD_COND_INITIALIZER \ + {0, 0, 0, 0, 0, 0, 0, 0, 0, CLOCK_REALTIME} #define PTHREAD_RWLOCK_INITIALIZER NULL /* @@ -148,7 +153,34 @@ enum pthread_rwlocktype_np }; struct _pthread_cleanup_info { - __uintptr_t pthread_cleanup_pad[8]; + __uintptr_t __pthread_cleanup_pad[8]; +}; + +struct pthread_mutex { + __int16_t __flags; + __int16_t __spinloops; + __int32_t __recurse; + struct pthread *__ownertd; + /* kernel umtx part */ + volatile __uint32_t __lockword; + __uint32_t __lockflags; + __uint32_t __ceilings[2]; + __uint8_t __robstate; + __uint8_t __pad1; +}; + +struct pthread_cond { + __uint32_t __lock; + int __waiters; + int __signals; + __uint32_t __seq; + __uint64_t __broadcast_seq; + int __refcount; + int __destroying; + /* kernel part */ + __uint32_t __kern_has_waiters; + __uint32_t __flags; + __uint32_t __clock_id; }; /* Modified: user/davidxu/libthr/lib/libc/Makefile ============================================================================== --- user/davidxu/libthr/lib/libc/Makefile Wed Nov 10 00:56:44 2010 (r215070) +++ user/davidxu/libthr/lib/libc/Makefile Wed Nov 10 01:27:48 2010 (r215071) @@ -152,3 +152,4 @@ SSP_CFLAGS:= ${SSP_CFLAGS:S/^-fstack-pro SSP_CFLAGS:= ${.IMPSRC:N*/stack_protector.c:C/^.+$/${SSP_CFLAGS}/} # Generate stack unwinding tables for cancellation points CANCELPOINTS_CFLAGS:= ${.IMPSRC:Mcancelpoints_*:C/^.+$/${CANCELPOINTS_CFLAGS}/:C/^$//} +CFLAGS+=-g -O0 Modified: user/davidxu/libthr/lib/libc/gen/closedir.c ============================================================================== --- user/davidxu/libthr/lib/libc/gen/closedir.c Wed Nov 10 00:56:44 2010 (r215070) +++ user/davidxu/libthr/lib/libc/gen/closedir.c Wed Nov 10 01:27:48 2010 (r215071) @@ -54,7 +54,7 @@ closedir(dirp) int fd; if (__isthreaded) - _pthread_mutex_lock(&dirp->dd_lock); + _pthread_mutex_lock(dirp->dd_lock); _seekdir(dirp, dirp->dd_rewind); /* free seekdir storage */ fd = dirp->dd_fd; dirp->dd_fd = -1; @@ -62,8 +62,9 @@ closedir(dirp) free((void *)dirp->dd_buf); _reclaim_telldir(dirp); if (__isthreaded) { - _pthread_mutex_unlock(&dirp->dd_lock); - _pthread_mutex_destroy(&dirp->dd_lock); + _pthread_mutex_unlock(dirp->dd_lock); + _pthread_mutex_destroy(dirp->dd_lock); + free(dirp->dd_lock); } free((void *)dirp); return(_close(fd)); Modified: user/davidxu/libthr/lib/libc/gen/opendir.c ============================================================================== --- user/davidxu/libthr/lib/libc/gen/opendir.c Wed Nov 10 00:56:44 2010 (r215070) +++ user/davidxu/libthr/lib/libc/gen/opendir.c Wed Nov 10 01:27:48 2010 (r215071) @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -297,7 +298,8 @@ __opendir_common(int fd, const char *nam dirp->dd_loc = 0; dirp->dd_fd = fd; dirp->dd_flags = flags; - dirp->dd_lock = NULL; + dirp->dd_lock = malloc(sizeof(struct pthread_mutex)); + _pthread_mutex_init(dirp->dd_lock, NULL); /* * Set up seek point for rewinddir. Modified: user/davidxu/libthr/lib/libc/gen/readdir.c ============================================================================== --- user/davidxu/libthr/lib/libc/gen/readdir.c Wed Nov 10 00:56:44 2010 (r215070) +++ user/davidxu/libthr/lib/libc/gen/readdir.c Wed Nov 10 01:27:48 2010 (r215071) @@ -88,9 +88,9 @@ readdir(dirp) struct dirent *dp; if (__isthreaded) { - _pthread_mutex_lock(&dirp->dd_lock); + _pthread_mutex_lock(dirp->dd_lock); dp = _readdir_unlocked(dirp, 1); - _pthread_mutex_unlock(&dirp->dd_lock); + _pthread_mutex_unlock(dirp->dd_lock); } else dp = _readdir_unlocked(dirp, 1); @@ -109,10 +109,10 @@ readdir_r(dirp, entry, result) saved_errno = errno; errno = 0; if (__isthreaded) { - _pthread_mutex_lock(&dirp->dd_lock); + _pthread_mutex_lock(dirp->dd_lock); if ((dp = _readdir_unlocked(dirp, 1)) != NULL) memcpy(entry, dp, _GENERIC_DIRSIZ(dp)); - _pthread_mutex_unlock(&dirp->dd_lock); + _pthread_mutex_unlock(dirp->dd_lock); } else if ((dp = _readdir_unlocked(dirp, 1)) != NULL) memcpy(entry, dp, _GENERIC_DIRSIZ(dp)); Modified: user/davidxu/libthr/lib/libc/gen/seekdir.c ============================================================================== --- user/davidxu/libthr/lib/libc/gen/seekdir.c Wed Nov 10 00:56:44 2010 (r215070) +++ user/davidxu/libthr/lib/libc/gen/seekdir.c Wed Nov 10 01:27:48 2010 (r215071) @@ -52,8 +52,8 @@ seekdir(dirp, loc) long loc; { if (__isthreaded) - _pthread_mutex_lock(&dirp->dd_lock); + _pthread_mutex_lock(dirp->dd_lock); _seekdir(dirp, loc); if (__isthreaded) - _pthread_mutex_unlock(&dirp->dd_lock); + _pthread_mutex_unlock(dirp->dd_lock); } Modified: user/davidxu/libthr/lib/libc/gen/telldir.c ============================================================================== --- user/davidxu/libthr/lib/libc/gen/telldir.c Wed Nov 10 00:56:44 2010 (r215070) +++ user/davidxu/libthr/lib/libc/gen/telldir.c Wed Nov 10 01:27:48 2010 (r215071) @@ -64,13 +64,13 @@ telldir(dirp) if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL) return (-1); if (__isthreaded) - _pthread_mutex_lock(&dirp->dd_lock); + _pthread_mutex_lock(dirp->dd_lock); lp->loc_index = dirp->dd_td->td_loccnt++; lp->loc_seek = dirp->dd_seek; lp->loc_loc = dirp->dd_loc; LIST_INSERT_HEAD(&dirp->dd_td->td_locq, lp, loc_lqe); if (__isthreaded) - _pthread_mutex_unlock(&dirp->dd_lock); + _pthread_mutex_unlock(dirp->dd_lock); return (lp->loc_index); } Modified: user/davidxu/libthr/lib/libc/stdio/_flock_stub.c ============================================================================== --- user/davidxu/libthr/lib/libc/stdio/_flock_stub.c Wed Nov 10 00:56:44 2010 (r215070) +++ user/davidxu/libthr/lib/libc/stdio/_flock_stub.c Wed Nov 10 01:27:48 2010 (r215071) @@ -67,7 +67,7 @@ _flockfile(FILE *fp) * Make sure this mutex is treated as a private * internal mutex: */ - _pthread_mutex_lock(&fp->_fl_mutex); + _pthread_mutex_lock(fp->_fl_mutex); fp->_fl_owner = curthread; fp->_fl_count = 1; } @@ -94,7 +94,7 @@ _ftrylockfile(FILE *fp) * Make sure this mutex is treated as a private * internal mutex: */ - else if (_pthread_mutex_trylock(&fp->_fl_mutex) == 0) { + else if (_pthread_mutex_trylock(fp->_fl_mutex) == 0) { fp->_fl_owner = curthread; fp->_fl_count = 1; } @@ -130,7 +130,7 @@ _funlockfile(FILE *fp) */ fp->_fl_count = 0; fp->_fl_owner = NULL; - _pthread_mutex_unlock(&fp->_fl_mutex); + _pthread_mutex_unlock(fp->_fl_mutex); } } } Modified: user/davidxu/libthr/lib/libc/stdio/findfp.c ============================================================================== --- user/davidxu/libthr/lib/libc/stdio/findfp.c Wed Nov 10 00:56:44 2010 (r215070) +++ user/davidxu/libthr/lib/libc/stdio/findfp.c Wed Nov 10 01:27:48 2010 (r215071) @@ -36,6 +36,7 @@ static char sccsid[] = "@(#)findfp.c 8.2 #include __FBSDID("$FreeBSD$"); +#include "namespace.h" #include #include #include @@ -48,12 +49,14 @@ __FBSDID("$FreeBSD$"); #include "libc_private.h" #include "local.h" #include "glue.h" +#include "un-namespace.h" int __sdidinit; #define NDYNAMIC 10 /* add ten more whenever necessary */ -#define std(flags, file) { \ + +#define std(flags, file, lock) { \ ._flags = (flags), \ ._file = (file), \ ._cookie = __sF + (file), \ @@ -61,16 +64,21 @@ int __sdidinit; ._read = __sread, \ ._seek = __sseek, \ ._write = __swrite, \ - ._fl_mutex = PTHREAD_MUTEX_INITIALIZER, \ + ._fl_mutex = &lock, \ } /* the usual - (stdin + stdout + stderr) */ static FILE usual[FOPEN_MAX - 3]; static struct glue uglue = { NULL, FOPEN_MAX - 3, usual }; +static pthread_mutex_t sfLOCK[3] = { + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER +}; static FILE __sF[3] = { - std(__SRD, STDIN_FILENO), - std(__SWR, STDOUT_FILENO), - std(__SWR|__SNBF, STDERR_FILENO) + std(__SRD, STDIN_FILENO, sfLOCK[0]), + std(__SWR, STDOUT_FILENO, sfLOCK[1]), + std(__SWR|__SNBF, STDERR_FILENO, sfLOCK[2]) }; FILE *__stdinp = &__sF[0]; @@ -97,7 +105,7 @@ moreglue(n) int n; { struct glue *g; - static FILE empty = { ._fl_mutex = PTHREAD_MUTEX_INITIALIZER }; + static FILE empty = { ._fl_mutex = NULL }; FILE *p; g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE)); @@ -155,7 +163,10 @@ found: fp->_ub._size = 0; fp->_lb._base = NULL; /* no line buffer */ fp->_lb._size = 0; -/* fp->_fl_mutex = NULL; */ /* once set always set (reused) */ + if (fp->_fl_mutex == NULL) { /* once set always set (reused) */ + fp->_fl_mutex = malloc(sizeof(struct pthread_mutex)); + _pthread_mutex_init(fp->_fl_mutex, NULL); + } fp->_orientation = 0; memset(&fp->_mbstate, 0, sizeof(mbstate_t)); return (fp); Modified: user/davidxu/libthr/lib/libc/stdio/local.h ============================================================================== --- user/davidxu/libthr/lib/libc/stdio/local.h Wed Nov 10 00:56:44 2010 (r215070) +++ user/davidxu/libthr/lib/libc/stdio/local.h Wed Nov 10 01:27:48 2010 (r215071) @@ -114,7 +114,7 @@ extern int __sdidinit; */ #define FAKE_FILE { \ ._file = -1, \ - ._fl_mutex = PTHREAD_MUTEX_INITIALIZER, \ + ._fl_mutex = NULL, \ } /* Modified: user/davidxu/libthr/lib/libthr/Makefile ============================================================================== --- user/davidxu/libthr/lib/libthr/Makefile Wed Nov 10 00:56:44 2010 (r215070) +++ user/davidxu/libthr/lib/libthr/Makefile Wed Nov 10 01:27:48 2010 (r215071) @@ -40,7 +40,7 @@ MAN= libthr.3 # enable extra internal consistancy checks CFLAGS+=-D_PTHREADS_INVARIANTS -#CFLAGS+=-g +CFLAGS+=-g -O0 PRECIOUSLIB= Modified: user/davidxu/libthr/lib/libthr/pthread.map ============================================================================== --- user/davidxu/libthr/lib/libthr/pthread.map Wed Nov 10 00:56:44 2010 (r215070) +++ user/davidxu/libthr/lib/libthr/pthread.map Wed Nov 10 01:27:48 2010 (r215071) @@ -55,12 +55,6 @@ FBSD_1.0 { pthread_cancel; pthread_cleanup_pop; pthread_cleanup_push; - pthread_cond_broadcast; - pthread_cond_destroy; - pthread_cond_init; - pthread_cond_signal; - pthread_cond_timedwait; - pthread_cond_wait; pthread_condattr_destroy; pthread_condattr_getclock; pthread_condattr_getpshared; @@ -81,14 +75,6 @@ FBSD_1.0 { pthread_kill; pthread_main_np; pthread_multi_np; - pthread_mutex_destroy; - pthread_mutex_getprioceiling; - pthread_mutex_init; - pthread_mutex_lock; - pthread_mutex_setprioceiling; - pthread_mutex_timedlock; - pthread_mutex_trylock; - pthread_mutex_unlock; pthread_mutexattr_destroy; pthread_mutexattr_getkind_np; pthread_mutexattr_getprioceiling; @@ -395,18 +381,32 @@ FBSD_1.1 { pthread_getaffinity_np; pthread_getcpuclockid; pthread_setaffinity_np; - pthread_mutex_getspinloops_np; - pthread_mutex_getyieldloops_np; - pthread_mutex_isowned_np; - pthread_mutex_setspinloops_np; - pthread_mutex_setyieldloops_np; }; FBSD_1.2 { openat; - setcontext; - swapcontext; + pthread_cond_broadcast; + pthread_cond_destroy; + pthread_cond_init; + pthread_cond_signal; + pthread_cond_timedwait; + pthread_cond_wait; + pthread_mutex_destroy; pthread_mutexattr_getrobust; pthread_mutexattr_setrobust; pthread_mutex_consistent; + pthread_mutex_getprioceiling; + pthread_mutex_getspinloops_np; + pthread_mutex_getyieldloops_np; + pthread_mutex_init; + pthread_mutex_isowned_np; + pthread_mutex_lock; + pthread_mutex_setprioceiling; + pthread_mutex_setspinloops_np; + pthread_mutex_setyieldloops_np; + pthread_mutex_timedlock; + pthread_mutex_trylock; + pthread_mutex_unlock; + setcontext; + swapcontext; }; Modified: user/davidxu/libthr/lib/libthr/thread/thr_cond.c ============================================================================== --- user/davidxu/libthr/lib/libthr/thread/thr_cond.c Wed Nov 10 00:56:44 2010 (r215070) +++ user/davidxu/libthr/lib/libthr/thread/thr_cond.c Wed Nov 10 01:27:48 2010 (r215071) @@ -61,114 +61,68 @@ __weak_reference(_pthread_cond_destroy, __weak_reference(_pthread_cond_signal, pthread_cond_signal); __weak_reference(_pthread_cond_broadcast, pthread_cond_broadcast); -#define CV_PSHARED(cv) (((cv)->c_kerncv.c_flags & USYNC_PROCESS_SHARED) != 0) +int _pthread_cond_init_1_0(pthread_cond_old_t *, const pthread_condattr_t *); +int _pthread_cond_signal_1_0(pthread_cond_old_t *); +int _pthread_cond_destroy_1_0(pthread_cond_old_t *); +int _pthread_cond_wait_1_0(pthread_cond_old_t *, pthread_mutex_old_t *); +int _pthread_cond_timedwait_1_0(pthread_cond_old_t *, pthread_mutex_old_t *, + const struct timespec *); +int _pthread_cond_broadcast_1_0(pthread_cond_old_t *); + +#define CV_PSHARED(cvp) (((cvp)->__flags & USYNC_PROCESS_SHARED) != 0) static int -cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr) +cond_init(struct pthread_cond *cvp, const pthread_condattr_t *cond_attr) { - pthread_cond_t pcond; - int rval = 0; + int error = 0; - if ((pcond = (pthread_cond_t) - calloc(1, sizeof(struct pthread_cond))) == NULL) { - rval = ENOMEM; + /* + * Initialise the condition variable structure: + */ + memset(cvp, 0, sizeof(*cvp)); + if (cond_attr == NULL || *cond_attr == NULL) { + cvp->__clock_id = CLOCK_REALTIME; } else { - /* - * Initialise the condition variable structure: - */ - if (cond_attr == NULL || *cond_attr == NULL) { - pcond->c_kerncv.c_clockid = CLOCK_REALTIME; - } else { - if ((*cond_attr)->c_pshared) - pcond->c_kerncv.c_flags |= USYNC_PROCESS_SHARED; - pcond->c_kerncv.c_clockid = (*cond_attr)->c_clockid; - } - pcond->c_kerncv.c_flags |= UCOND_BIND_MUTEX; - *cond = pcond; + if ((*cond_attr)->c_pshared) + cvp->__flags |= USYNC_PROCESS_SHARED; + cvp->__clock_id = (*cond_attr)->c_clockid; } - /* Return the completion status: */ - return (rval); -} - -static int -init_static(struct pthread *thread, pthread_cond_t *cond) -{ - int error; - - THR_LOCK_ACQUIRE(thread, &_cond_static_lock); - - if (*cond == NULL) - error = cond_init(cond, NULL); - else - error = 0; - - THR_LOCK_RELEASE(thread, &_cond_static_lock); - return (error); } -#define CHECK_AND_INIT_COND \ - if (__predict_false((cv = (*cond)) <= THR_COND_DESTROYED)) { \ - if (cv == THR_COND_INITIALIZER) { \ - int error; \ - error = init_static(_get_curthread(), cond); \ - if (error) \ - return (error); \ - } else if (cv == THR_COND_DESTROYED) { \ - return (EINVAL); \ - } \ - cv = *cond; \ - } - int _pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr) { - *cond = NULL; return (cond_init(cond, cond_attr)); } int -_pthread_cond_destroy(pthread_cond_t *cond) +_pthread_cond_destroy(pthread_cond_t *cvp) { - struct pthread_cond *cv; - int rval = 0; + int error = 0; - if ((cv = *cond) == THR_COND_INITIALIZER) - rval = 0; - else if (cv == THR_COND_DESTROYED) - rval = EINVAL; - else { - cv = *cond; - if (cv->c_refcount == 0) - goto next; - _thr_umtx_lock_spin(&cv->c_lock); - while (cv->c_refcount != 0) { - cv->c_destroying = 1; - if (cv->c_waiters > 0) { - cv->c_seq++; - cv->c_broadcast_seq++; - cv->c_waiters = 0; - cv->c_signals = 0; - _thr_umtx_wake(&cv->c_seq, INT_MAX, CV_PSHARED(cv)); - } - _thr_umtx_unlock(&cv->c_lock); - _thr_umtx_wait_uint((u_int *)&cv->c_destroying, - 1, NULL, CV_PSHARED(cv)); - _thr_umtx_lock_spin(&cv->c_lock); + if (cvp->__refcount == 0) + goto next; + _thr_umtx_lock_spin(&cvp->__lock); + while (cvp->__refcount != 0) { + cvp->__destroying = 1; + if (cvp->__waiters > 0) { + cvp->__seq++; + cvp->__broadcast_seq++; + cvp->__waiters = 0; + cvp->__signals = 0; + _thr_umtx_wake(&cvp->__seq, INT_MAX, CV_PSHARED(cvp)); } - _thr_umtx_unlock(&cv->c_lock); - next: - _thr_ucond_broadcast(&cv->c_kerncv); - *cond = THR_COND_DESTROYED; - - /* - * Free the memory allocated for the condition - * variable structure: - */ - free(cv); - } - return (rval); + _thr_umtx_unlock(&cvp->__lock); + _thr_umtx_wait_uint((u_int *)&cvp->__destroying, + 1, NULL, CV_PSHARED(cvp)); + _thr_umtx_lock_spin(&cvp->__lock); + } + _thr_umtx_unlock(&cvp->__lock); +next: + _thr_ucond_broadcast((struct ucond *)&cvp->__kern_has_waiters); + return (error); } /* @@ -180,28 +134,26 @@ _pthread_cond_destroy(pthread_cond_t *co * to be lost. */ static int -cond_wait_kernel(pthread_cond_t *cond, pthread_mutex_t *mutex, +cond_wait_kernel(struct pthread_cond *cvp, struct pthread_mutex *mp, const struct timespec *abstime, int cancel) { struct pthread *curthread = _get_curthread(); - pthread_cond_t cv; - struct pthread_mutex *m; int recurse; int error, error2 = 0; - cv = *cond; - error = _mutex_cv_detach(mutex, &recurse); + error = _mutex_cv_detach(mp, &recurse); if (__predict_false(error != 0)) return (error); - m = *mutex; if (cancel) { _thr_cancel_enter2(curthread, 0); - error = _thr_ucond_wait(&cv->c_kerncv, &m->m_lock, abstime, + error = _thr_ucond_wait((struct ucond *)&cvp->__kern_has_waiters, + (struct umutex *)&mp->__lockword, abstime, CVWAIT_ABSTIME|CVWAIT_CLOCKID); _thr_cancel_leave(curthread, 0); } else { - error = _thr_ucond_wait(&cv->c_kerncv, &m->m_lock, abstime, + error = _thr_ucond_wait((struct ucond *)&cvp->__kern_has_waiters, + (struct umutex *)&mp->__lockword, abstime, CVWAIT_ABSTIME|CVWAIT_CLOCKID); } @@ -210,16 +162,16 @@ cond_wait_kernel(pthread_cond_t *cond, p * interesting error codes. */ if (error == 0) { - error2 = _mutex_cv_lock(mutex, recurse); + error2 = _mutex_cv_lock(mp, recurse); } else if (error == EINTR || error == ETIMEDOUT) { - error2 = _mutex_cv_lock(mutex, recurse); + error2 = _mutex_cv_lock(mp, recurse); if (error2 == 0 && cancel) _thr_testcancel(curthread); if (error2 == EINTR) error = 0; } else { /* We know that it didn't unlock the mutex. */ - error2 = _mutex_cv_attach(mutex, recurse); + error2 = _mutex_cv_attach(mp, recurse); if (error2 == 0 && cancel) _thr_testcancel(curthread); } @@ -227,38 +179,36 @@ cond_wait_kernel(pthread_cond_t *cond, p } static int -cond_wait_user(pthread_cond_t *cond, pthread_mutex_t *mutex, +cond_wait_user(struct pthread_cond *cvp, struct pthread_mutex *mp, const struct timespec *abstime, int cancel) { struct pthread *curthread = _get_curthread(); struct timespec ts, ts2, *tsp; int recurse; - pthread_cond_t cv; int error; uint64_t seq, bseq; - cv = *cond; - _thr_umtx_lock_spin(&cv->c_lock); - if (cv->c_destroying) { - _thr_umtx_unlock(&cv->c_lock); + _thr_umtx_lock_spin(&cvp->__lock); + if (cvp->__destroying) { + _thr_umtx_unlock(&cvp->__lock); return (EINVAL); } - cv->c_waiters++; - error = _mutex_cv_unlock(mutex, &recurse); + cvp->__waiters++; + error = _mutex_cv_unlock(mp, &recurse); if (__predict_false(error != 0)) { - cv->c_waiters--; - _thr_umtx_unlock(&cv->c_lock); + cvp->__waiters--; + _thr_umtx_unlock(&cvp->__lock); return (error); } - bseq = cv->c_broadcast_seq; - cv->c_refcount++; + bseq = cvp->__broadcast_seq; + cvp->__refcount++; for(;;) { - seq = cv->c_seq; - _thr_umtx_unlock(&cv->c_lock); + seq = cvp->__seq; + _thr_umtx_unlock(&cvp->__lock); if (abstime != NULL) { - clock_gettime(cv->c_kerncv.c_clockid, &ts); + clock_gettime(cvp->__clock_id, &ts); TIMESPEC_SUB(&ts2, abstime, &ts); tsp = &ts2; } else @@ -266,73 +216,63 @@ cond_wait_user(pthread_cond_t *cond, pth if (cancel) { _thr_cancel_enter2(curthread, 0); - error = _thr_umtx_wait_uint((u_int *)&cv->c_seq, - (u_int)seq, tsp, CV_PSHARED(cv)); + error = _thr_umtx_wait_uint((u_int *)&cvp->__seq, + (u_int)seq, tsp, CV_PSHARED(cvp)); _thr_cancel_leave(curthread, 0); } else { - error = _thr_umtx_wait_uint((u_int *)&cv->c_seq, - (u_int)seq, tsp, CV_PSHARED(cv)); + error = _thr_umtx_wait_uint((u_int *)&cvp->__seq, + (u_int)seq, tsp, CV_PSHARED(cvp)); } - _thr_umtx_lock_spin(&cv->c_lock); - if (cv->c_broadcast_seq != bseq) { - cv->c_refcount--; + _thr_umtx_lock_spin(&cvp->__lock); + if (cvp->__broadcast_seq != bseq) { + cvp->__refcount--; error = 0; break; } - if (cv->c_signals > 0) { - cv->c_refcount--; - cv->c_signals--; + if (cvp->__signals > 0) { + cvp->__refcount--; + cvp->__signals--; error = 0; break; } else if (error == ETIMEDOUT) { - cv->c_refcount--; - cv->c_waiters--; + cvp->__refcount--; + cvp->__waiters--; break; } else if (cancel && SHOULD_CANCEL(curthread) && !THR_IN_CRITICAL(curthread)) { - cv->c_waiters--; - cv->c_refcount--; - if (cv->c_destroying && cv->c_refcount == 0) { - cv->c_destroying = 2; - _thr_umtx_wake(&cv->c_destroying, INT_MAX, CV_PSHARED(cv)); + cvp->__waiters--; + cvp->__refcount--; + if (cvp->__destroying && cvp->__refcount == 0) { + cvp->__destroying = 2; + _thr_umtx_wake(&cvp->__destroying, INT_MAX, CV_PSHARED(cvp)); } - _thr_umtx_unlock(&cv->c_lock); - _mutex_cv_lock(mutex, recurse); + _thr_umtx_unlock(&cvp->__lock); + _mutex_cv_lock(mp, recurse); _pthread_exit(PTHREAD_CANCELED); } } - if (cv->c_destroying && cv->c_refcount == 0) { - cv->c_destroying = 2; - _thr_umtx_wake(&cv->c_destroying, INT_MAX, CV_PSHARED(cv)); + if (cvp->__destroying && cvp->__refcount == 0) { + cvp->__destroying = 2; + _thr_umtx_wake(&cvp->__destroying, INT_MAX, CV_PSHARED(cvp)); } - _thr_umtx_unlock(&cv->c_lock); - _mutex_cv_lock(mutex, recurse); + _thr_umtx_unlock(&cvp->__lock); + _mutex_cv_lock(mp, recurse); return (error); } static int -cond_wait_common(pthread_cond_t *cond, pthread_mutex_t *mutex, +cond_wait_common(struct pthread_cond *cvp, struct pthread_mutex *mp, const struct timespec *abstime, int cancel) { struct pthread *curthread = _get_curthread(); - struct pthread_mutex *m; - pthread_cond_t cv; - int err; - - /* - * If the condition variable is statically initialized, - * perform the dynamic initialization: - */ - CHECK_AND_INIT_COND - - if ((err = _mutex_owned(curthread, mutex)) != 0) - return (err); + int error; - m = *mutex; + if ((error = _mutex_owned(curthread, mp)) != 0) + return (error); - if ((m->m_lock.m_flags & USYNC_PROCESS_SHARED) != - (cv->c_kerncv.c_flags & USYNC_PROCESS_SHARED)) + if ((mp->__lockflags & USYNC_PROCESS_SHARED) != + (cvp->__flags & USYNC_PROCESS_SHARED)) return (EINVAL); /* @@ -342,31 +282,31 @@ cond_wait_common(pthread_cond_t *cond, p * Note that if it is robust type of mutex, we should not use * the internal lock too, because it is not robust. */ - if (curthread->attr.sched_policy != SCHED_OTHER || + if (1 || curthread->attr.sched_policy != SCHED_OTHER || curthread->priority_mutex_count != 0 || - (m->m_lock.m_flags & (UMUTEX_PRIO_PROTECT|UMUTEX_PRIO_INHERIT| + (mp->__lockflags & (UMUTEX_PRIO_PROTECT|UMUTEX_PRIO_INHERIT| UMUTEX_ROBUST)) != 0) - return cond_wait_kernel(cond, mutex, abstime, cancel); + return cond_wait_kernel(cvp, mp, abstime, cancel); else - return cond_wait_user(cond, mutex, abstime, cancel); + return cond_wait_user(cvp, mp, abstime, cancel); } int -_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) +_pthread_cond_wait(pthread_cond_t *cvp, pthread_mutex_t *mp) { - return (cond_wait_common(cond, mutex, NULL, 0)); + return (cond_wait_common(cvp, mp, NULL, 0)); } int -__pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) +__pthread_cond_wait(pthread_cond_t *cvp, pthread_mutex_t *mp) { - return (cond_wait_common(cond, mutex, NULL, 1)); + return (cond_wait_common(cvp, mp, NULL, 1)); } int -_pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, +_pthread_cond_timedwait(pthread_cond_t *cvp, pthread_mutex_t *mp, const struct timespec * abstime) { @@ -374,65 +314,159 @@ _pthread_cond_timedwait(pthread_cond_t * abstime->tv_nsec >= 1000000000) return (EINVAL); - return (cond_wait_common(cond, mutex, abstime, 0)); + return (cond_wait_common(cvp, mp, abstime, 0)); } int -__pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, - const struct timespec *abstime) +__pthread_cond_timedwait(pthread_cond_t *cvp, pthread_mutex_t *mp, + const struct timespec * abstime) { if (abstime == NULL || abstime->tv_sec < 0 || abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) return (EINVAL); - return (cond_wait_common(cond, mutex, abstime, 1)); + return (cond_wait_common(cvp, mp, abstime, 1)); } static int -cond_signal_common(struct pthread_cond *cv) +cond_signal_common(struct pthread_cond *cvp) { - _thr_ucond_signal(&cv->c_kerncv); + _thr_ucond_signal((struct ucond *)&cvp->__kern_has_waiters); - if (cv->c_waiters == 0) + if (cvp->__waiters == 0) return (0); - _thr_umtx_lock_spin(&cv->c_lock); - if (cv->c_waiters > 0) { - cv->c_seq++; - cv->c_signals++; - cv->c_waiters--; - _thr_umtx_wake(&cv->c_seq, 1, CV_PSHARED(cv)); + _thr_umtx_lock_spin(&cvp->__lock); + if (cvp->__waiters > 0) { + cvp->__seq++; + cvp->__signals++; + cvp->__waiters--; + _thr_umtx_wake(&cvp->__seq, 1, CV_PSHARED(cvp)); } - _thr_umtx_unlock(&cv->c_lock); + _thr_umtx_unlock(&cvp->__lock); return (0); } static int -cond_broadcast_common(struct pthread_cond *cv) +cond_broadcast_common(struct pthread_cond *cvp) { - _thr_ucond_broadcast(&cv->c_kerncv); - if (cv->c_waiters == 0) + _thr_ucond_broadcast((struct ucond *)&cvp->__kern_has_waiters); + + if (cvp->__waiters == 0) return (0); - _thr_umtx_lock_spin(&cv->c_lock); - if (cv->c_waiters > 0) { - cv->c_seq++; - cv->c_broadcast_seq++; - cv->c_waiters = 0; - cv->c_signals = 0; - _thr_umtx_wake(&cv->c_seq, INT_MAX, CV_PSHARED(cv)); + _thr_umtx_lock_spin(&cvp->__lock); + if (cvp->__waiters > 0) { + cvp->__seq++; + cvp->__broadcast_seq++; + cvp->__waiters = 0; + cvp->__signals = 0; + _thr_umtx_wake(&cvp->__seq, INT_MAX, CV_PSHARED(cvp)); } - _thr_umtx_unlock(&cv->c_lock); + _thr_umtx_unlock(&cvp->__lock); return (0); } int -_pthread_cond_signal(pthread_cond_t * cond) +_pthread_cond_signal(pthread_cond_t *cvp) +{ + return (cond_signal_common(cvp)); +} + +int +_pthread_cond_broadcast(pthread_cond_t *cvp) +{ + return (cond_broadcast_common(cvp)); +} + +#define CHECK_AND_INIT_COND \ + if (__predict_false((cvp = (*cond)) <= THR_COND_DESTROYED)) { \ + if (cvp == THR_COND_INITIALIZER) { \ + int error; \ + error = init_static(_get_curthread(), cond); \ + if (error) \ + return (error); \ + } else if (cvp == THR_COND_DESTROYED) { \ + return (EINVAL); \ + } \ + cvp = *cond; \ + } + +static int +cond_init_old(pthread_cond_old_t *cond, const pthread_condattr_t *cond_attr) +{ + struct pthread_cond *cvp = NULL; + int error = 0; + + if ((cvp = (struct pthread_cond *) + calloc(1, sizeof(struct pthread_cond))) == NULL) { + error = ENOMEM; + } else { + error = cond_init(cvp, cond_attr); + if (error != 0) + free(cvp); + else + *cond = cvp; + } + return (error); +} + +static int +init_static(struct pthread *thread, pthread_cond_old_t *cond) +{ + int error; + + THR_LOCK_ACQUIRE(thread, &_cond_static_lock); + + if (*cond == NULL) + error = cond_init_old(cond, NULL); + else + error = 0; + + THR_LOCK_RELEASE(thread, &_cond_static_lock); + + return (error); +} + +int +_pthread_cond_init_1_0(pthread_cond_old_t *cond, const pthread_condattr_t *cond_attr) +{ + + *cond = NULL; + return (cond_init_old(cond, cond_attr)); +} + +int +_pthread_cond_destroy_1_0(pthread_cond_old_t *cond) { - pthread_cond_t cv; + struct pthread_cond *cvp; + int error = 0; + + if ((cvp = *cond) == THR_COND_INITIALIZER) + error = 0; + else if (cvp == THR_COND_DESTROYED) + error = EINVAL; + else { + cvp = *cond; + /* XXX */ + *cond = THR_COND_DESTROYED; + + /* + * Free the memory allocated for the condition + * variable structure: + */ + free(cvp); + } + return (error); +} + +int +_pthread_cond_signal_1_0(pthread_cond_old_t *cond) +{ + pthread_cond_t *cvp; /* * If the condition variable is statically initialized, perform dynamic @@ -440,13 +474,13 @@ _pthread_cond_signal(pthread_cond_t * co */ CHECK_AND_INIT_COND - return (cond_signal_common(cv)); + return (cond_signal_common(cvp)); } int -_pthread_cond_broadcast(pthread_cond_t * cond) +_pthread_cond_broadcast_1_0(pthread_cond_old_t *cond) { - pthread_cond_t cv; + pthread_cond_t *cvp; /* * If the condition variable is statically initialized, perform dynamic @@ -454,5 +488,49 @@ _pthread_cond_broadcast(pthread_cond_t * */ CHECK_AND_INIT_COND - return (cond_broadcast_common(cv)); + return (cond_broadcast_common(cvp)); } + +int +_pthread_cond_wait_1_0(pthread_cond_old_t *cond, pthread_mutex_old_t *mutex) +{ + pthread_cond_t *cvp; + int error; + + /* + * If the condition variable is statically initialized, perform dynamic + * initialization. + */ + CHECK_AND_INIT_COND + + if ((error = _mutex_owned_old(_get_curthread(), mutex)) != 0) *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***