static void restartInterval( uint8_t new_tou ) { int32_t tou_interval = 0; int32_t rand_val = 0; ker_timer_stop( KER_DFT_LOADER_PID, TOU_TID ); ker_timer_stop( KER_DFT_LOADER_PID, TRAN_TID ); ker_timer_stop( KER_DFT_LOADER_PID, DATA_TID ); if ( new_tou < TOU_MAX ) { st.tou = new_tou; } else { st.tou = TOU_MAX; } st.tran_count = 0; st.data_count = 0; tou_interval = TOU_INTERVAL * (1L << st.tou); ker_timer_start( KER_DFT_LOADER_PID, TOU_TID, tou_interval ); if ( st.net_state & SEND_DATA ) { //! pick random timeout between tou_interval / 2 and tou_interval rand_val = ker_rand() % (tou_interval / 2); rand_val += (tou_interval / 2); ker_timer_start( KER_DFT_LOADER_PID, DATA_TID, rand_val ); } else { //! pick random timeout between tou_interval / 2 and tou_interval rand_val = ker_rand() % (tou_interval / 2); rand_val += (tou_interval / 2); ker_timer_start( KER_DFT_LOADER_PID, TRAN_TID, rand_val ); } }
int8_t fetcher_request(sos_pid_t req_id, sos_shm_t key, uint16_t size, uint16_t src) { uint8_t bitmap_size; //! size of the bitmap in bytes uint16_t num_fragments; uint8_t i; fetcher_state_t *f; fetcher_cam_t *cam; cam = (fetcher_cam_t *) ker_shm_get( KER_FETCHER_PID, key); if( cam == NULL ) return -EINVAL; //if(fst != NULL) return -EBUSY; DEBUG_PID(KER_FETCHER_PID, "fetcher_request, req_id = %d, size = %d, src = %d\n", req_id, size, src); num_fragments = ((size + (FETCHER_FRAGMENT_SIZE - 1))/ FETCHER_FRAGMENT_SIZE); bitmap_size = (uint8_t)((num_fragments + 7)/ 8); //DEBUG("size = %d\n", sizeof(fetcher_state_t) + bitmap_size); f = ker_malloc(sizeof(fetcher_state_t) + bitmap_size, KER_FETCHER_PID); if(f == NULL) { return -ENOMEM; } //DEBUG("num_fragments = %d, bitmap_zie = %d\n", num_fragments, bitmap_size); f->requester = req_id; f->map.key = key; f->map.bitmap_size = bitmap_size; f->src_addr = src; f->num_funcs = 0; f->next = NULL; f->cm = cam->cm; for(i = 0; i < bitmap_size; i++) { f->map.bitmap[i] = 0xff; } if((num_fragments) % 8) { f->map.bitmap[bitmap_size - 1] = (1 << (num_fragments % 8)) - 1; } print_bitmap(&f->map); //! backoff first!!! f->retx = 0; if(fst != NULL) { fetcher_state_t *tmp = fst; cam->status = FETCHING_QUEUED; while(tmp->next != NULL) { tmp = tmp->next; } tmp->next = f; return SOS_OK; } cam->status = FETCHING_STARTED; fst = f; //! setup timer ker_timer_start(KER_FETCHER_PID, FETCHER_REQUEST_TID, FETCHER_REQUEST_BACKOFF_SLOT * ((ker_rand() % FETCHER_REQUEST_MAX_SLOT) + 1)); //DEBUG("request ret = %d\n", ret); return SOS_OK; }
/************************************************************************* * Implement exponential backoff mechanism * *************************************************************************/ static int16_t MacBackoff_congestionBackoff(int8_t retries) { int8_t i; int16_t masktime = 1; for(i=0; i<retries; i++) masktime *= 2; //masktime = 2^retries masktime --; //get the mask if( masktime > 1023 ) masktime = 1023; //max backoff 1023 // return ((ker_rand() & 0xF) + TIMER_MIN_INTERVAL); return ((ker_rand() & masktime) + TIMER_MIN_INTERVAL); }
static void start_new_fetch(void) { fst = fst->next; if (fst) { fetcher_cam_t *cam; cam = ker_shm_get( KER_FETCHER_PID, fst->map.key ); cam->status = FETCHING_STARTED; ker_timer_start(KER_FETCHER_PID, FETCHER_REQUEST_TID, FETCHER_REQUEST_BACKOFF_SLOT * ((ker_rand() % FETCHER_REQUEST_MAX_SLOT) + 1)); } }
void fetcher_restart(fetcher_state_t *s, uint16_t src) { fetcher_cam_t *cam; cam = ker_shm_get( KER_FETCHER_PID, s->map.key ); s->src_addr = src; s->retx = 0; s->next = NULL; if(fst != NULL) { fetcher_state_t *tmp = fst; cam->status = FETCHING_QUEUED; while(tmp->next != NULL) { tmp = tmp->next; } tmp->next = s; return; } fst = s; cam->status = FETCHING_STARTED; ker_timer_start(KER_FETCHER_PID, FETCHER_REQUEST_TID, FETCHER_REQUEST_BACKOFF_SLOT * ((ker_rand() % FETCHER_REQUEST_MAX_SLOT) + 1)); }
static inline void restart_request_timer() { ker_timer_restart(KER_FETCHER_PID, FETCHER_REQUEST_TID, FETCHER_REQUEST_WATCHDOG + (FETCHER_REQUEST_BACKOFF_SLOT * ((ker_rand() % FETCHER_REQUEST_MAX_SLOT) + 1))); }