// 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 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.