Skip to content

Instantly share code, notes, and snippets.

@ryos36
Created June 16, 2023 02:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryos36/a251b74dc8c8976a53947ae145b3799d to your computer and use it in GitHub Desktop.
Save ryos36/a251b74dc8c8976a53947ae145b3799d to your computer and use it in GitHub Desktop.
Pthread の mutex_cond を TKernel に移植。tk で始まるがオーソライズされた API ではない。テストが不十分なので broadcast は怪しい。
/* 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