[osal]: Use multiple status in MppThread

One thread May have multiple lock/wait/signal source:

Input  : signal source from input.
Output : signal source from output.
Control: signal source from async control operation.

Then the main working loop may stop on these lock/wait/signal points.

Change-Id: Ia6270b865cfb7087567fc21f07feb9248b929d7a
Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
This commit is contained in:
Herman Chen
2018-05-21 15:09:00 +08:00
parent 3ed61e06e1
commit bed754e33f
2 changed files with 35 additions and 15 deletions

View File

@@ -223,8 +223,9 @@ public:
MppThread(MppThreadFunc func, void *ctx, const char *name = NULL); MppThread(MppThreadFunc func, void *ctx, const char *name = NULL);
~MppThread() {}; ~MppThread() {};
MppThreadStatus get_status(); MppThreadStatus get_status(MppThreadSignal id = THREAD_WORK);
void set_status(MppThreadStatus status); void set_status(MppThreadStatus status, MppThreadSignal id = THREAD_WORK);
void dump_status();
void start(); void start();
void stop(); void stop();
@@ -241,7 +242,14 @@ public:
void wait(MppThreadSignal id = THREAD_WORK) { void wait(MppThreadSignal id = THREAD_WORK) {
mpp_assert(id < THREAD_SIGNAL_BUTT); mpp_assert(id < THREAD_SIGNAL_BUTT);
MppThreadStatus status = mStatus[id];
mStatus[id] = MPP_THREAD_WAITING;
mMutexCond[id].wait(); mMutexCond[id].wait();
// check the status is not changed then restore status
if (mStatus[id] == MPP_THREAD_WAITING)
mStatus[id] = status;
} }
void signal(MppThreadSignal id = THREAD_WORK) { void signal(MppThreadSignal id = THREAD_WORK) {
@@ -257,8 +265,8 @@ public:
private: private:
pthread_t mThread; pthread_t mThread;
MppMutexCond mMutexCond[THREAD_SIGNAL_BUTT]; MppMutexCond mMutexCond[THREAD_SIGNAL_BUTT];
MppThreadStatus mStatus[THREAD_SIGNAL_BUTT];
MppThreadStatus mStatus;
MppThreadFunc mFunction; MppThreadFunc mFunction;
char mName[THREAD_NAME_LEN]; char mName[THREAD_NAME_LEN];
void *mContext; void *mContext;

View File

@@ -29,23 +29,35 @@ static RK_U32 thread_debug = 0;
#define thread_dbg(flag, fmt, ...) _mpp_dbg(thread_debug, flag, fmt, ## __VA_ARGS__) #define thread_dbg(flag, fmt, ...) _mpp_dbg(thread_debug, flag, fmt, ## __VA_ARGS__)
MppThread::MppThread(MppThreadFunc func, void *ctx, const char *name) MppThread::MppThread(MppThreadFunc func, void *ctx, const char *name)
: mStatus(MPP_THREAD_UNINITED), : mFunction(func),
mFunction(func),
mContext(ctx) mContext(ctx)
{ {
mStatus[THREAD_WORK] = MPP_THREAD_UNINITED;
mStatus[THREAD_INPUT] = MPP_THREAD_RUNNING;
mStatus[THREAD_OUTPUT] = MPP_THREAD_RUNNING;
mStatus[THREAD_CONTROL] = MPP_THREAD_RUNNING;
if (name) if (name)
strncpy(mName, name, sizeof(mName)); strncpy(mName, name, sizeof(mName));
else else
snprintf(mName, sizeof(mName), "mpp_thread"); snprintf(mName, sizeof(mName), "mpp_thread");
} }
MppThreadStatus MppThread::get_status() MppThreadStatus MppThread::get_status(MppThreadSignal id)
{ {
return mStatus; return mStatus[id];
} }
void MppThread::set_status(MppThreadStatus status)
void MppThread::set_status(MppThreadStatus status, MppThreadSignal id)
{ {
mStatus = status; mStatus[id] = status;
}
void MppThread::dump_status()
{
mpp_log("thread %s status: %d %d %d %d\n", mName,
mStatus[THREAD_WORK], mStatus[THREAD_INPUT], mStatus[THREAD_OUTPUT],
mStatus[THREAD_CONTROL]);
} }
void MppThread::start() void MppThread::start()
@@ -54,9 +66,9 @@ void MppThread::start()
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
if (MPP_THREAD_UNINITED == mStatus) { if (MPP_THREAD_UNINITED == get_status()) {
// NOTE: set status here first to avoid unexpected loop quit racing condition // NOTE: set status here first to avoid unexpected loop quit racing condition
mStatus = MPP_THREAD_RUNNING; set_status(MPP_THREAD_RUNNING);
if (0 == pthread_create(&mThread, &attr, mFunction, mContext)) { if (0 == pthread_create(&mThread, &attr, mFunction, mContext)) {
#ifndef ARMLINUX #ifndef ARMLINUX
RK_S32 ret = pthread_setname_np(mThread, mName); RK_S32 ret = pthread_setname_np(mThread, mName);
@@ -67,16 +79,16 @@ void MppThread::start()
thread_dbg(MPP_THREAD_DBG_FUNCTION, "thread %s %p context %p create success\n", thread_dbg(MPP_THREAD_DBG_FUNCTION, "thread %s %p context %p create success\n",
mName, mFunction, mContext); mName, mFunction, mContext);
} else } else
mStatus = MPP_THREAD_UNINITED; set_status(MPP_THREAD_UNINITED);
} }
pthread_attr_destroy(&attr); pthread_attr_destroy(&attr);
} }
void MppThread::stop() void MppThread::stop()
{ {
if (MPP_THREAD_UNINITED != mStatus) { if (MPP_THREAD_UNINITED != get_status()) {
lock(); lock();
mStatus = MPP_THREAD_STOPPING; set_status(MPP_THREAD_STOPPING);
thread_dbg(MPP_THREAD_DBG_FUNCTION, thread_dbg(MPP_THREAD_DBG_FUNCTION,
"MPP_THREAD_STOPPING status set mThread %p", this); "MPP_THREAD_STOPPING status set mThread %p", this);
signal(); signal();
@@ -87,7 +99,7 @@ void MppThread::stop()
"thread %s %p context %p destroy success\n", "thread %s %p context %p destroy success\n",
mName, mFunction, mContext); mName, mFunction, mContext);
mStatus = MPP_THREAD_UNINITED; set_status(MPP_THREAD_UNINITED);
} }
} }