• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 Google LLC
2 //
3 // This source code is licensed under the BSD-style license found in the
4 // LICENSE file in the root directory of this source tree.
5 
6 #include <string.h>
7 
8 #include <xnnpack.h>
9 #include <xnnpack/common.h>
10 #include <xnnpack/log.h>
11 #include <xnnpack/mutex.h>
12 
13 #if XNN_PLATFORM_WINDOWS
14 #ifndef WIN32_LEAN_AND_MEAN
15 #define WIN32_LEAN_AND_MEAN
16 #endif
17 #include <windows.h>
18 #elif XNN_PLATFORM_MACOS || XNN_PLATFORM_IOS
19 #include <dispatch/dispatch.h>
20 #else
21 #include <pthread.h>
22 #endif
23 
xnn_mutex_init(struct xnn_mutex * mutex)24 enum xnn_status xnn_mutex_init(struct xnn_mutex* mutex) {
25 #if XNN_PLATFORM_WINDOWS
26   mutex->handle = CreateMutexW(
27       /* security attributes */ NULL,
28       /* initially owned */ FALSE,
29       /* name */ NULL);
30   if (mutex->handle == NULL) {
31     xnn_log_error("failed to initialize mutex, error code: %" PRIu32, (uint32_t) GetLastError());
32     return xnn_status_out_of_memory;
33   }
34 #elif XNN_PLATFORM_MACOS || XNN_PLATFORM_IOS
35   mutex->semaphore = dispatch_semaphore_create(1);
36   if (mutex->semaphore == NULL) {
37     xnn_log_error("failed to initialize mutex");
38     return xnn_status_out_of_memory;
39   }
40 #elif !XNN_PLATFORM_WEB || defined(__EMSCRIPTEN_PTHREADS__)
41   const int ret = pthread_mutex_init(&mutex->mutex, NULL);
42   if (ret != 0) {
43     xnn_log_error("failed to initialize mutex, error code: %d", ret);
44     return xnn_status_out_of_memory;
45   }
46 #endif
47   return xnn_status_success;
48 }
49 
xnn_mutex_lock(struct xnn_mutex * mutex)50 enum xnn_status xnn_mutex_lock(struct xnn_mutex* mutex) {
51 #if XNN_PLATFORM_WINDOWS
52   const DWORD wait_result = WaitForSingleObject(mutex->handle, INFINITE);
53   if (WAIT_OBJECT_0 != wait_result) {
54     xnn_log_error("failed to lock mutex, error code: %" PRIu32, (uint32_t) wait_result);
55     return xnn_status_invalid_state;
56   }
57 #elif XNN_PLATFORM_MACOS || XNN_PLATFORM_IOS
58   const int wait_result = dispatch_semaphore_wait(mutex->semaphore, DISPATCH_TIME_FOREVER);
59   if (0 != wait_result) {
60     xnn_log_error("failed to lock mutex, error code: %d", wait_result);
61     return xnn_status_invalid_state;
62   }
63 #elif !XNN_PLATFORM_WEB || defined(__EMSCRIPTEN_PTHREADS__)
64   const int ret = pthread_mutex_lock(&mutex->mutex);
65   if (ret != 0) {
66     xnn_log_error("failed to lock mutex, error code: %d", ret);
67     return xnn_status_invalid_state;
68   }
69 #endif
70   return xnn_status_success;
71 }
72 
xnn_mutex_unlock(struct xnn_mutex * mutex)73 enum xnn_status xnn_mutex_unlock(struct xnn_mutex* mutex) {
74 #if XNN_PLATFORM_WINDOWS
75   if (ReleaseMutex(mutex->handle) == 0) {
76     xnn_log_error("failed to unlock mutex, error code: %" PRIu32, (uint32_t) GetLastError());
77     return xnn_status_invalid_state;
78   }
79 #elif XNN_PLATFORM_MACOS || XNN_PLATFORM_IOS
80   dispatch_semaphore_signal(mutex->semaphore);
81 #elif !XNN_PLATFORM_WEB || defined(__EMSCRIPTEN_PTHREADS__)
82   const int ret = pthread_mutex_unlock(&mutex->mutex);
83   if (ret != 0) {
84     xnn_log_error("failed to unlock mutex, error code: %d", ret);
85     return xnn_status_invalid_state;
86   }
87 #endif
88   return xnn_status_success;
89 }
90 
xnn_mutex_destroy(struct xnn_mutex * mutex)91 enum xnn_status xnn_mutex_destroy(struct xnn_mutex* mutex) {
92 #if XNN_PLATFORM_WINDOWS
93   if (CloseHandle(mutex->handle) == 0) {
94     xnn_log_error("failed to destroy mutex, error code: %" PRIu32, (uint32_t) GetLastError());
95     return xnn_status_invalid_state;
96   }
97 #elif XNN_PLATFORM_MACOS || XNN_PLATFORM_IOS
98   dispatch_release(mutex->semaphore);
99 #elif !XNN_PLATFORM_WEB || defined(__EMSCRIPTEN_PTHREADS__)
100   const int ret = pthread_mutex_destroy(&mutex->mutex);
101   if (ret != 0) {
102     xnn_log_error("failed to destroy mutex, error code: %d", ret);
103     return xnn_status_invalid_state;
104   }
105 #endif
106   memset(mutex, 0, sizeof(struct xnn_mutex));
107   return xnn_status_success;
108 }
109