xref: /rockchip-linux_mpp/osal/inc/mpp_thread.h (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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