Revert "rt: Remove lock_held_by_current_thread"

Adds back the ability to make assertions about locks, but only under the
--enable-debug configuration

This reverts commit b247de64583e2ab527088813ba9192824554e801.

Conflicts:

	src/rt/rust_sched_loop.cpp
This commit is contained in:
Brian Anderson 2012-03-30 18:37:30 -07:00
parent 609144f7a6
commit c8dc6fcb4c
6 changed files with 111 additions and 0 deletions

View File

@ -389,6 +389,34 @@
fun:uv_loop_delete
}
{
lock_and_signal-probably-threadsafe-access-outside-of-lock
Helgrind:Race
fun:_ZN15lock_and_signal27lock_held_by_current_threadEv
...
}
{
lock_and_signal-probably-threadsafe-access-outside-of-lock2
Helgrind:Race
fun:_ZN15lock_and_signal6unlockEv
...
}
{
lock_and_signal-probably-threadsafe-access-outside-of-lock3
Helgrind:Race
fun:_ZN15lock_and_signal4lockEv
...
}
{
lock_and_signal-probably-threadsafe-access-outside-of-lock4
Helgrind:Race
fun:_ZN15lock_and_signal4waitEv
...
}
{
uv-async-send-does-racy-things
Helgrind:Race

View File

@ -69,6 +69,8 @@ void
rust_port_selector::msg_sent_on(rust_port *port) {
rust_task *task = port->task;
port->lock.must_not_have_lock();
// Prevent two ports from trying to wake up the task
// simultaneously
scoped_lock with(rendezvous_lock);

View File

@ -108,6 +108,8 @@ rust_sched_loop::number_of_live_tasks() {
*/
void
rust_sched_loop::reap_dead_tasks() {
lock.must_have_lock();
if (dead_task == NULL) {
return;
}

View File

@ -212,6 +212,7 @@ rust_task::must_fail_from_being_killed() {
bool
rust_task::must_fail_from_being_killed_unlocked() {
kill_lock.must_have_lock();
return killed && !reentered_rust_stack;
}

View File

@ -10,8 +10,15 @@
#include "lock_and_signal.h"
// FIXME: This is not a portable way of specifying an invalid pthread_t
#define INVALID_THREAD 0
#if defined(__WIN32__)
lock_and_signal::lock_and_signal()
#if defined(DEBUG_LOCKS)
: _holding_thread(INVALID_THREAD)
#endif
{
_event = CreateEvent(NULL, FALSE, FALSE, NULL);
@ -30,6 +37,9 @@ lock_and_signal::lock_and_signal()
#else
lock_and_signal::lock_and_signal()
#if defined(DEBUG_LOCKS)
: _holding_thread(INVALID_THREAD)
#endif
{
CHECKED(pthread_cond_init(&_cond, NULL));
CHECKED(pthread_mutex_init(&_mutex, NULL));
@ -47,14 +57,25 @@ lock_and_signal::~lock_and_signal() {
}
void lock_and_signal::lock() {
must_not_have_lock();
#if defined(__WIN32__)
EnterCriticalSection(&_cs);
#if defined(DEBUG_LOCKS)
_holding_thread = GetCurrentThreadId();
#endif
#else
CHECKED(pthread_mutex_lock(&_mutex));
#if defined(DEBUG_LOCKS)
_holding_thread = pthread_self();
#endif
#endif
}
void lock_and_signal::unlock() {
must_have_lock();
#if defined(DEBUG_LOCKS)
_holding_thread = INVALID_THREAD;
#endif
#if defined(__WIN32__)
LeaveCriticalSection(&_cs);
#else
@ -66,12 +87,24 @@ void lock_and_signal::unlock() {
* Wait indefinitely until condition is signaled.
*/
void lock_and_signal::wait() {
must_have_lock();
#if defined(DEBUG_LOCKS)
_holding_thread = INVALID_THREAD;
#endif
#if defined(__WIN32__)
LeaveCriticalSection(&_cs);
WaitForSingleObject(_event, INFINITE);
EnterCriticalSection(&_cs);
must_not_be_locked();
#if defined(DEBUG_LOCKS)
_holding_thread = GetCurrentThreadId();
#endif
#else
CHECKED(pthread_cond_wait(&_cond, &_mutex));
must_not_be_locked();
#if defined(DEBUG_LOCKS)
_holding_thread = pthread_self();
#endif
#endif
}
@ -86,6 +119,32 @@ void lock_and_signal::signal() {
#endif
}
#if defined(DEBUG_LOCKS)
bool lock_and_signal::lock_held_by_current_thread()
{
#if defined(__WIN32__)
return _holding_thread == GetCurrentThreadId();
#else
return pthread_equal(_holding_thread, pthread_self());
#endif
}
#endif
#if defined(DEBUG_LOCKS)
void lock_and_signal::must_have_lock() {
assert(lock_held_by_current_thread() && "must have lock");
}
void lock_and_signal::must_not_have_lock() {
assert(!lock_held_by_current_thread() && "must not have lock");
}
void lock_and_signal::must_not_be_locked() {
}
#else
void lock_and_signal::must_have_lock() { }
void lock_and_signal::must_not_have_lock() { }
void lock_and_signal::must_not_be_locked() { }
#endif
scoped_lock::scoped_lock(lock_and_signal &lock)
: lock(lock)
{

View File

@ -2,14 +2,30 @@
#ifndef LOCK_AND_SIGNAL_H
#define LOCK_AND_SIGNAL_H
#ifndef RUST_NDEBUG
#define DEBUG_LOCKS
#endif
class lock_and_signal {
#if defined(__WIN32__)
HANDLE _event;
CRITICAL_SECTION _cs;
#if defined(DEBUG_LOCKS)
DWORD _holding_thread;
#endif
#else
pthread_cond_t _cond;
pthread_mutex_t _mutex;
#if defined(DEBUG_LOCKS)
pthread_t _holding_thread;
#endif
#endif
#if defined(DEBUG_LOCKS)
bool lock_held_by_current_thread();
#endif
void must_not_be_locked();
public:
lock_and_signal();
@ -19,6 +35,9 @@ public:
void unlock();
void wait();
void signal();
void must_have_lock();
void must_not_have_lock();
};
class scoped_lock {