Datenklo: Timers may only be scheduled or deleted in the main thread
Set flags to schedule timers in main thread. Timers are: vtimer (datenklo.c), tx/rx timers (am791x.c)
This commit is contained in:
+70
-28
@@ -587,7 +587,6 @@ static void set_flag(int *flag_p, int value, const char *name)
|
||||
/*
|
||||
* state machine according to datasheet
|
||||
*/
|
||||
|
||||
static void go_main_channel_tx(am791x_t *am791x)
|
||||
{
|
||||
LOGP(DAM791X, LOGL_DEBUG, "Enable transmitter on main channel\n");
|
||||
@@ -601,7 +600,8 @@ static void go_main_channel_tx(am791x_t *am791x)
|
||||
/* activate TD now and set CTS timer (RCON) */
|
||||
set_flag(&am791x->block_td, 0, "TD RELEASED");
|
||||
set_flag(&am791x->tx_silence, 0, "RESET SILENCE");
|
||||
osmo_timer_schedule(&am791x->tx_timer, FLOAT_TO_TIMEOUT(am791x->t_rcon));
|
||||
/* Flag timer, because it must be added in main thread. */
|
||||
am791x->tx_timer_f = am791x->t_rcon;
|
||||
new_tx_state(am791x, AM791X_STATE_RCON);
|
||||
set_filters(am791x);
|
||||
/* check CD to be blocked */
|
||||
@@ -652,7 +652,8 @@ static void tx_data_done(am791x_t *am791x)
|
||||
if (!am791x->fullduplex) {
|
||||
set_flag(&am791x->squelch, 1, "SET SQUELCH (ON)");
|
||||
}
|
||||
osmo_timer_schedule(&am791x->tx_timer, FLOAT_TO_TIMEOUT(am791x->t_rcoff));
|
||||
/* Flag timer, because it must be added in main thread. */
|
||||
am791x->tx_timer_f = am791x->t_rcoff;
|
||||
}
|
||||
|
||||
static void rcoff_done(am791x_t *am791x)
|
||||
@@ -667,11 +668,13 @@ static void rcoff_done(am791x_t *am791x)
|
||||
return;
|
||||
}
|
||||
if (!am791x->sto) {
|
||||
osmo_timer_schedule(&am791x->tx_timer, FLOAT_TO_TIMEOUT(am791x->t_sq - am791x->t_rcoff));
|
||||
/* Flag timer, because it must be added in main thread. */
|
||||
am791x->tx_timer_f = am791x->t_sq - am791x->t_rcoff;
|
||||
new_tx_state(am791x, AM791X_STATE_SQ_OFF);
|
||||
return;
|
||||
}
|
||||
osmo_timer_schedule(&am791x->tx_timer, FLOAT_TO_TIMEOUT(am791x->t_sto - am791x->t_rcoff));
|
||||
/* Flag timer, because it must be added in main thread. */
|
||||
am791x->tx_timer_f = am791x->t_sto - am791x->t_rcoff;
|
||||
new_tx_state(am791x, AM791X_STATE_STO_OFF);
|
||||
}
|
||||
|
||||
@@ -695,7 +698,8 @@ static void sto_done(am791x_t *am791x)
|
||||
LOGP(DAM791X, LOGL_DEBUG, "STO over\n");
|
||||
|
||||
set_flag(&am791x->tx_sto, 0, "stop STO");
|
||||
osmo_timer_schedule(&am791x->tx_timer, FLOAT_TO_TIMEOUT(am791x->t_sq - am791x->t_sto));
|
||||
/* Flag timer, because it must be added in main thread. */
|
||||
am791x->tx_timer_f = am791x->t_sq - am791x->t_sto;
|
||||
new_tx_state(am791x, AM791X_STATE_SQ_OFF);
|
||||
}
|
||||
|
||||
@@ -711,7 +715,8 @@ static void go_back_channel_tx(am791x_t *am791x)
|
||||
/* activate BTD now and set BCTS timer (BRCON) */
|
||||
set_flag(&am791x->block_btd, 0, "BTD RELEASED");
|
||||
set_flag(&am791x->tx_silence, 0, "RESET SILENCE");
|
||||
osmo_timer_schedule(&am791x->tx_timer, FLOAT_TO_TIMEOUT(am791x->t_brcon));
|
||||
/* Flag timer, because it must be added in main thread. */
|
||||
am791x->tx_timer_f = am791x->t_brcon;
|
||||
new_tx_state(am791x, AM791X_STATE_BRCON);
|
||||
set_filters(am791x);
|
||||
/* check BCD to be blocked */
|
||||
@@ -747,7 +752,8 @@ static void tx_bdata_done(am791x_t *am791x)
|
||||
|
||||
set_flag(&am791x->block_btd, 1, "BTD IGNORED");
|
||||
set_flag(&am791x->tx_silence, 1, "SET SILENCE");
|
||||
osmo_timer_schedule(&am791x->tx_timer, FLOAT_TO_TIMEOUT(am791x->t_brcoff));
|
||||
/* Flag timer, because it must be added in main thread. */
|
||||
am791x->tx_timer_f = am791x->t_brcoff;
|
||||
}
|
||||
|
||||
static void brcoff_done(am791x_t *am791x)
|
||||
@@ -793,7 +799,8 @@ static void handle_tx_state(am791x_t *am791x)
|
||||
rcon_release_rts(am791x);
|
||||
break;
|
||||
}
|
||||
if (!osmo_timer_pending(&am791x->tx_timer)) {
|
||||
/* If timer is about to be switched off, of if it already has been switched off. */
|
||||
if (am791x->tx_timer_f < 0.0 || (!osmo_timer_pending(&am791x->tx_timer) && am791x->tx_timer_f == 0.0)) {
|
||||
rcon_done(am791x);
|
||||
break;
|
||||
}
|
||||
@@ -805,19 +812,22 @@ static void handle_tx_state(am791x_t *am791x)
|
||||
}
|
||||
break;
|
||||
case AM791X_STATE_RCOFF:
|
||||
if (!osmo_timer_pending(&am791x->tx_timer)) {
|
||||
/* If timer is about to be switched off, of if it already has been switched off. */
|
||||
if (am791x->tx_timer_f < 0.0 || (!osmo_timer_pending(&am791x->tx_timer) && am791x->tx_timer_f == 0.0)) {
|
||||
rcoff_done(am791x);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AM791X_STATE_STO_OFF:
|
||||
if (!osmo_timer_pending(&am791x->tx_timer)) {
|
||||
/* If timer is about to be switched off, of if it already has been switched off. */
|
||||
if (am791x->tx_timer_f < 0.0 || (!osmo_timer_pending(&am791x->tx_timer) && am791x->tx_timer_f == 0.0)) {
|
||||
sto_done(am791x);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AM791X_STATE_SQ_OFF:
|
||||
if (!osmo_timer_pending(&am791x->tx_timer)) {
|
||||
/* If timer is about to be switched off, of if it already has been switched off. */
|
||||
if (am791x->tx_timer_f < 0.0 || (!osmo_timer_pending(&am791x->tx_timer) && am791x->tx_timer_f == 0.0)) {
|
||||
sq_done(am791x);
|
||||
break;
|
||||
}
|
||||
@@ -828,7 +838,8 @@ static void handle_tx_state(am791x_t *am791x)
|
||||
brcon_release_brts(am791x);
|
||||
break;
|
||||
}
|
||||
if (!osmo_timer_pending(&am791x->tx_timer)) {
|
||||
/* If timer is about to be switched off, of if it already has been switched off. */
|
||||
if (am791x->tx_timer_f < 0.0 || (!osmo_timer_pending(&am791x->tx_timer) && am791x->tx_timer_f == 0.0)) {
|
||||
brcon_done(am791x);
|
||||
break;
|
||||
}
|
||||
@@ -840,7 +851,8 @@ static void handle_tx_state(am791x_t *am791x)
|
||||
}
|
||||
break;
|
||||
case AM791X_STATE_BRCOFF:
|
||||
if (!osmo_timer_pending(&am791x->tx_timer)) {
|
||||
/* If timer is about to be switched off, of if it already has been switched off. */
|
||||
if (am791x->tx_timer_f < 0.0 || (!osmo_timer_pending(&am791x->tx_timer) && am791x->tx_timer_f == 0.0)) {
|
||||
brcoff_done(am791x);
|
||||
break;
|
||||
}
|
||||
@@ -854,7 +866,8 @@ static void go_main_channel_rx(am791x_t *am791x)
|
||||
{
|
||||
LOGP(DAM791X, LOGL_DEBUG, "Enable receiver on main channel\n");
|
||||
|
||||
osmo_timer_schedule(&am791x->rx_timer, FLOAT_TO_TIMEOUT(am791x->t_cdon));
|
||||
/* Flag timer, because it must be added in main thread. */
|
||||
am791x->rx_timer_f = am791x->t_cdon;
|
||||
new_rx_state(am791x, AM791X_STATE_CDON);
|
||||
}
|
||||
|
||||
@@ -876,7 +889,8 @@ static void cdon_no_cd(am791x_t *am791x)
|
||||
{
|
||||
LOGP(DAM791X, LOGL_DEBUG, "Carrier is gone\n");
|
||||
|
||||
osmo_timer_del(&am791x->rx_timer);
|
||||
/* Flag timer, because it must be deleted in main thread. */
|
||||
am791x->rx_timer_f = -1;
|
||||
new_rx_state(am791x, AM791X_STATE_INIT);
|
||||
}
|
||||
|
||||
@@ -884,7 +898,8 @@ static void rx_data_done(am791x_t *am791x)
|
||||
{
|
||||
LOGP(DAM791X, LOGL_DEBUG, "Carrier lost\n");
|
||||
|
||||
osmo_timer_schedule(&am791x->rx_timer, FLOAT_TO_TIMEOUT(am791x->t_cdoff));
|
||||
/* Flag timer, because it must be added in main thread. */
|
||||
am791x->rx_timer_f = am791x->t_cdoff;
|
||||
new_rx_state(am791x, AM791X_STATE_CDOFF);
|
||||
}
|
||||
|
||||
@@ -906,7 +921,8 @@ static void cdoff_cd(am791x_t *am791x)
|
||||
{
|
||||
LOGP(DAM791X, LOGL_DEBUG, "Carrier recovered\n");
|
||||
|
||||
osmo_timer_del(&am791x->rx_timer);
|
||||
/* Flag timer, because it must be deleted in main thread. */
|
||||
am791x->rx_timer_f = -1;
|
||||
new_rx_state(am791x, AM791X_STATE_DATA);
|
||||
}
|
||||
|
||||
@@ -914,7 +930,8 @@ static void go_back_channel_rx(am791x_t *am791x)
|
||||
{
|
||||
LOGP(DAM791X, LOGL_DEBUG, "Enable receiver on back channel\n");
|
||||
|
||||
osmo_timer_schedule(&am791x->rx_timer, FLOAT_TO_TIMEOUT(am791x->t_bcdon));
|
||||
/* Flag timer, because it must be added in main thread. */
|
||||
am791x->rx_timer_f = am791x->t_bcdon;
|
||||
new_rx_state(am791x, AM791X_STATE_BCDON);
|
||||
}
|
||||
|
||||
@@ -936,7 +953,8 @@ static void bcdon_no_cd(am791x_t *am791x)
|
||||
{
|
||||
LOGP(DAM791X, LOGL_DEBUG, "Carrier is gone\n");
|
||||
|
||||
osmo_timer_del(&am791x->rx_timer);
|
||||
/* Flag timer, because it must be deleted in main thread. */
|
||||
am791x->rx_timer_f = -1;
|
||||
new_rx_state(am791x, AM791X_STATE_INIT);
|
||||
}
|
||||
|
||||
@@ -944,7 +962,8 @@ static void rx_bdata_done(am791x_t *am791x)
|
||||
{
|
||||
LOGP(DAM791X, LOGL_DEBUG, "Carrier lost\n");
|
||||
|
||||
osmo_timer_schedule(&am791x->rx_timer, FLOAT_TO_TIMEOUT(am791x->t_bcdoff));
|
||||
/* Flag timer, because it must be added in main thread. */
|
||||
am791x->rx_timer_f = am791x->t_bcdoff;
|
||||
new_rx_state(am791x, AM791X_STATE_BCDOFF);
|
||||
}
|
||||
|
||||
@@ -967,7 +986,8 @@ static void bcdoff_cd(am791x_t *am791x)
|
||||
{
|
||||
LOGP(DAM791X, LOGL_DEBUG, "Carrier recovered\n");
|
||||
|
||||
osmo_timer_del(&am791x->rx_timer);
|
||||
/* Flag timer, because it must be deleted in main thread. */
|
||||
am791x->rx_timer_f = -1;
|
||||
new_rx_state(am791x, AM791X_STATE_BDATA);
|
||||
}
|
||||
|
||||
@@ -994,7 +1014,8 @@ static void handle_rx_state(am791x_t *am791x)
|
||||
break;
|
||||
/* all main channel states ... */
|
||||
case AM791X_STATE_CDON:
|
||||
if (!osmo_timer_pending(&am791x->rx_timer)) {
|
||||
/* If timer is about to be switched off, of if it already has been switched off. */
|
||||
if (am791x->rx_timer_f < 0.0 || (!osmo_timer_pending(&am791x->rx_timer) && am791x->rx_timer_f == 0.0)) {
|
||||
cdon_done(am791x);
|
||||
break;
|
||||
}
|
||||
@@ -1010,7 +1031,8 @@ static void handle_rx_state(am791x_t *am791x)
|
||||
}
|
||||
break;
|
||||
case AM791X_STATE_CDOFF:
|
||||
if (!osmo_timer_pending(&am791x->rx_timer)) {
|
||||
/* If timer is about to be switched off, of if it already has been switched off. */
|
||||
if (am791x->rx_timer_f < 0.0 || (!osmo_timer_pending(&am791x->rx_timer) && am791x->rx_timer_f == 0.0)) {
|
||||
cdoff_done(am791x);
|
||||
break;
|
||||
}
|
||||
@@ -1021,7 +1043,8 @@ static void handle_rx_state(am791x_t *am791x)
|
||||
break;
|
||||
/* all back channel states ... */
|
||||
case AM791X_STATE_BCDON:
|
||||
if (!osmo_timer_pending(&am791x->rx_timer)) {
|
||||
/* If timer is about to be switched off, of if it already has been switched off. */
|
||||
if (am791x->rx_timer_f < 0.0 || (!osmo_timer_pending(&am791x->rx_timer) && am791x->rx_timer_f == 0.0)) {
|
||||
bcdon_done(am791x);
|
||||
break;
|
||||
}
|
||||
@@ -1037,7 +1060,8 @@ static void handle_rx_state(am791x_t *am791x)
|
||||
}
|
||||
break;
|
||||
case AM791X_STATE_BCDOFF:
|
||||
if (!osmo_timer_pending(&am791x->rx_timer)) {
|
||||
/* If timer is about to be switched off, of if it already has been switched off. */
|
||||
if (am791x->rx_timer_f < 0.0 || (!osmo_timer_pending(&am791x->rx_timer) && am791x->rx_timer_f == 0.0)) {
|
||||
bcdoff_done(am791x);
|
||||
break;
|
||||
}
|
||||
@@ -1191,8 +1215,10 @@ void am791x_reset(am791x_t *am791x)
|
||||
{
|
||||
LOGP(DAM791X, LOGL_INFO, "Reset!\n");
|
||||
|
||||
osmo_timer_del(&am791x->tx_timer);
|
||||
osmo_timer_del(&am791x->rx_timer);
|
||||
/* Flag timer, because it must be deleted in main thread. */
|
||||
am791x->tx_timer_f = -1.0;
|
||||
/* Flag timer, because it must be deleted in main thread. */
|
||||
am791x->rx_timer_f = -1.0;
|
||||
|
||||
if (am791x->f0_tx) {
|
||||
fsk_mod_cleanup(&am791x->fsk_tx);
|
||||
@@ -1266,3 +1292,19 @@ void am791x_ring(am791x_t *am791x, int ring)
|
||||
handle_state(am791x);
|
||||
}
|
||||
|
||||
void am791x_add_del_timers(am791x_t *am791x)
|
||||
{
|
||||
/* Timers may only be processed in main thread, because libosmocore has timer lists for individual threads. */
|
||||
if (am791x->tx_timer_f < 0.0)
|
||||
osmo_timer_del(&am791x->tx_timer);
|
||||
if (am791x->tx_timer_f > 0.0)
|
||||
osmo_timer_schedule(&am791x->tx_timer, FLOAT_TO_TIMEOUT(am791x->tx_timer_f));
|
||||
am791x->tx_timer_f = 0.0;
|
||||
|
||||
if (am791x->rx_timer_f < 0.0)
|
||||
osmo_timer_del(&am791x->rx_timer);
|
||||
if (am791x->rx_timer_f > 0.0)
|
||||
osmo_timer_schedule(&am791x->rx_timer, FLOAT_TO_TIMEOUT(am791x->rx_timer_f));
|
||||
am791x->rx_timer_f = 0.0;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ typedef struct am791x {
|
||||
|
||||
/* timers */
|
||||
struct osmo_timer_list tx_timer, rx_timer;
|
||||
double tx_timer_f, rx_timer_f; /* time to stat / flag to stop */
|
||||
double t_rcon;
|
||||
double t_rcoff;
|
||||
double t_brcon;
|
||||
@@ -104,4 +105,5 @@ void am791x_dtr(am791x_t *am791x, int dtr);
|
||||
void am791x_rts(am791x_t *am791x, int rts);
|
||||
void am791x_brts(am791x_t *am791x, int brts);
|
||||
void am791x_ring(am791x_t *am791x, int ring);
|
||||
void am791x_add_del_timers(am791x_t *am791x);
|
||||
|
||||
|
||||
+13
-5
@@ -1093,7 +1093,7 @@ static ssize_t dk_read(void *inst, char *buf, size_t size, int flags)
|
||||
if (vmin && vtime) {
|
||||
/* first: start timer */
|
||||
if (!datenklo->vtimeout)
|
||||
osmo_timer_schedule(&datenklo->vtimer, vtime/10,(vtime % 10) * 100000);
|
||||
datenklo->vtimer_us = vtime * 100000; /* start timer in main loop */
|
||||
/* no data: block (in blocking IO) */
|
||||
if (fill == 0) {
|
||||
/* special value to tell device there is no data right now, we have to block */
|
||||
@@ -1106,7 +1106,7 @@ static ssize_t dk_read(void *inst, char *buf, size_t size, int flags)
|
||||
}
|
||||
/* enough data or timeout or nonblocking IO: stop timer and return what we have */
|
||||
datenklo->vtimeout = 0;
|
||||
osmo_timer_del(&datenklo->vtimer);
|
||||
datenklo->vtimer_us = -1; /* stop timer in main loop */
|
||||
}
|
||||
/* both MIN and TIME are zero */
|
||||
if (!vmin && !vtime) {
|
||||
@@ -1119,7 +1119,7 @@ static ssize_t dk_read(void *inst, char *buf, size_t size, int flags)
|
||||
if (!vmin && vtime) {
|
||||
/* first: start timer */
|
||||
if (!datenklo->vtimeout)
|
||||
osmo_timer_schedule(&datenklo->vtimer, vtime/10,(vtime % 10) * 100000);
|
||||
datenklo->vtimer_us = vtime * 100000; /* start timer in main loop */
|
||||
if (fill == 0) {
|
||||
/* no data and no timeout: block (in blocking IO) */
|
||||
if (!datenklo->vtimeout) {
|
||||
@@ -1132,7 +1132,7 @@ static ssize_t dk_read(void *inst, char *buf, size_t size, int flags)
|
||||
}
|
||||
/* data: stop timer and return what we have */
|
||||
datenklo->vtimeout = 0;
|
||||
osmo_timer_del(&datenklo->vtimer);
|
||||
datenklo->vtimer_us = -1; /* stop timer in main loop */
|
||||
}
|
||||
/* MIN is nonzero, TIME is zero */
|
||||
if (vmin && !vtime) {
|
||||
@@ -1522,7 +1522,15 @@ void datenklo_main(datenklo_t *datenklo, int loopback)
|
||||
if (num_chan > 1)
|
||||
process_auto_rts(datenklo->slave);
|
||||
|
||||
/* process timers */
|
||||
/* Timers may only be processed in main thread, because libosmocore has timer lists for individual threads. */
|
||||
if (datenklo->vtimer_us < 0)
|
||||
osmo_timer_del(&datenklo->vtimer);
|
||||
if (datenklo->vtimer_us > 0)
|
||||
osmo_timer_schedule(&datenklo->vtimer, datenklo->vtimer_us / 1000000,datenklo->vtimer_us % 1000000);
|
||||
datenklo->vtimer_us = 0;
|
||||
|
||||
am791x_add_del_timers(&datenklo->am791x);
|
||||
|
||||
osmo_select_main(1);
|
||||
|
||||
#ifdef HAVE_ALSA
|
||||
|
||||
@@ -53,6 +53,7 @@ typedef struct datenklo {
|
||||
int auto_rts_cd; /* CD was indicated */
|
||||
int output_off; /* output stopped by flow control */
|
||||
struct osmo_timer_list vtimer; /* VTIME timer */
|
||||
int vtimer_us; /* time to stat / flag to stop */
|
||||
int vtimeout; /* when timeout has fired */
|
||||
|
||||
/* data fifos */
|
||||
|
||||
Reference in New Issue
Block a user