Implemented recursive mutex without thread-specific counter

This commit is contained in:
Tobias Brunner
2012-08-03 11:30:18 +02:00
parent 920f29e7d5
commit decc467a4f
+17 -23
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2008-2009 Tobias Brunner * Copyright (C) 2008-2012 Tobias Brunner
* Copyright (C) 2008 Martin Willi * Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil * Hochschule fuer Technik Rapperswil
* *
@@ -73,9 +73,9 @@ struct private_r_mutex_t {
pthread_t thread; pthread_t thread;
/** /**
* times we have locked the lock, stored per thread * times the current thread locked the mutex
*/ */
pthread_key_t times; u_int times;
}; };
/** /**
@@ -127,35 +127,24 @@ METHOD(mutex_t, lock_r, void,
{ {
pthread_t self = pthread_self(); pthread_t self = pthread_self();
if (this->thread == self) if (pthread_equal(this->thread, self))
{ {
uintptr_t times; this->times++;
/* times++ */
times = (uintptr_t)pthread_getspecific(this->times);
pthread_setspecific(this->times, (void*)times + 1);
} }
else else
{ {
lock(&this->generic); lock(&this->generic);
this->thread = self; this->thread = self;
/* times = 1 */ this->times = 1;
pthread_setspecific(this->times, (void*)1);
} }
} }
METHOD(mutex_t, unlock_r, void, METHOD(mutex_t, unlock_r, void,
private_r_mutex_t *this) private_r_mutex_t *this)
{ {
uintptr_t times; if (--this->times == 0)
/* times-- */
times = (uintptr_t)pthread_getspecific(this->times);
pthread_setspecific(this->times, (void*)--times);
if (times == 0)
{ {
this->thread = 0; memset(&this->thread, 0, sizeof(this->thread));
unlock(&this->generic); unlock(&this->generic);
} }
} }
@@ -173,7 +162,6 @@ METHOD(mutex_t, mutex_destroy_r, void,
{ {
profiler_cleanup(&this->generic.profile); profiler_cleanup(&this->generic.profile);
pthread_mutex_destroy(&this->generic.mutex); pthread_mutex_destroy(&this->generic.mutex);
pthread_key_delete(this->times);
free(this); free(this);
} }
@@ -200,7 +188,6 @@ mutex_t *mutex_create(mutex_type_t type)
); );
pthread_mutex_init(&this->generic.mutex, NULL); pthread_mutex_init(&this->generic.mutex, NULL);
pthread_key_create(&this->times, NULL);
profiler_init(&this->generic.profile); profiler_init(&this->generic.profile);
return &this->generic.public; return &this->generic.public;
@@ -233,11 +220,15 @@ METHOD(condvar_t, wait_, void,
if (mutex->recursive) if (mutex->recursive)
{ {
private_r_mutex_t* recursive = (private_r_mutex_t*)mutex; private_r_mutex_t* recursive = (private_r_mutex_t*)mutex;
u_int times;
/* keep track of the number of times this thread locked the mutex */
times = recursive->times;
/* mutex owner gets cleared during condvar wait */ /* mutex owner gets cleared during condvar wait */
recursive->thread = 0; memset(&recursive->thread, 0, sizeof(recursive->thread));
pthread_cond_wait(&this->condvar, &mutex->mutex); pthread_cond_wait(&this->condvar, &mutex->mutex);
recursive->thread = pthread_self(); recursive->thread = pthread_self();
recursive->times = times;
} }
else else
{ {
@@ -262,11 +253,14 @@ METHOD(condvar_t, timed_wait_abs, bool,
if (mutex->recursive) if (mutex->recursive)
{ {
private_r_mutex_t* recursive = (private_r_mutex_t*)mutex; private_r_mutex_t* recursive = (private_r_mutex_t*)mutex;
u_int times;
recursive->thread = 0; times = recursive->times;
memset(&recursive->thread, 0, sizeof(recursive->thread));
timed_out = pthread_cond_timedwait(&this->condvar, &mutex->mutex, timed_out = pthread_cond_timedwait(&this->condvar, &mutex->mutex,
&ts) == ETIMEDOUT; &ts) == ETIMEDOUT;
recursive->thread = pthread_self(); recursive->thread = pthread_self();
recursive->times = times;
} }
else else
{ {