1 /* 2 * GPAC - Multimedia Framework C SDK 3 * 4 * Authors: Jean Le Feuvre 5 * Copyright (c) Telecom ParisTech 2000-2019 6 * All rights reserved 7 * 8 * This file is part of GPAC / common tools sub-project 9 * 10 * GPAC is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License as published by 12 * the Free Software Foundation; either version 2, or (at your option) 13 * any later version. 14 * 15 * GPAC is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; see the file COPYING. If not, write to 22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 23 * 24 */ 25 26 #ifndef _GF_THREAD_H_ 27 #define _GF_THREAD_H_ 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 /*! 34 \file <gpac/thread.h> 35 \brief Threading and Mutual Exclusion 36 */ 37 38 /*! 39 \addtogroup thr_grp 40 \brief Threading and Mutual Exclusion 41 42 This section documents the threading of the GPAC framework. These provide an easy way to implement 43 safe multithreaded tools. 44 45 Available tools are thread, mutex and semaphore 46 47 \defgroup thread_grp Thread 48 \ingroup thr_grp 49 \defgroup mutex_grp Mutex 50 \ingroup thr_grp 51 \defgroup sema_grp Semaphore 52 \ingroup thr_grp 53 */ 54 55 /*! 56 \addtogroup thread_grp 57 \brief Thread processing 58 59 The thread object allows executing some code independently of the main process of your application. 60 @{ 61 */ 62 63 #include <gpac/tools.h> 64 65 66 //atomic ref_count++ / ref_count-- 67 #if defined(WIN32) || defined(_WIN32_WCE) 68 #include <Windows.h> 69 #include <WinBase.h> 70 71 #define safe_int_inc(__v) InterlockedIncrement((int *) (__v)) 72 #define safe_int_dec(__v) InterlockedDecrement((int *) (__v)) 73 74 #define safe_int_add(__v, inc_val) InterlockedAdd((int *) (__v), inc_val) 75 #define safe_int_sub(__v, dec_val) InterlockedAdd((int *) (__v), -dec_val) 76 77 #define safe_int64_add(__v, inc_val) InterlockedAdd64((LONG64 *) (__v), inc_val) 78 #define safe_int64_sub(__v, dec_val) InterlockedAdd64((LONG64 *) (__v), -dec_val) 79 80 #else 81 82 #define safe_int_inc(__v) __sync_add_and_fetch((int *) (__v), 1) 83 #define safe_int_dec(__v) __sync_sub_and_fetch((int *) (__v), 1) 84 85 #define safe_int_add(__v, inc_val) __sync_add_and_fetch((int *) (__v), inc_val) 86 #define safe_int_sub(__v, dec_val) __sync_sub_and_fetch((int *) (__v), dec_val) 87 88 #define safe_int64_add(__v, inc_val) __sync_add_and_fetch((int64_t *) (__v), inc_val) 89 #define safe_int64_sub(__v, dec_val) __sync_sub_and_fetch((int64_t *) (__v), dec_val) 90 #endif 91 92 93 /*! 94 \brief Thread states 95 * 96 *Indicates the execution status of a thread 97 */ 98 enum 99 { 100 /*! the thread has been initialized but is not started yet*/ 101 GF_THREAD_STATUS_STOP = 0, 102 /*! the thread is running*/ 103 GF_THREAD_STATUS_RUN = 1, 104 /*! the thread has exited its body function*/ 105 GF_THREAD_STATUS_DEAD = 2 106 }; 107 108 /*! 109 \brief abstracted thread object 110 */ 111 typedef struct __tag_thread GF_Thread; 112 113 /*! 114 \brief thread constructor 115 116 Constructs a new thread object 117 \param name log name of the thread if any 118 \return new thread object 119 */ 120 GF_Thread *gf_th_new(const char *name); 121 /*! 122 \brief thread destructor 123 124 Kills the thread if running and destroys the object 125 \param th the thread object 126 */ 127 void gf_th_del(GF_Thread *th); 128 129 /*! 130 \brief thread run function callback 131 132 The gf_thread_run type is the type for the callback of the \ref gf_thread_run function 133 \param par opaque user data 134 \return exit code of the thread, usually 1 for error and 0 if normal execution 135 */ 136 typedef u32 (*gf_thread_run)(void *par); 137 138 /*! 139 \brief thread execution 140 141 Executes the thread with the given function 142 \note A thread may be run several times but cannot be run twice in the same time. 143 \param th the thread object 144 \param run the function this thread will call 145 \param par the argument to the function the thread will call 146 \return error if any 147 */ 148 GF_Err gf_th_run(GF_Thread *th, gf_thread_run run, void *par); 149 /*! 150 \brief thread stopping 151 152 Waits for the thread exit until return 153 \param th the thread object 154 */ 155 void gf_th_stop(GF_Thread *th); 156 /*! 157 \brief thread status query 158 159 Gets the thread status 160 \param th the thread object 161 \return thread status 162 */ 163 u32 gf_th_status(GF_Thread *th); 164 165 /*! thread priorities */ 166 enum 167 { 168 /*!Idle Priority*/ 169 GF_THREAD_PRIORITY_IDLE=0, 170 /*!Less Idle Priority*/ 171 GF_THREAD_PRIORITY_LESS_IDLE, 172 /*!Lowest Priority*/ 173 GF_THREAD_PRIORITY_LOWEST, 174 /*!Low Priority*/ 175 GF_THREAD_PRIORITY_LOW, 176 /*!Normal Priority (the default one)*/ 177 GF_THREAD_PRIORITY_NORMAL, 178 /*!High Priority*/ 179 GF_THREAD_PRIORITY_HIGH, 180 /*!Highest Priority*/ 181 GF_THREAD_PRIORITY_HIGHEST, 182 /*!First real-time priority*/ 183 GF_THREAD_PRIORITY_REALTIME, 184 /*!Last real-time priority*/ 185 GF_THREAD_PRIORITY_REALTIME_END=255 186 }; 187 188 /*! 189 \brief thread priority 190 191 Sets the thread execution priority level. 192 \param th the thread object 193 \param priority the desired priority 194 \note this should be used with caution, especially use of real-time priorities. 195 */ 196 void gf_th_set_priority(GF_Thread *th, s32 priority); 197 /*! 198 \brief current thread ID 199 200 Gets the ID of the current thread the caller is in. 201 \return thread ID 202 */ 203 u32 gf_th_id(); 204 205 #ifdef GPAC_CONFIG_ANDROID 206 /*! Register a function that will be called before pthread_exist is called */ 207 GF_Err gf_register_before_exit_function(GF_Thread *t, u32 (*toRunBeforePthreadExit)(void *param)); 208 209 /*! Get the current Thread if any. May return NULL 210 */ 211 GF_Thread * gf_th_current(); 212 213 #endif /* GPAC_CONFIG_ANDROID */ 214 215 /*! @} */ 216 217 /*! 218 \addtogroup mutex_grp 219 \brief Mutual exclusion 220 221 The mutex object allows ensuring that portions of the code (typically access to variables) cannot be executed by two threads (or a thread and the main process) at the same time. 222 223 @{ 224 */ 225 226 /*! 227 \brief abstracted mutex object*/ 228 typedef struct __tag_mutex GF_Mutex; 229 /*! 230 \brief mutex constructor 231 232 Contructs a new mutex object 233 \param name log name of the thread if any 234 \return new mutex 235 */ 236 GF_Mutex *gf_mx_new(const char *name); 237 /*! 238 \brief mutex denstructor 239 240 Destroys a mutex object. This will wait for the mutex to be released if needed. 241 \param mx the mutex object 242 */ 243 void gf_mx_del(GF_Mutex *mx); 244 /*! 245 \brief mutex locking 246 247 Locks the mutex object, making sure that another thread locking this mutex cannot execute until the mutex is unlocked. 248 \param mx the mutex object 249 \return 1 if success, 0 if error locking the mutex (which should never happen) 250 */ 251 u32 gf_mx_p(GF_Mutex *mx); 252 /*! 253 \brief mutex unlocking 254 255 Unlocks the mutex object, allowing other threads waiting on this mutex to continue their execution 256 \param mx the mutex object 257 */ 258 void gf_mx_v(GF_Mutex *mx); 259 /*! 260 \brief mutex non-blocking lock 261 262 Attemps to lock the mutex object without blocking until the object is released. 263 \param mx the mutex object 264 \return GF_TRUE if the mutex has been successfully locked, in which case it shall then be unlocked, or GF_FALSE if the mutex is locked by another thread. 265 */ 266 Bool gf_mx_try_lock(GF_Mutex *mx); 267 268 /*! 269 \brief get mutex number of locks 270 271 Returns the number of locks on the mutex if the caller thread is holding the mutex. 272 \param mx the mutex object 273 \return -1 if the mutex is not hold by the calling thread, or the number of locks (possibly 0) otherwise. 274 */ 275 s32 gf_mx_get_num_locks(GF_Mutex *mx); 276 277 /*! @} */ 278 279 /*! 280 \addtogroup sema_grp 281 \brief Semaphore 282 283 284 The semaphore object allows controling how portions of the code (typically access to variables) are 285 executed by two threads (or a thread and the main process) at the same time. The best image for a semaphore is a limited set 286 of money coins (always easy to understand hmm?). If no money is in the set, nobody can buy anything until a coin is put back in the set. 287 When the set is full, the money is wasted (call it "the bank"...). 288 289 @{ 290 */ 291 292 /********************************************************************* 293 Semaphore Object 294 **********************************************************************/ 295 /*! 296 \brief abstracted semaphore object 297 */ 298 typedef struct __tag_semaphore GF_Semaphore; 299 /*! 300 \brief semaphore constructor 301 302 Constructs a new semaphore object 303 \param MaxCount the maximum notification count of this semaphore 304 \param InitCount the initial notification count of this semaphore upon construction 305 \return the semaphore object 306 */ 307 GF_Semaphore *gf_sema_new(u32 MaxCount, u32 InitCount); 308 /*! 309 \brief semaphore destructor 310 311 Destructs the semaphore object. This will wait for the semaphore to be released if needed. 312 \param sm the semaphore object 313 */ 314 void gf_sema_del(GF_Semaphore *sm); 315 /*! 316 \brief semaphore notification. 317 318 Notifies the semaphore of a certain amount of releases. 319 \param sm the semaphore object 320 \param nb_rel sm the number of release to notify 321 \return GF_TRUE if success, GF_FALSE otherwise 322 */ 323 Bool gf_sema_notify(GF_Semaphore *sm, u32 nb_rel); 324 /*! 325 \brief semaphore wait 326 327 Waits for the semaphore to be accessible (eg, may wait an infinite time). 328 \param sm the semaphore object 329 \return GF_TRUE if successfull wait, GF_FALSE if wait failed 330 */ 331 Bool gf_sema_wait(GF_Semaphore *sm); 332 /*! 333 \brief semaphore time wait 334 335 Waits for a certain for the semaphore to be accessible, and returns when semaphore is accessible or wait time has passed. 336 \param sm the semaphore object 337 \param time_out the amount of time to wait for the release in milliseconds 338 \return returns 1 if the semaphore was released before the timeout, 0 if the semaphore is still not released after the timeout. 339 */ 340 Bool gf_sema_wait_for(GF_Semaphore *sm, u32 time_out); 341 342 343 /*! @} */ 344 345 #ifdef __cplusplus 346 } 347 #endif 348 349 350 #endif /*_GF_THREAD_H_*/ 351 352