/*************************************************************************** * Copyright (c) 2012, Broadcom Corporation * All Rights Reserved * Confidential Property of Broadcom Corporation * * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE * AGREEMENT BETWEEN THE USER AND BROADCOM. YOU HAVE NO RIGHT TO USE OR * EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. * * $brcm_Workfile: $ * $brcm_Revision: $ * $brcm_Date: $ * * Module Description: * * Revision History: * * $brcm_Log: $ * ***************************************************************************/ #include #include #include "bstd.h" #include "bkni.h" #include "bapp_types.h" #include "bos.h" #include "bapp_util.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; extern int pthread_kill(pthread_t thread, int sig); 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 ) { BSTD_UNUSED(params); 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 ) { BSTD_UNUSED(events); BSTD_UNUSED(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) { sleep(sleep_ms/1000); usleep((sleep_ms%1000)*1000); } else { usleep(sleep_ms*1000); } } 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) { BSTD_UNUSED(clock); } unsigned int bos_enter_critical(void) { pthread_mutex_lock((pthread_mutex_t *)&s_mutex); return lflag++; } void bos_exit_critical(unsigned int flags) { BSTD_UNUSED(flags); pthread_mutex_unlock((pthread_mutex_t *)&s_mutex); } #ifndef LINUX /* Jan 6, 1980 => Sunday */ #define START_DAY 0 #define START_YEAR 1980 #else /* Jan 1, 1970 => Thursday */ #define START_DAY 3 #define START_YEAR 1970 #endif /* Days/month for non-leap year */ const unsigned char s_days_per_mon[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, }; #define IS_LEAP_YEAR(y) ( !((y + START_YEAR) % 4) && ( ((y + START_YEAR) % 100) || !((y + START_YEAR) % 400) ) ) void utctime(unsigned int secs,b_tm *p_tm) { unsigned int yday,mon,t_val; unsigned char *p_dpm = (unsigned char*)s_days_per_mon; memset(p_tm,0,sizeof(b_tm)); /* seconds */ p_tm->tm_sec = secs % 60; t_val = secs / 60; /* minutes */ /* minutes */ p_tm->tm_min = t_val % 60; t_val /= 60; /* hours */ /* hours */ p_tm->tm_hour = t_val % 24; t_val /= 24; /* day of week */ p_tm->tm_wday = t_val % 7; p_tm->tm_wday = (t_val - START_DAY) % 7; #ifndef LINUX t_val += 5; #endif /* year */ p_tm->tm_yday = t_val; p_tm->tm_year = 0; /* day of current year */ while ((IS_LEAP_YEAR(p_tm->tm_year) && (p_tm->tm_yday > 365)) || (!IS_LEAP_YEAR(p_tm->tm_year) && (p_tm->tm_yday > 364))) { if (IS_LEAP_YEAR(p_tm->tm_year)) p_tm->tm_yday -= 366; else p_tm->tm_yday -= 365; p_tm->tm_year++; } if (IS_LEAP_YEAR(p_tm->tm_year)) p_dpm += 12; yday = p_tm->tm_yday + 1; mon = 0; while(yday > p_dpm[mon]) { yday -= p_dpm[mon]; mon++; } /* month */ p_tm->tm_mon = mon; /* day of month */ p_tm->tm_mday = yday; } #ifdef CONFIG_GP void GP_putchar(char ch) { putchar(ch); } int GP_getchar(void) { return getchar(); } #endif