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
|
// Start of lock.h.
// A very simple cross-platform implementation of locks. Uses
// pthreads on Unix and some Windows thing there. Futhark's
// host-level code is not multithreaded, but user code may be, so we
// need some mechanism for ensuring atomic access to API functions.
// This is that mechanism. It is not exposed to user code at all, so
// we do not have to worry about name collisions.
#ifdef _WIN32
typedef HANDLE lock_t;
static void create_lock(lock_t *lock) {
*lock = CreateMutex(NULL, // Default security attributes.
FALSE, // Initially unlocked.
NULL); // Unnamed.
}
static void lock_lock(lock_t *lock) {
assert(WaitForSingleObject(*lock, INFINITE) == WAIT_OBJECT_0);
}
static void lock_unlock(lock_t *lock) {
assert(ReleaseMutex(*lock));
}
static void free_lock(lock_t *lock) {
CloseHandle(*lock);
}
#else
// Assuming POSIX
#include <pthread.h>
typedef pthread_mutex_t lock_t;
static void create_lock(lock_t *lock) {
int r = pthread_mutex_init(lock, NULL);
assert(r == 0);
}
static void lock_lock(lock_t *lock) {
int r = pthread_mutex_lock(lock);
assert(r == 0);
}
static void lock_unlock(lock_t *lock) {
int r = pthread_mutex_unlock(lock);
assert(r == 0);
}
static void free_lock(lock_t *lock) {
// Nothing to do for pthreads.
(void)lock;
}
#endif
// End of lock.h.
|