blob: 874b0aa1259f7f3eb905a4d796298a542f5ddac4 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
#include <pthread.h>
#include "WAVM/Inline/Assert.h"
#include "WAVM/Inline/Errors.h"
#include "WAVM/Platform/Defines.h"
#include "WAVM/Platform/Mutex.h"
using namespace WAVM;
using namespace WAVM::Platform;
Platform::Mutex::Mutex()
{
static_assert(sizeof(LockData) >= sizeof(pthread_mutex_t), "");
static_assert(alignof(LockData) >= alignof(pthread_mutex_t), "");
#if WAVM_ENABLE_ASSERTS
// Use a recursive mutex in debug builds to support isLockedByCurrentThread.
pthread_mutexattr_t pthreadMutexAttr;
WAVM_ERROR_UNLESS(!pthread_mutexattr_init(&pthreadMutexAttr));
WAVM_ERROR_UNLESS(!pthread_mutexattr_settype(&pthreadMutexAttr, PTHREAD_MUTEX_RECURSIVE));
WAVM_ERROR_UNLESS(!pthread_mutex_init((pthread_mutex_t*)&lockData, &pthreadMutexAttr));
WAVM_ERROR_UNLESS(!pthread_mutexattr_destroy(&pthreadMutexAttr));
isLocked = false;
#else
WAVM_ERROR_UNLESS(!pthread_mutex_init((pthread_mutex_t*)&lockData, nullptr));
#endif
}
Platform::Mutex::~Mutex()
{
WAVM_ERROR_UNLESS(!pthread_mutex_destroy((pthread_mutex_t*)&lockData));
}
void Platform::Mutex::lock()
{
WAVM_ERROR_UNLESS(!pthread_mutex_lock((pthread_mutex_t*)&lockData));
#if WAVM_ENABLE_ASSERTS
if(isLocked) { Errors::fatal("Recursive mutex lock"); }
isLocked = true;
#endif
}
void Platform::Mutex::unlock()
{
#if WAVM_ENABLE_ASSERTS
isLocked = false;
#endif
WAVM_ERROR_UNLESS(!pthread_mutex_unlock((pthread_mutex_t*)&lockData));
}
#if WAVM_ENABLE_ASSERTS
bool Platform::Mutex::isLockedByCurrentThread()
{
// Try to lock the mutex, and if EDEADLK is returned, it means the mutex was already locked by
// this thread.
int tryLockResult = pthread_mutex_trylock((pthread_mutex_t*)&lockData);
if(tryLockResult) { return false; }
const bool result = isLocked;
WAVM_ERROR_UNLESS(!pthread_mutex_unlock((pthread_mutex_t*)&lockData));
return result;
}
#endif
|