mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-09-26 21:15:53 +08:00
fix[osal]: Fix timeout expire too soon issue
Using CLOCK_MONOTONIC instead of CLOCK_REALTIME to avoid date-2038 issue. Also timeout will expire sooner or later than intended if using CLOCK_REALTIME when clock changed dramatically. Platform: 32-bit program Spec: all Reported-by: #555412 at redmine Reprodece: 1. setting system date after 2040-01-01 2. running 32-bit program calling mpp video encoder at non-block mode with 100ms timeout. eg: screenrecord at Android 11. This program will call mpp via vpu_api_legacy routine with a 100ms timeout. 3. timeout will expire sooner than 100ms. Change-Id: I804146d6e33f5c30cbd3bdfdcf10b6dd56b0610c Signed-off-by: Johnson Ding <johnson.ding@rock-chips.com>
This commit is contained in:

committed by
Herman Chen

parent
9c93a16e11
commit
0a0111b398
@@ -20,6 +20,10 @@
|
|||||||
#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER
|
#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__USE_XOPEN2K) || (defined(__ANDROID__) && __ANDROID_API__ >= 21)
|
||||||
|
#define COND_USE_CLOCK_MONOTONIC
|
||||||
|
#endif
|
||||||
|
|
||||||
#define THREAD_NAME_LEN 16
|
#define THREAD_NAME_LEN 16
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -37,16 +41,17 @@ typedef enum MppThreadStatus_e {
|
|||||||
} MppThreadStatus;
|
} MppThreadStatus;
|
||||||
|
|
||||||
typedef struct MppMutex_t {
|
typedef struct MppMutex_t {
|
||||||
pthread_mutex_t m_lock;
|
pthread_mutex_t lock;
|
||||||
} MppMutex;
|
} MppMutex;
|
||||||
|
|
||||||
typedef struct MppCond_t {
|
typedef struct MppCond_t {
|
||||||
pthread_cond_t m_cond;
|
pthread_cond_t cond;
|
||||||
|
clockid_t clock_id;
|
||||||
} MppCond;
|
} MppCond;
|
||||||
|
|
||||||
typedef struct MppMutexCond_t {
|
typedef struct MppMutexCond_t {
|
||||||
MppMutex m_lock;
|
MppMutex lock;
|
||||||
MppCond m_cond;
|
MppCond cond;
|
||||||
} MppMutexCond;
|
} MppMutexCond;
|
||||||
|
|
||||||
typedef enum MppThreadSignalId_e {
|
typedef enum MppThreadSignalId_e {
|
||||||
@@ -63,7 +68,7 @@ typedef struct MppThread_t {
|
|||||||
MppThreadStatus thd_status[THREAD_SIGNAL_BUTT];
|
MppThreadStatus thd_status[THREAD_SIGNAL_BUTT];
|
||||||
MppThreadFunc func;
|
MppThreadFunc func;
|
||||||
char name[THREAD_NAME_LEN];
|
char name[THREAD_NAME_LEN];
|
||||||
void *m_ctx;
|
void *ctx;
|
||||||
} MppThread;
|
} MppThread;
|
||||||
|
|
||||||
// Mutex functions
|
// Mutex functions
|
||||||
|
@@ -25,7 +25,7 @@ MppThread *mpp_thread_create(MppThreadFunc func, void *ctx, const char *name)
|
|||||||
|
|
||||||
if (thread) {
|
if (thread) {
|
||||||
thread->func = func;
|
thread->func = func;
|
||||||
thread->m_ctx = ctx;
|
thread->ctx = ctx;
|
||||||
|
|
||||||
thread->thd_status[THREAD_WORK] = MPP_THREAD_UNINITED;
|
thread->thd_status[THREAD_WORK] = MPP_THREAD_UNINITED;
|
||||||
thread->thd_status[THREAD_INPUT] = MPP_THREAD_RUNNING;
|
thread->thd_status[THREAD_INPUT] = MPP_THREAD_RUNNING;
|
||||||
@@ -62,7 +62,7 @@ void mpp_thread_start(MppThread *thread)
|
|||||||
|
|
||||||
if (mpp_thread_get_status(thread, THREAD_WORK) == MPP_THREAD_UNINITED) {
|
if (mpp_thread_get_status(thread, THREAD_WORK) == MPP_THREAD_UNINITED) {
|
||||||
mpp_thread_set_status(thread, MPP_THREAD_RUNNING, THREAD_WORK);
|
mpp_thread_set_status(thread, MPP_THREAD_RUNNING, THREAD_WORK);
|
||||||
if (0 == pthread_create(&thread->thd, &attr, thread->func, thread->m_ctx)) {
|
if (0 == pthread_create(&thread->thd, &attr, thread->func, thread->ctx)) {
|
||||||
#ifndef __linux__
|
#ifndef __linux__
|
||||||
int ret = pthread_setname_np(thread->thd, thread->name);
|
int ret = pthread_setname_np(thread->thd, thread->name);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -70,7 +70,7 @@ void mpp_thread_start(MppThread *thread)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
thread_dbg(THREAD_DBG_FUNC, "thread %s %p context %p create success\n",
|
thread_dbg(THREAD_DBG_FUNC, "thread %s %p context %p create success\n",
|
||||||
thread->name, thread->func, thread->m_ctx);
|
thread->name, thread->func, thread->ctx);
|
||||||
} else {
|
} else {
|
||||||
mpp_thread_set_status(thread, MPP_THREAD_UNINITED, THREAD_WORK);
|
mpp_thread_set_status(thread, MPP_THREAD_UNINITED, THREAD_WORK);
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,7 @@ void mpp_thread_stop(MppThread *thread)
|
|||||||
mpp_thread_unlock(thread, THREAD_WORK);
|
mpp_thread_unlock(thread, THREAD_WORK);
|
||||||
|
|
||||||
pthread_join(thread->thd, &dummy);
|
pthread_join(thread->thd, &dummy);
|
||||||
thread_dbg(THREAD_DBG_FUNC, "thread %s %p context %p destroy success\n", thread->name, thread->func, thread->m_ctx);
|
thread_dbg(THREAD_DBG_FUNC, "thread %s %p context %p destroy success\n", thread->name, thread->func, thread->ctx);
|
||||||
|
|
||||||
mpp_thread_set_status(thread, MPP_THREAD_UNINITED, THREAD_WORK);
|
mpp_thread_set_status(thread, MPP_THREAD_UNINITED, THREAD_WORK);
|
||||||
}
|
}
|
||||||
@@ -111,122 +111,140 @@ void mpp_mutex_init(MppMutex *mutex)
|
|||||||
pthread_mutexattr_t attr;
|
pthread_mutexattr_t attr;
|
||||||
pthread_mutexattr_init(&attr);
|
pthread_mutexattr_init(&attr);
|
||||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||||
pthread_mutex_init(&mutex->m_lock, &attr);
|
pthread_mutex_init(&mutex->lock, &attr);
|
||||||
pthread_mutexattr_destroy(&attr);
|
pthread_mutexattr_destroy(&attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mpp_mutex_destroy(MppMutex *mutex)
|
void mpp_mutex_destroy(MppMutex *mutex)
|
||||||
{
|
{
|
||||||
pthread_mutex_destroy(&mutex->m_lock);
|
pthread_mutex_destroy(&mutex->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mpp_mutex_lock(MppMutex *mutex)
|
void mpp_mutex_lock(MppMutex *mutex)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&mutex->m_lock);
|
pthread_mutex_lock(&mutex->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mpp_mutex_unlock(MppMutex *mutex)
|
void mpp_mutex_unlock(MppMutex *mutex)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&mutex->m_lock);
|
pthread_mutex_unlock(&mutex->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mpp_mutex_trylock(MppMutex *mutex)
|
int mpp_mutex_trylock(MppMutex *mutex)
|
||||||
{
|
{
|
||||||
return pthread_mutex_trylock(&mutex->m_lock);
|
return pthread_mutex_trylock(&mutex->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MppCond functions
|
// MppCond functions
|
||||||
void mpp_cond_init(MppCond *condition)
|
void mpp_cond_init(MppCond *condition)
|
||||||
{
|
{
|
||||||
pthread_cond_init(&condition->m_cond, NULL);
|
#ifdef COND_USE_CLOCK_MONOTONIC
|
||||||
|
pthread_condattr_t attr;
|
||||||
|
|
||||||
|
pthread_condattr_init(&attr);;
|
||||||
|
|
||||||
|
if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)) {
|
||||||
|
pthread_cond_init(&condition->cond, NULL);
|
||||||
|
condition->clock_id = CLOCK_REALTIME;
|
||||||
|
} else {
|
||||||
|
pthread_cond_init(&condition->cond, &attr);
|
||||||
|
condition->clock_id = CLOCK_MONOTONIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_condattr_destroy(&attr);
|
||||||
|
#else
|
||||||
|
pthread_cond_init(&condition->cond, NULL);
|
||||||
|
condition->clock_id = CLOCK_REALTIME;
|
||||||
|
#endif // COND_USE_CLOCK_MONOTONIC
|
||||||
}
|
}
|
||||||
|
|
||||||
void mpp_cond_destroy(MppCond *condition)
|
void mpp_cond_destroy(MppCond *condition)
|
||||||
{
|
{
|
||||||
pthread_cond_destroy(&condition->m_cond);
|
pthread_cond_destroy(&condition->cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
rk_s32 mpp_cond_wait(MppCond *condition, MppMutex *mutex)
|
rk_s32 mpp_cond_wait(MppCond *condition, MppMutex *mutex)
|
||||||
{
|
{
|
||||||
return pthread_cond_wait(&condition->m_cond, &mutex->m_lock);
|
return pthread_cond_wait(&condition->cond, &mutex->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
rk_s32 mpp_cond_timedwait(MppCond *condition, MppMutex *mutex, rk_s64 timeout)
|
rk_s32 mpp_cond_timedwait(MppCond *condition, MppMutex *mutex, rk_s64 timeout)
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
clock_gettime(CLOCK_REALTIME, &ts);
|
|
||||||
|
clock_gettime(condition->clock_id, &ts);
|
||||||
|
|
||||||
ts.tv_sec += timeout / 1000;
|
ts.tv_sec += timeout / 1000;
|
||||||
ts.tv_nsec += (timeout % 1000) * 1000000;
|
ts.tv_nsec += (timeout % 1000) * 1000000;
|
||||||
ts.tv_sec += ts.tv_nsec / 1000000000;
|
ts.tv_sec += ts.tv_nsec / 1000000000;
|
||||||
ts.tv_nsec %= 1000000000;
|
ts.tv_nsec %= 1000000000;
|
||||||
|
|
||||||
return pthread_cond_timedwait(&condition->m_cond, &mutex->m_lock, &ts);
|
return pthread_cond_timedwait(&condition->cond, &mutex->lock, &ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
rk_s32 mpp_cond_signal(MppCond *condition)
|
rk_s32 mpp_cond_signal(MppCond *condition)
|
||||||
{
|
{
|
||||||
return pthread_cond_signal(&condition->m_cond);
|
return pthread_cond_signal(&condition->cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
rk_s32 mpp_cond_broadcast(MppCond *condition)
|
rk_s32 mpp_cond_broadcast(MppCond *condition)
|
||||||
{
|
{
|
||||||
return pthread_cond_broadcast(&condition->m_cond);
|
return pthread_cond_broadcast(&condition->cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MppMutexCond functions
|
// MppMutexCond functions
|
||||||
void mpp_mutex_cond_init(MppMutexCond *mutexCond)
|
void mpp_mutex_cond_init(MppMutexCond *mutexCond)
|
||||||
{
|
{
|
||||||
mpp_mutex_init(&mutexCond->m_lock);
|
mpp_mutex_init(&mutexCond->lock);
|
||||||
mpp_cond_init(&mutexCond->m_cond);
|
mpp_cond_init(&mutexCond->cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mpp_mutex_cond_destroy(MppMutexCond *mutexCond)
|
void mpp_mutex_cond_destroy(MppMutexCond *mutexCond)
|
||||||
{
|
{
|
||||||
mpp_mutex_destroy(&mutexCond->m_lock);
|
mpp_mutex_destroy(&mutexCond->lock);
|
||||||
mpp_cond_destroy(&mutexCond->m_cond);
|
mpp_cond_destroy(&mutexCond->cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mpp_mutex_cond_lock(MppMutexCond *mutexCond)
|
void mpp_mutex_cond_lock(MppMutexCond *mutexCond)
|
||||||
{
|
{
|
||||||
mpp_mutex_lock(&mutexCond->m_lock);
|
mpp_mutex_lock(&mutexCond->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mpp_mutex_cond_unlock(MppMutexCond *mutexCond)
|
void mpp_mutex_cond_unlock(MppMutexCond *mutexCond)
|
||||||
{
|
{
|
||||||
mpp_mutex_unlock(&mutexCond->m_lock);
|
mpp_mutex_unlock(&mutexCond->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mpp_mutex_cond_trylock(MppMutexCond *mutexCond)
|
int mpp_mutex_cond_trylock(MppMutexCond *mutexCond)
|
||||||
{
|
{
|
||||||
return mpp_mutex_trylock(&mutexCond->m_lock);
|
return mpp_mutex_trylock(&mutexCond->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
rk_s32 mpp_mutex_cond_wait(MppMutexCond *mutexCond)
|
rk_s32 mpp_mutex_cond_wait(MppMutexCond *mutexCond)
|
||||||
{
|
{
|
||||||
return mpp_cond_wait(&mutexCond->m_cond, &mutexCond->m_lock);
|
return mpp_cond_wait(&mutexCond->cond, &mutexCond->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
rk_s32 mpp_mutex_cond_timedwait(MppMutexCond *mutexCond, rk_s64 timeout)
|
rk_s32 mpp_mutex_cond_timedwait(MppMutexCond *mutexCond, rk_s64 timeout)
|
||||||
{
|
{
|
||||||
return mpp_cond_timedwait(&mutexCond->m_cond, &mutexCond->m_lock, timeout);
|
return mpp_cond_timedwait(&mutexCond->cond, &mutexCond->lock, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mpp_mutex_cond_signal(MppMutexCond *mutexCond)
|
void mpp_mutex_cond_signal(MppMutexCond *mutexCond)
|
||||||
{
|
{
|
||||||
mpp_cond_signal(&mutexCond->m_cond);
|
mpp_cond_signal(&mutexCond->cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mpp_mutex_cond_broadcast(MppMutexCond *mutexCond)
|
void mpp_mutex_cond_broadcast(MppMutexCond *mutexCond)
|
||||||
{
|
{
|
||||||
mpp_cond_broadcast(&mutexCond->m_cond);
|
mpp_cond_broadcast(&mutexCond->cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MppThread functions
|
// MppThread functions
|
||||||
void mpp_thread_init(MppThread *thread, MppThreadFunc func, void *ctx, const char *name)
|
void mpp_thread_init(MppThread *thread, MppThreadFunc func, void *ctx, const char *name)
|
||||||
{
|
{
|
||||||
thread->func = func;
|
thread->func = func;
|
||||||
thread->m_ctx = ctx;
|
thread->ctx = ctx;
|
||||||
if (name) {
|
if (name) {
|
||||||
strncpy(thread->name, name, THREAD_NAME_LEN - 1);
|
strncpy(thread->name, name, THREAD_NAME_LEN - 1);
|
||||||
thread->name[THREAD_NAME_LEN - 1] = '\0';
|
thread->name[THREAD_NAME_LEN - 1] = '\0';
|
||||||
|
Reference in New Issue
Block a user