* Copyright (c) 1983 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University 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 REGENTS 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 REGENTS 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
static char sccsid
[] = "@(#)clock.c 8.1 (Berkeley) 6/7/93";
# define sigmask(s) (1 << ((s) - 1))
** SETEVENT -- set an event to happen at a specific time.
** Events are stored in a sorted list for fast processing.
** An event only applies to the process that set it.
** intvl -- intvl until next event occurs.
** func -- function to call on event.
** arg -- argument to func on event.
setevent(intvl
, func
, arg
)
syserr("554 setevent: intvl=%ld\n", intvl
);
/* search event queue for correct position */
for (evp
= &EventQueue
; (ev
= *evp
) != NULL
; evp
= &ev
->ev_link
)
if (ev
->ev_time
>= now
+ intvl
)
ev
= (EVENT
*) xalloc(sizeof *ev
);
ev
->ev_time
= now
+ intvl
;
printf("setevent: intvl=%ld, for=%ld, func=%x, arg=%d, ev=%x\n",
intvl
, now
+ intvl
, func
, arg
, ev
);
** CLREVENT -- remove an event from the event queue.
** ev -- pointer to event to remove.
** arranges for event ev to not happen.
printf("clrevent: ev=%x\n", ev
);
/* find the parent event */
(void) signal(SIGALRM
, SIG_IGN
);
for (evp
= &EventQueue
; *evp
!= NULL
; evp
= &(*evp
)->ev_link
)
/* restore clocks and pick up anything spare */
** TICK -- take a clock tick
** Called by the alarm clock. This routine runs events as needed.
** calls the next function in EventQueue.
(void) signal(SIGALRM
, SIG_IGN
);
printf("tick: now=%ld\n", now
);
while ((ev
= EventQueue
) != NULL
&&
(ev
->ev_time
<= now
|| ev
->ev_pid
!= mypid
))
/* process the event on the top of the queue */
EventQueue
= EventQueue
->ev_link
;
printf("tick: ev=%x, func=%x, arg=%d, pid=%d\n", ev
,
ev
->ev_func
, ev
->ev_arg
, ev
->ev_pid
);
/* we must be careful in here because ev_func may not return */
(void) signal(SIGALRM
, tick
);
/* reset 4.2bsd signal mask to allow future alarms */
(void) sigsetmask(sigblock(0) & ~sigmask(SIGALRM
));
if (EventQueue
->ev_time
> now
)
(void) alarm((unsigned) (EventQueue
->ev_time
- now
));
(void) signal(SIGALRM
, tick
);
(void) alarm((unsigned) (EventQueue
->ev_time
- now
));
** SLEEP -- a version of sleep that works with this stuff
** Because sleep uses the alarm facility, I must reimplement
** intvl -- time to sleep.
** waits for intvl time. However, other events can
** be run during that interval.
(void) setevent((time_t) intvl
, endsleep
, 0);