From 1a320e34ff787813880802b922362e2485243b4a Mon Sep 17 00:00:00 2001 From: harti Date: Fri, 8 Dec 2006 14:45:15 +0000 Subject: Vendor patch that adds a microsecond timer function. --- contrib/libbegemot/rpoll.c | 98 ++++++++++++++++++++++++++++---------------- contrib/libbegemot/rpoll.h | 2 + contrib/libbegemot/rpoll.man | 49 ++++++++++++++++------ 3 files changed, 100 insertions(+), 49 deletions(-) (limited to 'contrib/libbegemot') diff --git a/contrib/libbegemot/rpoll.c b/contrib/libbegemot/rpoll.c index b598663..408635e 100644 --- a/contrib/libbegemot/rpoll.c +++ b/contrib/libbegemot/rpoll.c @@ -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; } @@ -373,6 +373,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; /* find unused entry */ @@ -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); diff --git a/contrib/libbegemot/rpoll.h b/contrib/libbegemot/rpoll.h index baa11b2..497a41e 100644 --- a/contrib/libbegemot/rpoll.h +++ b/contrib/libbegemot/rpoll.h @@ -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) diff --git a/contrib/libbegemot/rpoll.man b/contrib/libbegemot/rpoll.man index 9b5c406..7550ffb 100644 --- a/contrib/libbegemot/rpoll.man +++ b/contrib/libbegemot/rpoll.man @@ -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 '\" '\" 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 " .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 -- cgit v1.1