lwip-contrib-mac/ports/unix/proj/minimal/timer.c

164 lines
3.6 KiB
C

/*
* Copyright (c) 2006 Christiaan Simons.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. 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.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
* This file is part of and a contribution to the lwIP TCP/IP stack.
*
* Author: Christiaan Simons <christiaan.simons@axon.tv>
*/
/**
* @file
* Simple pre-allocated interval (reload) timers.
* @see timer.h
*/
#include <stddef.h>
#include <signal.h>
#include <sys/time.h>
#include "timer.h"
#include "lwip/snmp.h"
static struct itimerval tmr;
struct itmr
{
volatile unsigned int interval;
volatile unsigned int cnt;
volatile unsigned char event;
};
static struct itmr timers[TIMER_NUM];
void sigalarm_handler(int sig);
/**
* Initializes interval timers.
*/
void
timer_init(void)
{
unsigned char i;
struct itmr *tp;
tp = &timers[TIMER_NUM-1];
for(i = TIMER_NUM; i > 0; i--)
{
tp->event = 0;
tp->interval = 0;
tp->cnt = 0;
tp--;
}
signal(SIGALRM,sigalarm_handler);
/* timer reload is in 10msec steps */
tmr.it_interval.tv_sec = 0;
tmr.it_interval.tv_usec = 10000;
/* set to half period (enables timer) */
tmr.it_value.tv_sec = 0;
tmr.it_value.tv_usec = 5000;
setitimer(ITIMER_REAL,&tmr,NULL);
}
/**
* Configures timer.
*
* @param tmr the timer number from timer.h
* @param interval when > 0 enables this timer, 0 disables.
*/
void
timer_set_interval(unsigned char tmr_num, unsigned int interval)
{
if (tmr_num < TIMER_NUM)
{
timers[tmr_num].interval = interval;
}
}
/**
* Returns timer event and restarts timer.
*/
unsigned char
timer_testclr_evt(unsigned char tmr_num)
{
if (tmr_num < TIMER_NUM)
{
unsigned char evt;
struct itmr *tp;
tp = &timers[tmr_num];
evt = tp->event;
if (tp->event != 0)
{
tp->event = 0;
tp->cnt = tp->interval;
}
return evt;
}
else
{
return 0;
}
}
/**
* interrupting (!) sigalarm handler
*/
void
sigalarm_handler(int sig)
{
unsigned char i;
struct itmr *tp;
LWIP_UNUSED_ARG(sig);
snmp_inc_sysuptime();
tp = &timers[TIMER_NUM-1];
for(i = TIMER_NUM; i > 0; i--)
{
if (tp->interval != 0)
{
/* timer is running */
if (tp->cnt == 0)
{
/* timer expired */
tp->event |= 1;
}
else
{
/* timer ticking */
tp->cnt--;
}
}
tp--;
}
}