Reputation: 7261
I was wondering if I could make a recursive mutex type on my own with a PTHREAD_MUTEX_ERRORCHECK
mutex, this is the result:
typedef struct {
pthread_mutex_t mutex;
uint32_t deadlocks;
pthread_t owner;
BOOL isLocked;
} pthread_recursivemutex_t;
int pthread_recursivemutex_init(pthread_recursivemutex_t *mutex)
{
int ret;
pthread_mutexattr_t attr;
mutex->deadlocks = 0;
ret = pthread_mutexattr_init(&attr);
if (ret != 0) {
return ret;
}
(void)pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
ret = pthread_mutex_init(&mutex->mutex, &attr);
(void)pthread_mutexattr_destroy(&attr);
mutex->isLocked = FALSE;
return ret;
}
void pthread_recursivemutex_lock(pthread_recursivemutex_t *mutex)
{
int ret;
BOOL locked;
locked = mutex->isLocked;
__sync_synchronize();
if (locked == TRUE) {
if (pthread_equal(pthread_self(), mutex->owner) == 0) {
return;
}
}
ret = pthread_mutex_lock(&mutex->mutex);
if (ret == 0) {
mutex->deadlocks = 0;
__sync_synchronize();
mutex->isLocked = TRUE;
} else if (ret == EDEADLK) {
mutex->deadlocks += 1;
}
}
void pthread_recursivemutex_unlock(pthread_recursivemutex_t *mutex)
{
if (mutex->deadlocks == 0) {
(void)pthread_mutex_unlock(&mutex->mutex);
__sync_synchronize();
mutex->isLocked = FALSE;
} else {
mutex->deadlocks -= 1;
}
}
void pthread_recursivemutex_destroy(pthread_recursivemutex_t *mutex)
{
(void)pthread_mutex_destroy(&mutex->mutex);
}
I found out that this type of recursive mutex is a lot faster than a mutex with the PTHREAD_MUTEX_RECURSIVE
attribute:
iterations : 1000000
pthread_mutex_t : 71757 μSeconds
pthread_recursivemutex_t : 48583 μSeconds
Test code (each called 1000000 times):
void mutex_test()
{
pthread_mutex_lock(&recursiveMutex);
pthread_mutex_lock(&recursiveMutex);
pthread_mutex_unlock(&recursiveMutex);
pthread_mutex_unlock(&recursiveMutex);
}
void recursivemutex_test()
{
pthread_recursivemutex_lock(&myMutex);
pthread_recursivemutex_lock(&myMutex);
pthread_recursivemutex_unlock(&myMutex);
pthread_recursivemutex_unlock(&myMutex);
}
pthread_recursivemutex_t
is almost twice as fast as pthread_mutex_t
?! But both behave the same way...?
Is this solution above safe?
Upvotes: 1
Views: 1312
Reputation: 96258
Your mutex won't work: you don't check which thread is acquiring the lock.
You allow multiple threads to lock the same mutex.
Upvotes: 2