예제 #1
0
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);
}
예제 #2
0
파일: dumpbind.c 프로젝트: andreiw/polaris
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);
}
예제 #3
0
파일: profile.c 프로젝트: andreiw/polaris
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);
}
예제 #4
0
/***********************************************************************
 *		InterlockedDecrement (KERNEL32.@)
 */
LONG WINAPI InterlockedDecrement( PLONG dest )
{
    LONG retv;
    _lwp_mutex_lock( &interlocked_mutex );

    retv = --*dest;

    _lwp_mutex_unlock( &interlocked_mutex );
    return retv;
}
예제 #5
0
void FLMAPI f_mutexLock(
	F_MUTEX		hMutex)
{
	for( ;;)
	{
		if( _lwp_mutex_lock( (lwp_mutex_t *)hMutex) == 0)
		{
			break;
		}
	}
}
예제 #6
0
/***********************************************************************
 *		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;
}
예제 #7
0
/***********************************************************************
 *		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;
}
예제 #8
0
/*
 * 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);
}
예제 #9
0
/***********************************************************************
 *		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;
}
예제 #10
0
/*
 * 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);
}
예제 #11
0
/*
 * 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);
}
예제 #12
0
/*
 * 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);
}
예제 #13
0
/*
 * 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);
}