Created
June 16, 2023 02:07
-
-
Save ryos36/a251b74dc8c8976a53947ae145b3799d to your computer and use it in GitHub Desktop.
Pthread の mutex_cond を TKernel に移植。tk で始まるがオーソライズされた API ではない。テストが不十分なので broadcast は怪しい。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Copyright (C) 2007, 2016 Sinby Corporation. All Rights Reserved. */ | |
#ifndef __LIB_TK_MUTEX_COND_H__ | |
#define __LIB_TK_MUTEX_COND_H__ | |
#include <assert.h> | |
#include <stdbool.h> | |
#include "kernel.h" | |
//------------------------------------------------------------------------ | |
// 初期値 0 , 最大値 1 のセマフォを期待している | |
struct tk_mutex_cond { | |
ID mutex_id; | |
ID semaphore_id; | |
}; | |
//------------------------------------------------------------------------ | |
static | |
inline | |
void tk_mutex_cond_init(struct tk_mutex_cond *mcond) | |
{ | |
T_CMTX pk_cmtx; | |
T_CSEM pk_csem; | |
pk_cmtx.exinf = 0; | |
pk_cmtx.mtxatr = TA_INHERIT; | |
pk_cmtx.ceilpri = 0; | |
mcond->mutex_id = tk_cre_mtx(&pk_cmtx); | |
assert(0 < mcond->mutex_id); | |
pk_csem.exinf = 0; | |
pk_csem.sematr = TA_TFIFO | TA_FIRST; | |
pk_csem.isemcnt = 0; | |
pk_csem.maxsem = 1; | |
mcond->semaphore_id = tk_cre_sem(&pk_csem); | |
assert(0 < mcond->semaphore_id); | |
} | |
//------------------------------------------------------------------------ | |
static | |
inline | |
void tk_mutex_cond_reinit(struct tk_mutex_cond *mcond) | |
{ | |
T_RSEM pk_rsem; | |
ER er; | |
er = tk_ref_sem(mcond->semaphore_id, &pk_rsem); | |
assert( er == E_OK ); | |
if ( pk_rsem.semcnt == 1 ) { | |
er = tk_wai_sem(mcond->semaphore_id, 1, TMO_POL); | |
assert(er == E_OK); | |
} | |
} | |
//---------------------------------------------------------------- | |
static | |
inline | |
void tk_mutex_cond_term(struct tk_mutex_cond *mcond) | |
{ | |
ER er; | |
er = tk_del_mtx(mcond->mutex_id); | |
assert( er == E_OK ); | |
er = tk_del_sem(mcond->semaphore_id); | |
assert( er == E_OK ); | |
} | |
//---------------------------------------------------------------- | |
static inline | |
void | |
tk_mutex_cond_lock(struct tk_mutex_cond *mcond) | |
{ | |
ER er; | |
er = tk_loc_mtx(mcond->mutex_id, TMO_FEVR); | |
assert( er == E_OK ); | |
} | |
//-------------------------------------------------------- | |
static inline | |
void | |
tk_mutex_cond_unlock(struct tk_mutex_cond *mcond) | |
{ | |
ER er; | |
er = tk_unl_mtx(mcond->mutex_id); | |
assert( er == E_OK ); | |
} | |
//--------------------------------------------------- | |
static | |
inline | |
void | |
tk_mutex_cond_wait(struct tk_mutex_cond *mcond) | |
{ | |
ER er; | |
tk_mutex_cond_unlock(mcond); | |
er = tk_wai_sem(mcond->semaphore_id, 1, TMO_FEVR); | |
assert(er == E_OK); | |
tk_mutex_cond_lock(mcond); | |
}; | |
//-------------------------------------------------------------------------- | |
static | |
inline | |
bool | |
tk_mutex_cond_timed_wait(struct tk_mutex_cond *mcond, unsigned int *msec) | |
{ | |
ER er; | |
SYSTIM stim0, stim1; // SYSTIM is long long | |
er = tk_get_otm(&stim0); | |
assert(er == E_OK); | |
tk_mutex_cond_unlock(mcond); | |
er = tk_wai_sem(mcond->semaphore_id, 1, *msec); | |
assert((er == E_OK) || ( er == E_TMOUT)); | |
tk_mutex_cond_lock(mcond); | |
if ( er == E_TMOUT ) { | |
*msec = 0; | |
return false; | |
} | |
er = tk_get_otm(&stim1); | |
assert(er == E_OK); | |
unsigned int time_diff_msec; | |
if ( stim0.hi == stim1.hi ) { | |
time_diff_msec = (unsigned int)(stim1.lo - stim0.lo); | |
} else { | |
time_diff_msec = (unsigned int)(stim1.lo + ~stim0.lo); | |
} | |
if ( *msec <= time_diff_msec ) { | |
*msec = 0; | |
} else { | |
*msec -= time_diff_msec; | |
} | |
return true; | |
} | |
//-------------------------------------------------------------------------- | |
static inline | |
void | |
tk_mutex_cond_signal(struct tk_mutex_cond *mcond) | |
{ | |
ER er; | |
er = tk_sig_sem(mcond->semaphore_id, 1); | |
assert((er == E_OK) || ( er == E_QOVR)); | |
}; | |
//--------------------------------------------------- | |
static inline | |
void | |
tk_mutex_cond_broadcast(struct tk_mutex_cond *mcond) | |
{ | |
ER er; | |
T_RSEM k_rsem; | |
tk_mutex_cond_lock(mcond); | |
do { | |
er = tk_sig_sem(mcond->semaphore_id, 1); | |
assert((er == E_OK) || ( er == E_QOVR)); | |
if ( er == E_QOVR ) { | |
break; | |
} | |
er = tk_ref_sem(mcond->semaphore_id, &k_rsem); | |
assert(er == E_OK); | |
if ( k_rsem.wtsk == 0 ) { | |
break; | |
} | |
} while ( true ); | |
tk_mutex_cond_unlock(mcond); | |
} | |
#endif // __LIB_TK_MUTEX_COND_H__ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment