1 /* Copyright (C) 2010-2020 The RetroArch team 2 * 3 * --------------------------------------------------------------------------------------- 4 * The following license statement only applies to this file (rthreads.h). 5 * --------------------------------------------------------------------------------------- 6 * 7 * Permission is hereby granted, free of charge, 8 * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation the rights to 10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 23 #ifndef __LIBRETRO_SDK_RTHREADS_H__ 24 #define __LIBRETRO_SDK_RTHREADS_H__ 25 26 #include <retro_common_api.h> 27 28 #include <boolean.h> 29 #include <stdint.h> 30 #include <retro_inline.h> 31 #include <retro_miscellaneous.h> 32 33 RETRO_BEGIN_DECLS 34 35 typedef struct sthread sthread_t; 36 typedef struct slock slock_t; 37 typedef struct scond scond_t; 38 39 #ifdef HAVE_THREAD_STORAGE 40 typedef unsigned sthread_tls_t; 41 #endif 42 43 /** 44 * sthread_create: 45 * @start_routine : thread entry callback function 46 * @userdata : pointer to userdata that will be made 47 * available in thread entry callback function 48 * 49 * Create a new thread. 50 * 51 * Returns: pointer to new thread if successful, otherwise NULL. 52 */ 53 sthread_t *sthread_create(void (*thread_func)(void*), void *userdata); 54 55 /** 56 * sthread_create_with_priority: 57 * @start_routine : thread entry callback function 58 * @userdata : pointer to userdata that will be made 59 * available in thread entry callback function 60 * @thread_priority : thread priority hint value from [1-100] 61 * 62 * Create a new thread. It is possible for the caller to give a hint 63 * for the thread's priority from [1-100]. Any passed in @thread_priority 64 * values that are outside of this range will cause sthread_create() to 65 * create a new thread using the operating system's default thread 66 * priority. 67 * 68 * Returns: pointer to new thread if successful, otherwise NULL. 69 */ 70 sthread_t *sthread_create_with_priority(void (*thread_func)(void*), void *userdata, int thread_priority); 71 72 /** 73 * sthread_detach: 74 * @thread : pointer to thread object 75 * 76 * Detach a thread. When a detached thread terminates, its 77 * resource sare automatically released back to the system 78 * without the need for another thread to join with the 79 * terminated thread. 80 * 81 * Returns: 0 on success, otherwise it returns a non-zero error number. 82 */ 83 int sthread_detach(sthread_t *thread); 84 85 /** 86 * sthread_join: 87 * @thread : pointer to thread object 88 * 89 * Join with a terminated thread. Waits for the thread specified by 90 * @thread to terminate. If that thread has already terminated, then 91 * it will return immediately. The thread specified by @thread must 92 * be joinable. 93 * 94 * Returns: 0 on success, otherwise it returns a non-zero error number. 95 */ 96 void sthread_join(sthread_t *thread); 97 98 /** 99 * sthread_isself: 100 * @thread : pointer to thread object 101 * 102 * Returns: true (1) if calling thread is the specified thread 103 */ 104 bool sthread_isself(sthread_t *thread); 105 106 /** 107 * slock_new: 108 * 109 * Create and initialize a new mutex. Must be manually 110 * freed. 111 * 112 * Returns: pointer to a new mutex if successful, otherwise NULL. 113 **/ 114 slock_t *slock_new(void); 115 116 /** 117 * slock_free: 118 * @lock : pointer to mutex object 119 * 120 * Frees a mutex. 121 **/ 122 void slock_free(slock_t *lock); 123 124 /** 125 * slock_lock: 126 * @lock : pointer to mutex object 127 * 128 * Locks a mutex. If a mutex is already locked by 129 * another thread, the calling thread shall block until 130 * the mutex becomes available. 131 **/ 132 void slock_lock(slock_t *lock); 133 134 /** 135 * slock_try_lock: 136 * @lock : pointer to mutex object 137 * 138 * Attempts to lock a mutex. If a mutex is already locked by 139 * another thread, return false. If the lock is acquired, return true. 140 **/ 141 bool slock_try_lock(slock_t *lock); 142 143 /** 144 * slock_unlock: 145 * @lock : pointer to mutex object 146 * 147 * Unlocks a mutex. 148 **/ 149 void slock_unlock(slock_t *lock); 150 151 /** 152 * scond_new: 153 * 154 * Creates and initializes a condition variable. Must 155 * be manually freed. 156 * 157 * Returns: pointer to new condition variable on success, 158 * otherwise NULL. 159 **/ 160 scond_t *scond_new(void); 161 162 /** 163 * scond_free: 164 * @cond : pointer to condition variable object 165 * 166 * Frees a condition variable. 167 **/ 168 void scond_free(scond_t *cond); 169 170 /** 171 * scond_wait: 172 * @cond : pointer to condition variable object 173 * @lock : pointer to mutex object 174 * 175 * Block on a condition variable (i.e. wait on a condition). 176 **/ 177 void scond_wait(scond_t *cond, slock_t *lock); 178 179 /** 180 * scond_wait_timeout: 181 * @cond : pointer to condition variable object 182 * @lock : pointer to mutex object 183 * @timeout_us : timeout (in microseconds) 184 * 185 * Try to block on a condition variable (i.e. wait on a condition) until 186 * @timeout_us elapses. 187 * 188 * Returns: false (0) if timeout elapses before condition variable is 189 * signaled or broadcast, otherwise true (1). 190 **/ 191 bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us); 192 193 /** 194 * scond_broadcast: 195 * @cond : pointer to condition variable object 196 * 197 * Broadcast a condition. Unblocks all threads currently blocked 198 * on the specified condition variable @cond. 199 **/ 200 int scond_broadcast(scond_t *cond); 201 202 /** 203 * scond_signal: 204 * @cond : pointer to condition variable object 205 * 206 * Signal a condition. Unblocks at least one of the threads currently blocked 207 * on the specified condition variable @cond. 208 **/ 209 void scond_signal(scond_t *cond); 210 211 #ifdef HAVE_THREAD_STORAGE 212 /** 213 * @brief Creates a thread local storage key 214 * 215 * This function shall create thread-specific data key visible to all threads in 216 * the process. The same key can be used by multiple threads to store 217 * thread-local data. 218 * 219 * When the key is created NULL shall be associated with it in all active 220 * threads. Whenever a new thread is spawned the all defined keys will be 221 * associated with NULL on that thread. 222 * 223 * @param tls 224 * @return whether the operation suceeded or not 225 */ 226 bool sthread_tls_create(sthread_tls_t *tls); 227 228 /** 229 * @brief Deletes a thread local storage 230 * @param tls 231 * @return whether the operation suceeded or not 232 */ 233 bool sthread_tls_delete(sthread_tls_t *tls); 234 235 /** 236 * @brief Retrieves thread specific data associated with a key 237 * 238 * There is no way to tell whether this function failed. 239 * 240 * @param tls 241 * @return 242 */ 243 void *sthread_tls_get(sthread_tls_t *tls); 244 245 /** 246 * @brief Binds thread specific data to a key 247 * @param tls 248 * @return Whether the operation suceeded or not 249 */ 250 bool sthread_tls_set(sthread_tls_t *tls, const void *data); 251 #endif 252 253 /* 254 * @brief Get thread ID of specified thread 255 * @param thread 256 * @return The ID of the specified thread 257 */ 258 uintptr_t sthread_get_thread_id(sthread_t *thread); 259 260 /* 261 * @brief Get thread ID of the current thread 262 * @param 263 * @return The ID of the current thread 264 */ 265 uintptr_t sthread_get_current_thread_id(void); 266 267 RETRO_END_DECLS 268 269 #endif 270