1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */ 2 /* 3 * Copyright (c) 2015 Rockchip Electronics Co., Ltd. 4 */ 5 6 #ifndef __MPP_THREAD_H__ 7 #define __MPP_THREAD_H__ 8 9 #include <unistd.h> 10 #include <semaphore.h> 11 #include <pthread.h> 12 #include <sys/time.h> 13 #include <string.h> 14 #include <time.h> 15 #include <assert.h> 16 17 #include "rk_type.h" 18 19 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 20 #define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER 21 #endif 22 23 #if defined(__USE_XOPEN2K) || (defined(__ANDROID__) && __ANDROID_API__ >= 21) 24 #define COND_USE_CLOCK_MONOTONIC 25 #endif 26 27 #define THREAD_NAME_LEN 16 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 typedef void *(*MppThreadFunc)(void *); 34 35 typedef enum MppThreadStatus_e { 36 MPP_THREAD_UNINITED, 37 MPP_THREAD_READY, 38 MPP_THREAD_RUNNING, 39 MPP_THREAD_WAITING, 40 MPP_THREAD_STOPPING, 41 } MppThreadStatus; 42 43 typedef struct MppMutex_t { 44 pthread_mutex_t lock; 45 } MppMutex; 46 47 typedef struct MppCond_t { 48 pthread_cond_t cond; 49 clockid_t clock_id; 50 } MppCond; 51 52 typedef struct MppMutexCond_t { 53 MppMutex lock; 54 MppCond cond; 55 } MppMutexCond; 56 57 typedef enum MppThreadSignalId_e { 58 THREAD_WORK, 59 THREAD_INPUT, 60 THREAD_OUTPUT, 61 THREAD_CONTROL, 62 THREAD_SIGNAL_BUTT, 63 } MppThreadSignalId; 64 65 typedef struct MppThread_t { 66 pthread_t thd; 67 MppMutexCond mutex_cond[THREAD_SIGNAL_BUTT]; 68 MppThreadStatus thd_status[THREAD_SIGNAL_BUTT]; 69 MppThreadFunc func; 70 char name[THREAD_NAME_LEN]; 71 void *ctx; 72 } MppThread; 73 74 // Mutex functions 75 void mpp_mutex_init(MppMutex *mutex); 76 void mpp_mutex_destroy(MppMutex *mutex); 77 void mpp_mutex_lock(MppMutex *mutex); 78 void mpp_mutex_unlock(MppMutex *mutex); 79 int mpp_mutex_trylock(MppMutex *mutex); 80 81 // Condition functions 82 void mpp_cond_init(MppCond *condition); 83 void mpp_cond_destroy(MppCond *condition); 84 rk_s32 mpp_cond_wait(MppCond *condition, MppMutex *mutex); 85 rk_s32 mpp_cond_timedwait(MppCond *condition, MppMutex *mutex, rk_s64 timeout); 86 rk_s32 mpp_cond_signal(MppCond *condition); 87 rk_s32 mpp_cond_broadcast(MppCond *condition); 88 89 // Mutex-Condition functions 90 void mpp_mutex_cond_init(MppMutexCond *mutexCond); 91 void mpp_mutex_cond_destroy(MppMutexCond *mutexCond); 92 void mpp_mutex_cond_lock(MppMutexCond *mutexCond); 93 void mpp_mutex_cond_unlock(MppMutexCond *mutexCond); 94 int mpp_mutex_cond_trylock(MppMutexCond *mutexCond); 95 rk_s32 mpp_mutex_cond_wait(MppMutexCond *mutexCond); 96 rk_s32 mpp_mutex_cond_timedwait(MppMutexCond *mutexCond, rk_s64 timeout); 97 void mpp_mutex_cond_signal(MppMutexCond *mutexCond); 98 void mpp_mutex_cond_broadcast(MppMutexCond *mutexCond); 99 100 // Thread functions 101 void mpp_thread_init(MppThread *thread, MppThreadFunc func, void *ctx, const char *name); 102 void mpp_thread_set_status(MppThread *thread, MppThreadStatus status, MppThreadSignalId id); 103 MppThreadStatus mpp_thread_get_status(MppThread *thread, MppThreadSignalId id); 104 void mpp_thread_lock(MppThread *thread, MppThreadSignalId id); 105 void mpp_thread_unlock(MppThread *thread, MppThreadSignalId id); 106 void mpp_thread_wait(MppThread *thread, MppThreadSignalId id); 107 void mpp_thread_signal(MppThread *thread, MppThreadSignalId id); 108 109 MppThread *mpp_thread_create(MppThreadFunc func, void *ctx, const char *name); 110 void mpp_thread_destroy(MppThread *thread); 111 void mpp_thread_start(MppThread *thread); 112 void mpp_thread_stop(MppThread *thread); 113 114 115 /* 116 * status transaction: 117 * create 118 * v 119 * MPP_THREAD_UNINITED 120 * v 121 * setup 122 * v 123 * destroy <- MPP_THREAD_READY <-------------------+ 124 * v | 125 * start | 126 * v | 127 * MPP_THREAD_RUNNING -> stop -> MPP_THREAD_STOPPING 128 * v | 129 * wait | 130 * v | 131 * MPP_THREAD_WAITING -> stop ------------+ 132 * 133 */ 134 typedef enum MppSThdStatus_e { 135 MPP_STHD_UNINITED, 136 MPP_STHD_READY, 137 MPP_STHD_RUNNING, 138 MPP_STHD_WAITING, 139 MPP_STHD_STOPPING, 140 MPP_STHD_BUTT, 141 } MppSThdStatus; 142 143 /* MppSThd for Mpp Simple Thread */ 144 typedef void* MppSThd; 145 typedef void* MppSThdGrp; 146 147 typedef struct MppSThdCtx_t { 148 MppSThd thd; 149 void *ctx; 150 } MppSThdCtx; 151 152 typedef void *(*MppSThdFunc)(MppSThdCtx *); 153 154 MppSThd mpp_sthd_get(const char *name); 155 void mpp_sthd_put(MppSThd thd); 156 157 MppSThdStatus mpp_sthd_get_status(MppSThd thd); 158 const char* mpp_sthd_get_name(MppSThd thd); 159 rk_s32 mpp_sthd_get_idx(MppSThd thd); 160 rk_s32 mpp_sthd_check(MppSThd thd); 161 162 void mpp_sthd_setup(MppSThd thd, MppSThdFunc func, void *ctx); 163 164 void mpp_sthd_start(MppSThd thd); 165 void mpp_sthd_stop(MppSThd thd); 166 void mpp_sthd_stop_sync(MppSThd thd); 167 168 void mpp_sthd_lock(MppSThd thd); 169 void mpp_sthd_unlock(MppSThd thd); 170 int mpp_sthd_trylock(MppSThd thd); 171 172 void mpp_sthd_wait(MppSThd thd); 173 void mpp_sthd_signal(MppSThd thd); 174 void mpp_sthd_broadcast(MppSThd thd); 175 176 /* multi-thread group with same callback and context */ 177 MppSThdGrp mpp_sthd_grp_get(const char *name, rk_s32 count); 178 void mpp_sthd_grp_put(MppSThdGrp grp); 179 180 void mpp_sthd_grp_setup(MppSThdGrp grp, MppSThdFunc func, void *ctx); 181 MppSThd mpp_sthd_grp_get_each(MppSThdGrp grp, rk_s32 idx); 182 183 void mpp_sthd_grp_start(MppSThdGrp grp); 184 void mpp_sthd_grp_stop(MppSThdGrp grp); 185 void mpp_sthd_grp_stop_sync(MppSThdGrp grp); 186 187 #ifdef __cplusplus 188 } 189 #endif 190 191 #endif