X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=callout.c;fp=callout.c;h=0000000000000000000000000000000000000000;hb=8a9ba904e4215b92930a6d71c06c97514bcc6688;hp=d87d9f7c9fa91856f6354e2dac6116b149d639ac;hpb=013bac441997a3a008507835aa4c745458422786;p=protos%2Fxbee-avr.git diff --git a/callout.c b/callout.c deleted file mode 100644 index d87d9f7..0000000 --- a/callout.c +++ /dev/null @@ -1,329 +0,0 @@ -/*- - * Copyright (c) <2010>, Intel Corporation - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * - Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "callout.h" - -#ifdef CALLOUT_STATS -#define __TIMER_STAT_ADD(cm, field, x) cm->stats.field += x -#else -#define __TIMER_STAT_ADD(cm, field, x) do { } while(0) -#endif - -#ifdef CALLOUT_DEBUG -#define callout_dprintf_P(fmt, ...) printf_P(PSTR("%s(): " fmt), __FUNCTION__, \ - __VA_ARGS__) -#else -#define callout_dprintf_P(...) do { } while (0) -#endif - -/* Initialize a callout manager */ -int -callout_manager_init(struct callout_manager *cm, get_time_t *get_time) -{ - if (get_time == NULL) - return -1; - memset(cm, 0, sizeof(*cm)); - cm->get_time = get_time; - TAILQ_INIT(&cm->pending_list); - return 0; -} - -/* Initialize the timer handle tim for use */ -void -callout_init(struct callout *tim) -{ - memset(tim, 0, sizeof(*tim)); -} - -/* - * add in list (timer must not already be in a list) - */ -static void -callout_add(struct callout_manager *cm, struct callout *tim) -{ - struct callout *t; - - callout_dprintf_P(PSTR("cm=%p tim=%p\r\n"), cm, tim); - - /* list is empty */ - if (TAILQ_EMPTY(&cm->pending_list)) { - TAILQ_INSERT_HEAD(&cm->pending_list, tim, next); - return; - } - - /* 'tim' expires before first entry */ - t = TAILQ_FIRST(&cm->pending_list); - if ((int16_t)(tim->expire - t->expire) < 0) { - TAILQ_INSERT_HEAD(&cm->pending_list, tim, next); - return; - } - - /* find an element that will expire after 'tim' */ - TAILQ_FOREACH(t, &cm->pending_list, next) { - if ((int16_t)(tim->expire - t->expire) < 0) { - TAILQ_INSERT_BEFORE(t, tim, next); - return; - } - } - - /* not found, insert at the end of the list */ - TAILQ_INSERT_TAIL(&cm->pending_list, tim, next); -} - -/* - * del from list (timer must be in a list) - */ -static void -callout_del(struct callout_manager *cm, struct callout *tim) -{ - callout_dprintf_P(PSTR("cm=%p tim=%p\r\n"), cm, tim); - TAILQ_REMOVE(&cm->pending_list, tim, next); -} - -/* Reset and start the timer associated with the timer handle tim */ -static int -__callout_reset(struct callout_manager *cm, struct callout *tim, uint16_t expire, - uint16_t period, callout_cb_t fct, void *arg) -{ - callout_dprintf_P(PSTR("cm=%p tim=%p expire=%d period=%d\r\n"), - cm, tim, expire, period); - - __TIMER_STAT_ADD(cm, reset, 1); - cm->updated = 1; - - /* remove it from list */ - if (tim->scheduled == 1 && tim->running == 0) { - callout_del(cm, tim); - __TIMER_STAT_ADD(cm, pending, -1); - } - - tim->period = period; - tim->expire = expire; - tim->f = fct; - tim->arg = arg; - tim->scheduled = 1; - tim->running = 0; - - __TIMER_STAT_ADD(cm, pending, 1); - callout_add(cm, tim); - - return 0; -} - -/* Reset and start the timer associated with the timer handle tim */ -int -callout_reset(struct callout_manager *cm, struct callout *tim, uint16_t ticks, - enum callout_type type, callout_cb_t fct, void *arg) -{ - uint16_t cur_time = cm->get_time(); - return __callout_reset(cm, tim, ticks + cur_time, - type == PERIODICAL ? ticks : 0, fct, arg); -} - -/* Stop the timer associated with the timer handle tim */ -void -callout_stop(struct callout_manager *cm, struct callout *tim) -{ - callout_dprintf_P(PSTR("cm=%p tim=%p\r\n"), cm, tim); - - __TIMER_STAT_ADD(cm, stop, 1); - cm->updated = 1; - - /* remove it from list */ - if (tim->scheduled == 1 && tim->running == 0) { - callout_del(cm, tim); - __TIMER_STAT_ADD(cm, pending, -1); - } -} - -/* Test the PENDING status of the timer handle tim */ -int -callout_pending(struct callout *tim) -{ - return tim->scheduled == 1; -} - -/* must be called periodically, run all timer that expired */ -void callout_manage(struct callout_manager *cm) -{ - struct callout_list expired_list; - struct callout *tim; - uint16_t cur_time = cm->get_time(); - - callout_dprintf_P(PSTR("cm=%p\r\n"), cm); - - TAILQ_INIT(&expired_list); - __TIMER_STAT_ADD(cm, manage, 1); - - /* move all expired timers in a local list */ - while (!TAILQ_EMPTY(&cm->pending_list)) { - tim = TAILQ_FIRST(&cm->pending_list); - - if ((int16_t)(cur_time - tim->expire) < 0) - break; - - TAILQ_REMOVE(&cm->pending_list, tim, next); - TAILQ_INSERT_TAIL(&expired_list, tim, next); - } - - /* for each timer of 'expired' list, execute callback */ - while (!TAILQ_EMPTY(&expired_list)) { - tim = TAILQ_FIRST(&expired_list); - TAILQ_REMOVE(&expired_list, tim, next); - - cm->updated = 0; - - /* execute callback function with list unlocked */ - __TIMER_STAT_ADD(cm, pending, -1); - __TIMER_STAT_ADD(cm, running, 1); - tim->running = 1; - tim->f(cm, tim, tim->arg); - __TIMER_STAT_ADD(cm, running, -1); - - /* the timer was stopped or reloaded by the callback - * function, we have nothing to do here */ - if (cm->updated == 1) - continue; - - tim->running = 0; - tim->scheduled = 0; - - /* if timer type is periodical, reschedule */ - if (tim->period != 0) { - __callout_reset(cm, tim, cur_time + tim->period, - tim->period, tim->f, tim->arg); - } - } -} - -/* dump statistics about timers */ -void callout_dump_stats(struct callout_manager *cm) -{ -#ifdef CALLOUT_STATS - printf_P(PSTR("Timer statistics:\r\n")); - printf_P(PSTR(" reset = %d\r\n"), cm->stats.reset); - printf_P(PSTR(" stop = %d\r\n"), cm->stats.stop); - printf_P(PSTR(" manage = %d\r\n"), cm->stats.manage); - printf_P(PSTR(" pending = %d\r\n"), cm->stats.pending); - printf_P(PSTR(" running = %d\r\n"), cm->stats.running); -#else - printf_P(PSTR("No timer statistics, CALLOUT_STATS is disabled\r\n")); -#endif -} - -#if 0 - -/******************************/ - -#include -#include - -static uint16_t get_time(void) -{ - struct timeval tv; - - gettimeofday(&tv, NULL); - return tv.tv_sec; -} - -static void cb1(struct callout_manager *cm, struct callout *tim, void *arg); -static void cb2(struct callout_manager *cm, struct callout *tim, void *arg); -static void cb3(struct callout_manager *cm, struct callout *tim, void *arg); - -static void cb1(struct callout_manager *cm, struct callout *tim, void *arg) -{ - static int cnt; - arg = arg; /* silent compiler */ - - printf_P(PSTR("cb1\r\n")); - callout_dump_stats(cm); - if (++cnt >= 4) - callout_stop(cm, tim); -} - -static void cb2(struct callout_manager *cm, struct callout *tim, void *arg) -{ - static int cnt; - struct callout *t3 = arg; - - printf_P(PSTR("cb2\r\n")); - if (++cnt < 3) - callout_reset(cm, tim, 5, SINGLE, cb2, arg); - else - callout_reset(cm, t3, 1, SINGLE, cb3, NULL); -} - -static void cb3(struct callout_manager *cm, struct callout *tim, void *arg) -{ - cm = cm; /* silent compiler */ - tim = tim; /* silent compiler */ - arg = arg; /* silent compiler */ - - printf_P(PSTR("cb3\r\n")); -} - -int main(void) -{ - struct callout_manager cm; - struct callout t1, t2, t3; - int i; - - if (callout_manager_init(&cm, get_time) < 0) - return -1; - - callout_init(&t1); - callout_init(&t2); - callout_init(&t3); - - callout_reset(&cm, &t1, 3, PERIODICAL, cb1, NULL); - callout_reset(&cm, &t2, 5, SINGLE, cb2, &t3); - - for (i = 0; i < 18; i++) { - callout_manage(&cm); - sleep(1); - } - - callout_dump_stats(&cm); - return 0; -} - -#endif