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