#include #include #include #include "bstd.h" #include "bos.h" #include "genericlist.h" typedef struct bos_event_t { LINKS_T links; b_event_t *event; }bos_event_t; typedef struct bos_queue_t { LIST_T list; pthread_mutex_t mutex; }bos_queue_t; int g_ticks_per_ms = 1; static pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER; static int lflag = 0; void bos_init(void) { } void bos_start(void) { } bresult bos_start_task( b_task_t *handle, const b_task_params *params, b_task_func func, void *data ) { if (pthread_create((pthread_t*)handle, NULL, (void *(*)(void*))func, data) == 0) { return b_ok; } return berr_out_of_memory; } void bos_stop_task(b_task_t handle) { #ifndef __MINGW32__ pthread_kill((pthread_t*)handle,-9); #endif } bresult bos_create_queue( b_queue_t *handle, b_event_t *events, int num_events ) { bos_queue_t *p_bq = (bos_queue_t*)malloc(sizeof(bos_queue_t)); if (!p_bq) return berr_out_of_memory; if (pthread_mutex_init(&p_bq->mutex,NULL) != 0) { free(p_bq); return berr_out_of_memory; } initl(&p_bq->list); *handle = (b_queue_t)p_bq; return b_ok; } void bos_delete_queue( b_queue_t *handle ) { bos_queue_t *p_bq = (bos_queue_t*)handle; bos_event_t *p_evt; for (p_evt = (bos_event_t*)remlh(&p_bq->list); p_evt != NULL; p_evt = (bos_event_t*)remlh(&p_bq->list)) { free(p_evt); } free(p_bq); } bresult bos_post_event( b_queue_t handle, b_event_t *event ) { bos_queue_t *p_bq = (bos_queue_t*)handle; bos_event_t *p_evt = NULL; p_evt = (bos_event_t*)malloc(sizeof(bos_event_t)); if (!p_bq) return berr_out_of_memory; if (pthread_mutex_lock((pthread_mutex_t *)&p_bq->mutex) != 0) goto error; p_evt->event = event; inslt(&p_bq->list,p_evt); pthread_mutex_unlock((pthread_mutex_t *)&p_bq->mutex); return b_ok; error: if (p_evt) free(p_evt); return berr_timeout; } b_event_t *bos_pend_event( b_queue_t handle, int timeout_ms ) { bos_queue_t *p_bq = (bos_queue_t*)handle; bos_event_t *p_evt = NULL; b_event_t *return_event = NULL; unsigned int timout_ticks = bos_getticks() + timeout_ms * g_ticks_per_ms;; if (pthread_mutex_lock((pthread_mutex_t *)&p_bq->mutex) != 0) goto exit; while (LEMPTY(&p_bq->list)) { pthread_mutex_unlock((pthread_mutex_t *)&p_bq->mutex); bos_sleep(1); if (timeout_ms >= 0) { if (timout_ticks < bos_getticks()) goto exit; } if (pthread_mutex_lock((pthread_mutex_t *)&p_bq->mutex) != 0) goto exit; } p_evt = (bos_event_t*)LHEAD(&p_bq->list); reml(&p_bq->list,p_evt); return_event = p_evt->event; free(p_evt); pthread_mutex_unlock((pthread_mutex_t *)&p_bq->mutex); exit: return return_event; } bresult bos_create_mutex( b_mutex_t *handle ) { handle->queue = (b_queue_t)malloc(sizeof(pthread_mutex_t)); if (pthread_mutex_init((pthread_mutex_t *)(handle->queue),NULL) == 0) return b_ok; return berr_out_of_memory; } void bos_delete_mutex( b_mutex_t *handle) { pthread_mutex_destroy((pthread_mutex_t *)(handle->queue)); free((void*)(handle->queue)); } bresult bos_acquire_mutex( b_mutex_t *handle, int timeout_ms ) { if (timeout_ms < 0) { if (pthread_mutex_lock((pthread_mutex_t *)(handle->queue)) != 0) return berr_timeout; } else { unsigned int timout_ticks = bos_getticks() + timeout_ms * g_ticks_per_ms; while (pthread_mutex_trylock((pthread_mutex_t *)(handle->queue)) != 0) { bos_sleep(1); if (timout_ticks < bos_getticks()) return berr_timeout; } } return b_ok; } bresult bos_release_mutex( b_mutex_t *handle ) { pthread_mutex_unlock((pthread_mutex_t *)(handle->queue)); return b_ok; } void bos_sleep( unsigned int sleep_ms ) { if (sleep_ms >=1000) { g_usleep(sleep_ms * 1000); } else { usleep(sleep_ms*1000); } } static int timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y) { /* Perform the carry for the later subtraction by updating y. */ if (x->tv_usec < y->tv_usec) { int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1; y->tv_usec -= 1000000 * nsec; y->tv_sec += nsec; } if (x->tv_usec - y->tv_usec > 1000000) { int nsec = (x->tv_usec - y->tv_usec) / 1000000; y->tv_usec += 1000000 * nsec; y->tv_sec -= nsec; } /* Compute the time remaining to wait. tv_usec is certainly positive. */ result->tv_sec = x->tv_sec - y->tv_sec; result->tv_usec = x->tv_usec - y->tv_usec; /* Return 1 if result is negative. */ return x->tv_sec < y->tv_sec; } static struct timeval s_start_time = {0,0}; unsigned int bos_getticks( void ) { struct timeval tv; struct timeval cur_tv; if ((s_start_time.tv_sec == 0) && (s_start_time.tv_usec == 0)) { gettimeofday(&s_start_time,NULL); } gettimeofday(&cur_tv,NULL); timeval_subtract(&tv,&cur_tv,&s_start_time); return (tv.tv_sec * 1000 + tv.tv_usec/1000); } void bos_getclock(b_clock *clock) { } unsigned int bos_enter_critical(void) { pthread_mutex_lock((pthread_mutex_t *)&s_mutex); return lflag++; } void bos_exit_critical(unsigned int flags) { pthread_mutex_unlock((pthread_mutex_t *)&s_mutex); }