void __assfail(const char *assertion, const char *filename, int line_num) { char buf[800]; /* no assert() message in the library is this long */ ulwp_t *self; lwpid_t lwpid; /* avoid recursion deadlock */ if ((self = __curthread()) != NULL) { if (assert_thread == self) _exit(127); enter_critical(self); (void) _lwp_mutex_lock(&assert_lock); assert_thread = self; lwpid = self->ul_lwpid; } else { self = NULL; (void) _lwp_mutex_lock(&assert_lock); lwpid = _lwp_self(); } /* * This is a hack, but since the Abort function isn't exported * to outside consumers, libzpool's vpanic() function calls * assfail() with a filename set to NULL. In that case, it'd be * best not to print "assertion failed" since it was a panic and * not an assertion failure. */ if (filename == NULL) { (void) strcpy(buf, "failure for thread "); } else { (void) strcpy(buf, "assertion failed for thread "); } ultos((uint64_t)(uintptr_t)self, 16, buf + strlen(buf)); (void) strcat(buf, ", thread-id "); ultos((uint64_t)lwpid, 10, buf + strlen(buf)); (void) strcat(buf, ": "); (void) strcat(buf, assertion); if (filename != NULL) { (void) strcat(buf, ", file "); (void) strcat(buf, filename); (void) strcat(buf, ", line "); ultos((uint64_t)line_num, 10, buf + strlen(buf)); } (void) strcat(buf, "\n"); (void) __write(2, buf, strlen(buf)); /* * We could replace the call to Abort() with the following code * if we want just to issue a warning message and not die. * assert_thread = NULL; * _lwp_mutex_unlock(&assert_lock); * if (self != NULL) * exit_critical(self); */ Abort(buf); }
static void set_buffer_locks(bindhead * bhp) { int i; for (i = 0; i < bhp->bh_bktcnt; i++) (void) _lwp_mutex_lock(&bhp->bh_bkts[i].bb_lock); (void) _lwp_mutex_lock(&bhp->bh_strlock); (void) _lwp_mutex_lock(&bhp->bh_lock); }
static int prof_mutex_lock(lwp_mutex_t *mp, sigset_t *oset) { if (oset) (void) sigprocmask(SIG_BLOCK, &iset, oset); (void) _lwp_mutex_lock(mp); return (0); }
/*********************************************************************** * InterlockedDecrement (KERNEL32.@) */ LONG WINAPI InterlockedDecrement( PLONG dest ) { LONG retv; _lwp_mutex_lock( &interlocked_mutex ); retv = --*dest; _lwp_mutex_unlock( &interlocked_mutex ); return retv; }
void FLMAPI f_mutexLock( F_MUTEX hMutex) { for( ;;) { if( _lwp_mutex_lock( (lwp_mutex_t *)hMutex) == 0) { break; } } }
/*********************************************************************** * InterlockedExchangeAdd (KERNEL32.@) */ LONG WINAPI InterlockedExchangeAdd( PLONG dest, LONG incr ) { LONG retv; _lwp_mutex_lock( &interlocked_mutex ); retv = *dest; *dest += incr; _lwp_mutex_unlock( &interlocked_mutex ); return retv; }
/*********************************************************************** * InterlockedExchange (KERNEL32.@) */ LONG WINAPI InterlockedExchange( PLONG dest, LONG val ) { LONG retv; _lwp_mutex_lock( &interlocked_mutex ); retv = *dest; *dest = val; _lwp_mutex_unlock( &interlocked_mutex ); return retv; }
/* * Report a thread usage error. * Not called if _THREAD_ERROR_DETECTION=0. * Writes message and continues execution if _THREAD_ERROR_DETECTION=1. * Writes message and dumps core if _THREAD_ERROR_DETECTION=2. */ void thread_error(const char *msg) { char buf[800]; uberdata_t *udp; ulwp_t *self; lwpid_t lwpid; /* avoid recursion deadlock */ if ((self = __curthread()) != NULL) { if (assert_thread == self) _exit(127); enter_critical(self); (void) _lwp_mutex_lock(&assert_lock); assert_thread = self; lwpid = self->ul_lwpid; udp = self->ul_uberdata; } else { self = NULL; (void) _lwp_mutex_lock(&assert_lock); lwpid = _lwp_self(); udp = &__uberdata; } (void) strcpy(buf, "\n*** _THREAD_ERROR_DETECTION: " "thread usage error detected ***\n*** "); (void) strcat(buf, msg); (void) strcat(buf, "\n*** calling thread is "); ultos((uint64_t)(uintptr_t)self, 16, buf + strlen(buf)); (void) strcat(buf, " thread-id "); ultos((uint64_t)lwpid, 10, buf + strlen(buf)); (void) strcat(buf, "\n\n"); (void) __write(2, buf, strlen(buf)); if (udp->uberflags.uf_thread_error_detection >= 2) Abort(buf); assert_thread = NULL; (void) _lwp_mutex_unlock(&assert_lock); if (self != NULL) exit_critical(self); }
/*********************************************************************** * InterlockedCompareExchange (KERNEL32.@) */ LONG WINAPI InterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare ) { _lwp_mutex_lock( &interlocked_mutex ); if ( *dest == compare ) *dest = xchg; else compare = *dest; _lwp_mutex_unlock( &interlocked_mutex ); return compare; }
/* * Write a panic message w/o grabbing any locks other than assert_lock. * We have no idea what locks are held at this point. */ void common_panic(const char *head, const char *why) { char msg[400]; /* no panic() message in the library is this long */ ulwp_t *self; size_t len1, len2; if ((self = __curthread()) != NULL) enter_critical(self); (void) _lwp_mutex_lock(&assert_lock); (void) memset(msg, 0, sizeof (msg)); (void) strcpy(msg, head); len1 = strlen(msg); len2 = strlen(why); if (len1 + len2 >= sizeof (msg)) len2 = sizeof (msg) - len1 - 1; (void) strncat(msg, why, len2); len1 = strlen(msg); if (msg[len1 - 1] != '\n') msg[len1++] = '\n'; (void) __write(2, msg, len1); Abort(msg); }
/* * Called from exit() (atexit function) to give precedence * to assertion failures and a core dump over _exit(). */ void grab_assert_lock() { (void) _lwp_mutex_lock(&assert_lock); }
/* * Report application lock usage error for rwlocks. * Not called if _THREAD_ERROR_DETECTION=0. * Continue execution if _THREAD_ERROR_DETECTION=1. * Dump core if _THREAD_ERROR_DETECTION=2. */ void rwlock_error(const rwlock_t *rp, const char *who, const char *msg) { rwlock_t rcopy; uint32_t rwstate; char buf[800]; uberdata_t *udp; ulwp_t *self; lwpid_t lwpid; pid_t pid; int process; /* * Take a snapshot of the rwlock before it changes (we hope!). * Use memcpy() rather than 'rcopy = *rp' in case rp is unaligned. */ (void) memcpy(&rcopy, rp, sizeof (rcopy)); /* avoid recursion deadlock */ if ((self = __curthread()) != NULL) { if (assert_thread == self) _exit(127); enter_critical(self); (void) _lwp_mutex_lock(&assert_lock); assert_thread = self; lwpid = self->ul_lwpid; udp = self->ul_uberdata; pid = udp->pid; } else { self = NULL; (void) _lwp_mutex_lock(&assert_lock); lwpid = _lwp_self(); udp = &__uberdata; pid = getpid(); } rwstate = (uint32_t)rcopy.rwlock_readers; process = (rcopy.rwlock_type & USYNC_PROCESS); (void) strcpy(buf, "\n*** _THREAD_ERROR_DETECTION: lock usage error detected ***\n"); (void) strcat(buf, who); (void) strcat(buf, "("); ultos((uint64_t)(uintptr_t)rp, 16, buf + strlen(buf)); (void) strcat(buf, "): "); (void) strcat(buf, msg); (void) strcat(buf, "\ncalling thread is "); ultos((uint64_t)(uintptr_t)self, 16, buf + strlen(buf)); (void) strcat(buf, " thread-id "); ultos((uint64_t)lwpid, 10, buf + strlen(buf)); if (process) { (void) strcat(buf, " in process "); ultos((uint64_t)pid, 10, buf + strlen(buf)); } if (rwstate & URW_WRITE_LOCKED) { (void) strcat(buf, "\nthe writer lock owner is "); ultos((uint64_t)rcopy.rwlock_owner, 16, buf + strlen(buf)); if (process) { (void) strcat(buf, " in process "); ultos((uint64_t)rcopy.rwlock_ownerpid, 10, buf + strlen(buf)); } } else if (rwstate & URW_READERS_MASK) { (void) strcat(buf, "\nthe reader lock is held by "); ultos((uint64_t)(rwstate & URW_READERS_MASK), 10, buf + strlen(buf)); (void) strcat(buf, " readers"); } else { (void) strcat(buf, "\nthe lock is unowned"); } if (rwstate & URW_HAS_WAITERS) (void) strcat(buf, "\nand the lock appears to have waiters"); (void) strcat(buf, "\n\n"); (void) __write(2, buf, strlen(buf)); if (udp->uberflags.uf_thread_error_detection >= 2) Abort(buf); assert_thread = NULL; (void) _lwp_mutex_unlock(&assert_lock); if (self != NULL) exit_critical(self); }
/* * Report application lock usage error for mutexes and condvars. * Not called if _THREAD_ERROR_DETECTION=0. * Continue execution if _THREAD_ERROR_DETECTION=1. * Dump core if _THREAD_ERROR_DETECTION=2. */ void lock_error(const mutex_t *mp, const char *who, void *cv, const char *msg) { mutex_t mcopy; char buf[800]; uberdata_t *udp; ulwp_t *self; lwpid_t lwpid; pid_t pid; /* * Take a snapshot of the mutex before it changes (we hope!). * Use memcpy() rather than 'mcopy = *mp' in case mp is unaligned. */ (void) memcpy(&mcopy, mp, sizeof (mcopy)); /* avoid recursion deadlock */ if ((self = __curthread()) != NULL) { if (assert_thread == self) _exit(127); enter_critical(self); (void) _lwp_mutex_lock(&assert_lock); assert_thread = self; lwpid = self->ul_lwpid; udp = self->ul_uberdata; pid = udp->pid; } else { self = NULL; (void) _lwp_mutex_lock(&assert_lock); lwpid = _lwp_self(); udp = &__uberdata; pid = getpid(); } (void) strcpy(buf, "\n*** _THREAD_ERROR_DETECTION: lock usage error detected ***\n"); (void) strcat(buf, who); (void) strcat(buf, "("); if (cv != NULL) { ultos((uint64_t)(uintptr_t)cv, 16, buf + strlen(buf)); (void) strcat(buf, ", "); } ultos((uint64_t)(uintptr_t)mp, 16, buf + strlen(buf)); (void) strcat(buf, ")"); if (msg != NULL) { (void) strcat(buf, ": "); (void) strcat(buf, msg); } else if (!mutex_held(&mcopy)) { (void) strcat(buf, ": calling thread does not own the lock"); } else if (mcopy.mutex_rcount) { (void) strcat(buf, ": mutex rcount = "); ultos((uint64_t)mcopy.mutex_rcount, 10, buf + strlen(buf)); } else { (void) strcat(buf, ": calling thread already owns the lock"); } (void) strcat(buf, "\ncalling thread is "); ultos((uint64_t)(uintptr_t)self, 16, buf + strlen(buf)); (void) strcat(buf, " thread-id "); ultos((uint64_t)lwpid, 10, buf + strlen(buf)); if (msg != NULL || mutex_held(&mcopy)) /* EMPTY */; else if (mcopy.mutex_lockw == 0) (void) strcat(buf, "\nthe lock is unowned"); else if (!(mcopy.mutex_type & USYNC_PROCESS)) { (void) strcat(buf, "\nthe lock owner is "); ultos((uint64_t)mcopy.mutex_owner, 16, buf + strlen(buf)); } else { (void) strcat(buf, " in process "); ultos((uint64_t)pid, 10, buf + strlen(buf)); (void) strcat(buf, "\nthe lock owner is "); ultos((uint64_t)mcopy.mutex_owner, 16, buf + strlen(buf)); (void) strcat(buf, " in process "); ultos((uint64_t)mcopy.mutex_ownerpid, 10, buf + strlen(buf)); } (void) strcat(buf, "\n\n"); (void) __write(2, buf, strlen(buf)); if (udp->uberflags.uf_thread_error_detection >= 2) Abort(buf); assert_thread = NULL; (void) _lwp_mutex_unlock(&assert_lock); if (self != NULL) exit_critical(self); }