Vendor patch that adds a microsecond timer function.
This commit is contained in:
parent
5ae1be8157
commit
ca77a23f23
@ -101,16 +101,16 @@
|
||||
# endif
|
||||
|
||||
|
||||
typedef signed long long tval_t;
|
||||
typedef int64_t tval_t;
|
||||
|
||||
static inline tval_t GETMSECS(void);
|
||||
static inline tval_t GETUSECS(void);
|
||||
|
||||
static inline tval_t
|
||||
GETMSECS(void) {
|
||||
GETUSECS(void) {
|
||||
struct timeval tval;
|
||||
|
||||
(void)gettimeofday(&tval, NULL);
|
||||
return (tval_t)tval.tv_sec*1000+tval.tv_usec/1000;
|
||||
return (tval_t)tval.tv_sec * 1000000 + tval.tv_usec;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -170,11 +170,11 @@ typedef struct {
|
||||
* Now for timers
|
||||
*/
|
||||
typedef struct {
|
||||
u_int msecs; /* millisecond value of the timer */
|
||||
uint64_t usecs; /* microsecond value of the timer */
|
||||
int repeat; /* one shot or repeat? */
|
||||
void *arg; /* client arg */
|
||||
timer_f func; /* handler, 0 means disfunct */
|
||||
tval_t when; /* next time to trigger in msecs! */
|
||||
tval_t when; /* next time to trigger in usecs! */
|
||||
} PollTim_t;
|
||||
|
||||
/* how many records should our table grow at once? */
|
||||
@ -296,8 +296,8 @@ poll_register(int fd, poll_f func, void *arg, int mask)
|
||||
poll_unblocksig();
|
||||
|
||||
if(rpoll_trace)
|
||||
fprintf(stderr, "poll_register(%d, %#lx, %#lx, %#x)->%d",
|
||||
fd, (u_long)func, (u_long)arg, mask, p - regs);
|
||||
fprintf(stderr, "poll_register(%d, %p, %p, %#x)->%tu",
|
||||
fd, (void *)func, (void *)arg, mask, p - regs);
|
||||
return p - regs;
|
||||
}
|
||||
|
||||
@ -372,6 +372,13 @@ poll_build(void)
|
||||
|
||||
int
|
||||
poll_start_timer(u_int msecs, int repeat, timer_f func, void *arg)
|
||||
{
|
||||
return (poll_start_utimer((unsigned long long)msecs * 1000,
|
||||
repeat, func, arg));
|
||||
}
|
||||
|
||||
int
|
||||
poll_start_utimer(unsigned long long usecs, int repeat, timer_f func, void *arg)
|
||||
{
|
||||
PollTim_t *p;
|
||||
|
||||
@ -392,19 +399,19 @@ poll_start_timer(u_int msecs, int repeat, timer_f func, void *arg)
|
||||
}
|
||||
|
||||
/* create entry */
|
||||
p->msecs = msecs;
|
||||
p->usecs = usecs;
|
||||
p->repeat = repeat;
|
||||
p->arg = arg;
|
||||
p->func = func;
|
||||
p->when = GETMSECS() + msecs;
|
||||
p->when = GETUSECS() + usecs;
|
||||
|
||||
tims_used++;
|
||||
|
||||
resort = 1;
|
||||
|
||||
if(rpoll_trace)
|
||||
fprintf(stderr, "poll_start_timer(%u, %d, %#lx, %#lx)->%u",
|
||||
msecs, repeat, (u_long)func, (u_long)arg, p - tims);
|
||||
fprintf(stderr, "poll_start_utimer(%llu, %d, %p, %p)->%tu",
|
||||
usecs, repeat, (void *)func, (void *)arg, p - tims);
|
||||
|
||||
return p - tims;
|
||||
}
|
||||
@ -497,7 +504,7 @@ poll_dispatch(int wait)
|
||||
u_int i, idx;
|
||||
int ret;
|
||||
tval_t now;
|
||||
int tout;
|
||||
tval_t tout;
|
||||
static u_int last_index;
|
||||
|
||||
# ifdef USE_SELECT
|
||||
@ -519,12 +526,13 @@ poll_dispatch(int wait)
|
||||
/* in wait mode - compute the timeout */
|
||||
if(wait) {
|
||||
if(tfd_used) {
|
||||
now = GETMSECS();
|
||||
now = GETUSECS();
|
||||
# ifdef DEBUG
|
||||
{
|
||||
fprintf(stderr, "now=%"QUADFMT"u", now);
|
||||
fprintf(stderr, "now=%llu", now);
|
||||
for(i = 0; i < tims_used; i++)
|
||||
fprintf(stderr, "timers[%2d] = %"QUADFMT"d", i, tfd[i]->when - now);
|
||||
fprintf(stderr, "timers[%2d] = %lld",
|
||||
i, tfd[i]->when - now);
|
||||
}
|
||||
# endif
|
||||
if((tout = tims[tfd[0]].when - now) < 0)
|
||||
@ -539,7 +547,7 @@ poll_dispatch(int wait)
|
||||
# endif
|
||||
|
||||
# ifdef USE_POLL
|
||||
ret = poll(pfd, regs_used, tout);
|
||||
ret = poll(pfd, regs_used, tout == INFTIM ? INFTIM : (tout / 1000));
|
||||
# endif
|
||||
|
||||
# ifdef USE_SELECT
|
||||
@ -547,13 +555,13 @@ poll_dispatch(int wait)
|
||||
nwset = wset;
|
||||
nxset = xset;
|
||||
if(tout != INFTIM) {
|
||||
tv.tv_sec = tout / 1000;
|
||||
tv.tv_usec = (tout % 1000) * 1000;
|
||||
tv.tv_sec = tout / 1000000;
|
||||
tv.tv_usec = tout % 1000000;
|
||||
}
|
||||
ret = select(maxfd+1,
|
||||
SELECT_CAST(&nrset),
|
||||
SELECT_CAST(&nwset),
|
||||
SELECT_CAST(&nxset), (tout==INFTIM) ? 0 : &tv);
|
||||
SELECT_CAST(&nxset), (tout==INFTIM) ? NULL : &tv);
|
||||
# endif
|
||||
|
||||
if(ret == -1) {
|
||||
@ -574,20 +582,26 @@ poll_dispatch(int wait)
|
||||
|
||||
# ifdef USE_POLL
|
||||
if(regs[idx].pfd) {
|
||||
if(regs[idx].pfd->revents & poll_in)
|
||||
if ((regs[idx].mask & POLL_IN) &&
|
||||
(regs[idx].pfd->revents & poll_in))
|
||||
mask |= POLL_IN;
|
||||
if(regs[idx].pfd->revents & poll_out)
|
||||
if ((regs[idx].mask & POLL_OUT) &&
|
||||
(regs[idx].pfd->revents & poll_out))
|
||||
mask |= POLL_OUT;
|
||||
if(regs[idx].pfd->revents & poll_except)
|
||||
if((regs[idx].mask & POLL_EXCEPT) &&
|
||||
(regs[idx].pfd->revents & poll_except))
|
||||
mask |= POLL_EXCEPT;
|
||||
}
|
||||
# endif
|
||||
# ifdef USE_SELECT
|
||||
if(FD_ISSET(regs[idx].fd, &nrset))
|
||||
if ((regs[idx].mask & POLL_IN) &&
|
||||
FD_ISSET(regs[idx].fd, &nrset))
|
||||
mask |= POLL_IN;
|
||||
if(FD_ISSET(regs[idx].fd, &nwset))
|
||||
if ((regs[idx].mask & POLL_OUT) &&
|
||||
FD_ISSET(regs[idx].fd, &nwset))
|
||||
mask |= POLL_OUT;
|
||||
if(FD_ISSET(regs[idx].fd, &nxset))
|
||||
if ((regs[idx].mask & POLL_EXCEPT) &&
|
||||
FD_ISSET(regs[idx].fd, &nxset))
|
||||
mask |= POLL_EXCEPT;
|
||||
# endif
|
||||
assert(idx < regs_alloc);
|
||||
@ -595,8 +609,8 @@ poll_dispatch(int wait)
|
||||
if(mask) {
|
||||
if(rpoll_trace)
|
||||
fprintf(stderr, "poll_dispatch() -- "
|
||||
"file %d/%d",
|
||||
regs[idx].fd, idx);
|
||||
"file %d/%d %x",
|
||||
regs[idx].fd, idx, mask);
|
||||
(*regs[idx].func)(regs[idx].fd, mask, regs[idx].arg);
|
||||
}
|
||||
}
|
||||
@ -607,7 +621,7 @@ poll_dispatch(int wait)
|
||||
|
||||
/* dispatch timeouts */
|
||||
if(tfd_used) {
|
||||
now = GETMSECS();
|
||||
now = GETUSECS();
|
||||
for(i = 0; i < tfd_used; i++) {
|
||||
if(tfd[i] < 0)
|
||||
continue;
|
||||
@ -619,7 +633,7 @@ poll_dispatch(int wait)
|
||||
if(tfd[i] < 0)
|
||||
continue;
|
||||
if(tims[tfd[i]].repeat)
|
||||
tims[tfd[i]].when = now + tims[tfd[i]].msecs;
|
||||
tims[tfd[i]].when = now + tims[tfd[i]].usecs;
|
||||
else {
|
||||
tims[tfd[i]].func = NULL;
|
||||
tims_used--;
|
||||
@ -644,8 +658,8 @@ elaps(void)
|
||||
{
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
return (double)(10 * now.tv_sec + now.tv_usec / 100000 - 10 * start.tv_sec - start.tv_usec / 100000)
|
||||
/ 10;
|
||||
return (double)(10 * now.tv_sec + now.tv_usec / 100000 -
|
||||
10 * start.tv_sec - start.tv_usec / 100000) / 10;
|
||||
}
|
||||
|
||||
void
|
||||
@ -675,6 +689,14 @@ tfunc1(int tid, void *arg)
|
||||
{
|
||||
printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg);
|
||||
}
|
||||
void
|
||||
tfunc2(int tid, void *arg)
|
||||
{
|
||||
static u_int count = 0;
|
||||
|
||||
if (++count % 10000 == 0)
|
||||
printf("%4.1f -- %d\n", elaps(), tid);
|
||||
}
|
||||
|
||||
void first(int tid, void *arg);
|
||||
void second(int tid, void *arg);
|
||||
@ -683,7 +705,7 @@ void
|
||||
second(int tid, void *arg)
|
||||
{
|
||||
printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg);
|
||||
poll_start_timer(5500, 0, first, "first");
|
||||
poll_start_utimer(5500000, 0, first, "first");
|
||||
poll_stop_timer(t1);
|
||||
t0 = poll_start_timer(1000, 1, tfunc0, "1 second");
|
||||
}
|
||||
@ -699,12 +721,16 @@ first(int tid, void *arg)
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
argc = argc;
|
||||
argv = argv;
|
||||
gettimeofday(&start, NULL);
|
||||
poll_register(0, infunc, NULL, POLL_IN);
|
||||
t0 = poll_start_timer(1000, 1, tfunc0, "1 second");
|
||||
poll_start_timer(2500, 0, first, "first");
|
||||
|
||||
if (argc < 2) {
|
||||
t0 = poll_start_timer(1000, 1, tfunc0, "1 second");
|
||||
poll_start_timer(2500, 0, first, "first");
|
||||
} else {
|
||||
t0 = poll_start_utimer(300, 1, tfunc2, NULL);
|
||||
}
|
||||
|
||||
while(1)
|
||||
poll_dispatch(1);
|
||||
|
@ -43,6 +43,8 @@ int poll_register(int fd, poll_f func, void *arg, int mask);
|
||||
void poll_unregister(int);
|
||||
void poll_dispatch(int wait);
|
||||
int poll_start_timer(u_int msecs, int repeat, timer_f func, void *arg);
|
||||
int poll_start_utimer(unsigned long long usecs, int repeat, timer_f func,
|
||||
void *arg);
|
||||
void poll_stop_timer(int);
|
||||
|
||||
# if defined(POLL_IN)
|
||||
|
@ -1,8 +1,8 @@
|
||||
'\"
|
||||
'\" Copyright (c)1996-2002 by Hartmut Brandt
|
||||
'\" Copyright (c)1996-2006 by Hartmut Brandt
|
||||
'\" All rights reserved.
|
||||
'\"
|
||||
'\" Author: Hartmut Brandt
|
||||
'\" Author: harti@freebsd.org <Hartmut Brandt>
|
||||
'\"
|
||||
'\" Redistribution of this software and documentation and use in source and
|
||||
'\" binary forms, with or without modification, are permitted provided that
|
||||
@ -28,28 +28,32 @@
|
||||
'\"
|
||||
'\" $Begemot: libbegemot/rpoll.man,v 1.4 2004/09/21 15:59:00 brandt Exp $
|
||||
'\"
|
||||
.TH rpoll 3 "21 Oct 1996" "BEGEMOT" "BEGEMOT Library"
|
||||
.TH rpoll 3 "8 Dec 2006" "BEGEMOT" "BEGEMOT Library"
|
||||
.SH NAME
|
||||
rpoll - callback functions for file descriptors and timers
|
||||
.SH SYNOPSIS
|
||||
.LP
|
||||
.B "# include <rpoll.h>"
|
||||
.LP
|
||||
.BR "typedef void (*poll_f)(int " "fd" ", int " "mask" ", void *" "arg);"
|
||||
.BR "typedef void (*poll_f)(int " "fd" ", int " "mask" ", void *" "arg" ");"
|
||||
.br
|
||||
.BR "typedef void (*timer_f)(int " "tid" ", void *" "arg);"
|
||||
.BR "typedef void (*timer_f)(int " "tid" ", void *" "arg" ");"
|
||||
.LP
|
||||
.BR "int poll_register(int " "fd" ", poll_f "
|
||||
.RB "func" ", void *" "arg" ", int " "mask" ");"
|
||||
.LP
|
||||
.BR "void poll_unregister(int " "handle" ");"
|
||||
.LP
|
||||
.BR "int poll_start_timer(u_int " "msecs" ", int " "repeat" ", timer_f " "func,"
|
||||
.BR "int poll_start_timer(u_int " "msecs" ", int " "repeat" ", timer_f " "func" ","
|
||||
.if n .ti +.5i
|
||||
.BR "void *" "arg);"
|
||||
.BR "void *" "arg" ");"
|
||||
.LP
|
||||
.BR "void poll_stop_timer(int " "handle" ");"
|
||||
.LP
|
||||
.BR "int poll_start_utimer(unsigned long long " "usecs" ", int " "repeat" ",
|
||||
.if n .ti +.5i
|
||||
.BR "timer_f " "func" ", void *" "arg" ");"
|
||||
.LP
|
||||
.BR "void poll_dispatch(int " "wait" ");"
|
||||
.SH DESCRIPTION
|
||||
Many programs need to read from several file descriptors at the same time.
|
||||
@ -113,9 +117,24 @@ with the handle returned by
|
||||
.BR poll_register .
|
||||
.LP
|
||||
A timer is created with
|
||||
.BR poll_start_timer .
|
||||
.BR poll_start_timer
|
||||
or
|
||||
.BR poll_start_utimer .
|
||||
.I msecs
|
||||
is the number of milliseconds, after which the timer event will be generated.
|
||||
is the number of milliseconds in
|
||||
.BR poll_start_timer
|
||||
while
|
||||
.I usecs
|
||||
is the number of microseconds in
|
||||
.BR poll_start_utimer ,
|
||||
after which the timer event will be generated.
|
||||
If the functions use the
|
||||
.BR poll (2)
|
||||
system call, then
|
||||
.I usecs
|
||||
is rounded to milliseconds and
|
||||
.BR poll_start_timer
|
||||
is called.
|
||||
.I repeat
|
||||
selects one-short behavior (if 0) or a repeatable timer (if not 0). A one-short timer
|
||||
will automatically unregistered after expiry.
|
||||
@ -123,7 +142,9 @@ will automatically unregistered after expiry.
|
||||
is the user function which will be called with a timer id and the user supplied
|
||||
.IR arg .
|
||||
.B poll_start_timer
|
||||
returnes a timer id, which may be used to cancel the timer with
|
||||
and
|
||||
.B poll_start_utimer
|
||||
return a timer id, which may be used to cancel the timer with
|
||||
.BR poll_stop_timer .
|
||||
A one-short timer should be canceled only if it has not yet fired.
|
||||
.LP
|
||||
@ -151,10 +172,12 @@ while(1)
|
||||
.SH "SEE ALSO"
|
||||
.BR poll (2), select (3C)
|
||||
.SH "RETURN VALUES"
|
||||
.B poll_register
|
||||
and
|
||||
.B poll_register ,
|
||||
.B poll_start_timer
|
||||
return a handle which may be used to unregister the file descriptor or cancel the timer.
|
||||
and
|
||||
.B poll_start_utimer
|
||||
return a handle which may be used to unregister the file descriptor or
|
||||
cancel the timer.
|
||||
.LP
|
||||
Both functions and
|
||||
.B poll_dispatch
|
||||
|
Loading…
x
Reference in New Issue
Block a user