Add thread checks

pull/2/head
Stelios Bounanos 2008-10-07 08:41:23 +01:00
rodzic 1c9f450f60
commit ec83b170d0
7 zmienionych plików z 74 dodań i 62 usunięć

Wyświetl plik

@ -585,17 +585,12 @@ void init_modem(trx_mode mode)
void init_modem_sync(trx_mode m)
{
if (trx_state != STATE_RX)
return;
ENSURE_THREAD(FLMAIN_TID);
#ifndef NDEBUG
if (GET_THREAD_ID() == TRX_TID)
LOG_ERROR("trx thread called init_modem_sync!");
#endif
if (trx_state != STATE_RX)
TRX_WAIT(STATE_RX, abort_tx());
wait_modem_ready_prep();
init_modem(m);
wait_modem_ready_cmpl();
TRX_WAIT(STATE_RX, init_modem(m));
REQ_FLUSH(TRX_TID);
}

Wyświetl plik

@ -34,15 +34,6 @@
using namespace std;
const char *state_names[] = {
"PAUSED",
"RECEIVE",
"TRANSMIT",
"TUNING",
"ABORTED",
"FLUSHING"
};
// Elements are in enum trx_mode order. Mode name video-id uses the
// first string (sname), so its length should be a multiple of 2.
const struct mode_info_t mode_info[NUM_MODES] = {

Wyświetl plik

@ -44,7 +44,6 @@ enum state_t {
STATE_IDLE,
STATE_NEW_MODEM
};
extern const char *state_names[];
enum {
MODE_PREV = -2,

Wyświetl plik

@ -15,7 +15,7 @@ int sem_timedwait_rel(sem_t* sem, double rel_timeout);
int pthread_cond_timedwait_rel(pthread_cond_t* cond, pthread_mutex_t* mutex, double rel_timeout);
// 3 threads use qrunner
enum { UNKNOWN_TID = -1, TRX_TID, QRZ_TID, RIGCTL_TID,
enum { INVALID_TID = -1, TRX_TID, QRZ_TID, RIGCTL_TID,
#if USE_XMLRPC
XMLRPC_TID,
#endif
@ -25,16 +25,39 @@ enum { UNKNOWN_TID = -1, TRX_TID, QRZ_TID, RIGCTL_TID,
#if USE_TLS
# define THREAD_ID_TYPE __thread int
# define CREATE_THREAD_ID() thread_id_ = UNKNOWN_TID
# define CREATE_THREAD_ID() thread_id_ = INVALID_TID
# define SET_THREAD_ID(x) thread_id_ = (x)
# define GET_THREAD_ID() thread_id_
#else
# define THREAD_ID_TYPE pthread_key_t
# define CREATE_THREAD_ID() pthread_key_create(&thread_id_, 0);
# define CREATE_THREAD_ID() pthread_key_create(&thread_id_, 0)
# define SET_THREAD_ID(x) pthread_setspecific(thread_id_, (void *)(x))
# define GET_THREAD_ID() (int)pthread_getspecific(thread_id_)
#endif // USE_TLS
#ifndef NDEBUG
# include "debug.h"
bool thread_in_list(int id, const int* list);
# define ENSURE_THREAD(...) \
do { \
int id_ = GET_THREAD_ID(); \
int t_[] = { __VA_ARGS__, INVALID_TID }; \
if (!thread_in_list(id_, t_)) \
LOG_ERROR("bad thread context: %d", id_); \
} while (0)
# define ENSURE_NOT_THREAD(...) \
do { \
int id_ = GET_THREAD_ID(); \
int t_[] = { __VA_ARGS__, INVALID_TID }; \
if (thread_in_list(id_, t_)) \
LOG_ERROR("bad thread context: %d", id_); \
} while (0)
#else
# define ENSURE_THREAD(...) ((void)0)
# define ENSURE_NOT_THREAD(...) ((void)0)
#endif // ! NDEBUG
extern THREAD_ID_TYPE thread_id_;
#include "fl_lock.h"

Wyświetl plik

@ -48,9 +48,9 @@ extern void trx_receive();
extern void trx_reset(void);
extern void trx_start_macro_timer();
extern void wait_modem_ready_prep(void);
extern void wait_modem_ready_cmpl(void);
extern void signal_modem_ready(void);
extern void wait_trx_state_prep(void);
extern void wait_trx_state_wait(void);
extern void wait_trx_state_cmpl(void);
extern void macro_timer(void *);
@ -62,4 +62,14 @@ extern SoundBase *scard;
extern bool bHistory;
#define TRX_WAIT(s_, code_) \
do { \
ENSURE_NOT_THREAD(TRX_TID); \
wait_trx_state_prep(); \
code_; \
while (trx_state != s_) \
wait_trx_state_wait(); \
wait_trx_state_cmpl(); \
} while (0)
#endif

Wyświetl plik

@ -54,3 +54,13 @@ int pthread_cond_timedwait_rel(pthread_cond_t* cond, pthread_mutex_t* mutex, dou
return pthread_cond_timedwait(cond, mutex, &t);
}
#ifndef NDEBUG
bool thread_in_list(int id, const int* list)
{
while (*list != INVALID_TID)
if (id == *list++)
return true;
return false;
}
#endif

Wyświetl plik

@ -52,6 +52,7 @@ void trx_start_modem_loop();
void trx_receive_loop();
void trx_transmit_loop();
void trx_tune_loop();
static void signal_trx_state(void);
//#define DEBUG
@ -321,7 +322,13 @@ void *trx_loop(void *args)
{
SET_THREAD_ID(TRX_TID);
state_t old_state = STATE_NOOP;
for (;;) {
if (unlikely(old_state != trx_state)) {
old_state = trx_state;
signal_trx_state();
}
switch (trx_state) {
case STATE_ABORT:
delete scard;
@ -351,32 +358,21 @@ void *trx_loop(void *args)
}
//=============================================================================
modem *trx_m;
modem* new_modem;
void trx_start_modem_loop()
{
if (trx_m == active_modem) {
trx_state = STATE_RX;
if (new_modem == active_modem) {
active_modem->restart();
signal_modem_ready();
trx_state = STATE_RX;
return;
}
modem* old_modem = active_modem;
if (old_modem == trx_m) {
trx_state = STATE_RX;
signal_modem_ready();
return;
}
if (old_modem)
old_modem->shutdown();
active_modem = trx_m;
active_modem->init();
new_modem->init();
active_modem = new_modem;
trx_state = STATE_RX;
signal_modem_ready();
REQ(&waterfall::opmode, wf);
if (old_modem) {
@ -388,7 +384,7 @@ void trx_start_modem_loop()
//=============================================================================
void trx_start_modem(modem *m)
{
trx_m = m;
new_modem = m;
trx_state = STATE_NEW_MODEM;
}
@ -538,36 +534,24 @@ void trx_tune(void) { trx_state = STATE_TUNE; }
void trx_receive(void) { trx_state = STATE_RX; }
//=============================================================================
void wait_modem_ready_prep(void)
{
#ifndef NDEBUG
if (GET_THREAD_ID() == TRX_TID)
LOG_ERROR("trx thread called wait_modem_ready_prep!");
#endif
void wait_trx_state_prep(void)
{
pthread_mutex_lock(&trx_cond_mutex);
}
void wait_modem_ready_cmpl(void)
void wait_trx_state_wait(void)
{
#ifndef NDEBUG
if (GET_THREAD_ID() == TRX_TID)
LOG_ERROR("trx thread called wait_modem_ready_cmpl!");
#endif
pthread_cond_wait(&trx_cond, &trx_cond_mutex);
}
void wait_trx_state_cmpl(void)
{
pthread_mutex_unlock(&trx_cond_mutex);
}
void signal_modem_ready(void)
static void signal_trx_state(void)
{
#ifndef NDEBUG
if (GET_THREAD_ID() != TRX_TID)
LOG_ERROR("thread %d called signal_modem_ready!", GET_THREAD_ID());
#endif
ENSURE_THREAD(TRX_TID);
pthread_mutex_lock(&trx_cond_mutex);
pthread_cond_broadcast(&trx_cond);
pthread_mutex_unlock(&trx_cond_mutex);
}