mirror of https://github.com/ArduPilot/ardupilot
HAL_SITL: implement barriers using pthread condition variables
this avoid pthread_barrier_*, which is not available on cygwin
This commit is contained in:
parent
c974134ea4
commit
063a33ebce
|
@ -55,7 +55,9 @@ SITLScheduler::SITLScheduler(SITL_State *sitlState) :
|
||||||
stopped_clock_usec(0)
|
stopped_clock_usec(0)
|
||||||
{
|
{
|
||||||
signal(SIGCONT, sigcont_handler);
|
signal(SIGCONT, sigcont_handler);
|
||||||
pthread_barrier_init(&clock_barrier, NULL, 2);
|
pthread_mutex_init(&clock_barrier.m, NULL);
|
||||||
|
pthread_cond_init(&clock_barrier.cv, NULL);
|
||||||
|
clock_barrier.state = CLOCK_WAIT_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SITLScheduler::init(void *unused)
|
void SITLScheduler::init(void *unused)
|
||||||
|
@ -134,6 +136,38 @@ uint32_t SITLScheduler::millis()
|
||||||
|
|
||||||
extern AVR_SITL::SITL_State *g_state;
|
extern AVR_SITL::SITL_State *g_state;
|
||||||
|
|
||||||
|
/*
|
||||||
|
implement a barrier wait for SITL lock-step scheduling. We don't use
|
||||||
|
pthread_barrier_* as it is not available in cygwin
|
||||||
|
*/
|
||||||
|
void SITLScheduler::clock_barrier_wait(void)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&clock_barrier.m);
|
||||||
|
|
||||||
|
while (clock_barrier.state == CLOCK_WAIT_TWO ||
|
||||||
|
clock_barrier.state == CLOCK_WAIT_THREE) {
|
||||||
|
pthread_cond_wait(&clock_barrier.cv, &clock_barrier.m);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clock_barrier.state == CLOCK_WAIT_INIT) {
|
||||||
|
clock_barrier.state = CLOCK_WAIT_ONE;
|
||||||
|
pthread_cond_signal(&clock_barrier.cv);
|
||||||
|
while (clock_barrier.state != CLOCK_WAIT_TWO) {
|
||||||
|
pthread_cond_wait(&clock_barrier.cv, &clock_barrier.m);
|
||||||
|
}
|
||||||
|
clock_barrier.state = CLOCK_WAIT_THREE;
|
||||||
|
pthread_cond_signal(&clock_barrier.cv);
|
||||||
|
} else {
|
||||||
|
clock_barrier.state = CLOCK_WAIT_TWO;
|
||||||
|
pthread_cond_signal(&clock_barrier.cv);
|
||||||
|
while (clock_barrier.state != CLOCK_WAIT_THREE) {
|
||||||
|
pthread_cond_wait(&clock_barrier.cv, &clock_barrier.m);
|
||||||
|
}
|
||||||
|
clock_barrier.state = CLOCK_WAIT_INIT;
|
||||||
|
pthread_cond_signal(&clock_barrier.cv);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&clock_barrier.m);
|
||||||
|
}
|
||||||
|
|
||||||
void SITLScheduler::delay_microseconds(uint16_t usec)
|
void SITLScheduler::delay_microseconds(uint16_t usec)
|
||||||
{
|
{
|
||||||
|
@ -145,7 +179,7 @@ void SITLScheduler::delay_microseconds(uint16_t usec)
|
||||||
we are using a synthetic clock. We want to wait until
|
we are using a synthetic clock. We want to wait until
|
||||||
the stop_clock() call advances the clock
|
the stop_clock() call advances the clock
|
||||||
*/
|
*/
|
||||||
pthread_barrier_wait(&clock_barrier);
|
clock_barrier_wait();
|
||||||
} else {
|
} else {
|
||||||
usleep(usec - dtime);
|
usleep(usec - dtime);
|
||||||
}
|
}
|
||||||
|
@ -332,13 +366,13 @@ void SITLScheduler::stop_clock(uint64_t time_usec)
|
||||||
wait until the main thread is waiting for us. This ensures
|
wait until the main thread is waiting for us. This ensures
|
||||||
that any processing is complete before we advance the clock
|
that any processing is complete before we advance the clock
|
||||||
*/
|
*/
|
||||||
pthread_barrier_wait(&clock_barrier);
|
clock_barrier_wait();
|
||||||
}
|
}
|
||||||
stopped_clock_usec = time_usec;
|
stopped_clock_usec = time_usec;
|
||||||
/*
|
/*
|
||||||
wait again to ensure the main thread can't get behind the FDM
|
wait again to ensure the main thread can't get behind the FDM
|
||||||
*/
|
*/
|
||||||
pthread_barrier_wait(&clock_barrier);
|
clock_barrier_wait();
|
||||||
_run_io_procs(false);
|
_run_io_procs(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,10 +74,16 @@ private:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void stop_clock(uint64_t time_usec);
|
void stop_clock(uint64_t time_usec);
|
||||||
|
void clock_barrier_wait();
|
||||||
|
|
||||||
bool _initialized;
|
bool _initialized;
|
||||||
volatile uint64_t stopped_clock_usec;
|
volatile uint64_t stopped_clock_usec;
|
||||||
pthread_barrier_t clock_barrier;
|
enum clock_wait { CLOCK_WAIT_INIT, CLOCK_WAIT_ONE, CLOCK_WAIT_TWO, CLOCK_WAIT_THREE };
|
||||||
|
struct {
|
||||||
|
enum clock_wait state;
|
||||||
|
pthread_mutex_t m;
|
||||||
|
pthread_cond_t cv;
|
||||||
|
} clock_barrier;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
#endif // __AP_HAL_SITL_SCHEDULER_H__
|
#endif // __AP_HAL_SITL_SCHEDULER_H__
|
||||||
|
|
Loading…
Reference in New Issue