kopia lustrzana https://github.com/jamescoxon/dl-fldigi
Add thread checks
rodzic
1c9f450f60
commit
ec83b170d0
|
@ -585,17 +585,12 @@ void init_modem(trx_mode mode)
|
|||
|
||||
void init_modem_sync(trx_mode m)
|
||||
{
|
||||
ENSURE_THREAD(FLMAIN_TID);
|
||||
|
||||
if (trx_state != STATE_RX)
|
||||
return;
|
||||
TRX_WAIT(STATE_RX, abort_tx());
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (GET_THREAD_ID() == TRX_TID)
|
||||
LOG_ERROR("trx thread called init_modem_sync!");
|
||||
#endif
|
||||
|
||||
wait_modem_ready_prep();
|
||||
init_modem(m);
|
||||
wait_modem_ready_cmpl();
|
||||
TRX_WAIT(STATE_RX, init_modem(m));
|
||||
REQ_FLUSH(TRX_TID);
|
||||
}
|
||||
|
||||
|
|
|
@ -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] = {
|
||||
|
|
|
@ -44,7 +44,6 @@ enum state_t {
|
|||
STATE_IDLE,
|
||||
STATE_NEW_MODEM
|
||||
};
|
||||
extern const char *state_names[];
|
||||
|
||||
enum {
|
||||
MODE_PREV = -2,
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
new_modem->init();
|
||||
active_modem = new_modem;
|
||||
trx_state = STATE_RX;
|
||||
signal_modem_ready();
|
||||
return;
|
||||
}
|
||||
|
||||
if (old_modem)
|
||||
old_modem->shutdown();
|
||||
|
||||
active_modem = trx_m;
|
||||
active_modem->init();
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue