2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 /*******************************************************************\
13 * Information Technology Center *
14 * Carnegie-Mellon University *
18 \*******************************************************************/
21 #include <afsconfig.h>
22 #include <afs/param.h>
41 typedef unsigned char bool;
46 #define expiration TotalTime
48 #define new_elem() ((struct TM_Elem *) malloc(sizeof(struct TM_Elem)))
50 #define MILLION 1000000
52 static globalInitDone = 0;
54 void openafs_insque(struct TM_Elem *, struct TM_Elem *);
55 void openafs_remque(struct TM_Elem *);
60 register struct timeval *t1, *t2, *t3;
62 register int sec2, usec2, sec3, usec3;
69 /* Take care of the probably non-existent case where the
70 * usec field has more than 1 second in it. */
72 while (usec3 > usec2) {
77 /* Check for a negative time and use zero for the answer,
78 * since the tv_sec field is unsigned */
82 t1->tv_sec = (afs_uint32) 0;
84 t1->tv_usec = usec2 - usec3;
85 t1->tv_sec = sec2 - sec3;
93 register struct timeval *t1, *t2;
95 t1->tv_usec += t2->tv_usec;
96 t1->tv_sec += t2->tv_sec;
97 if (t1->tv_usec >= MILLION) {
99 t1->tv_usec -= MILLION;
106 TM_eql(struct timeval *t1, struct timeval *t2)
108 return (t1->tv_usec == t2->tv_usec) && (t1->tv_sec == t2->tv_sec);
114 obsolete, commentless procedure, all done by hand expansion now.
115 static bool geq(t1, t2)
116 register struct timeval *t1, *t2;
118 return (t1->tv_sec > t2->tv_sec) ||
119 (t1->tv_sec == t2->tv_sec && t1->tv_usec >= t2->tv_usec);
125 register struct TM_Elem *t;
127 return (t->TotalTime.tv_sec < 0 || t->TotalTime.tv_usec < 0);
133 Initializes a list -- returns -1 if failure, else 0.
138 register struct TM_Elem **list;
140 if (!globalInitDone) {
148 (*list)->Next = *list;
149 (*list)->Prev = *list;
150 (*list)->TotalTime.tv_sec = 0;
151 (*list)->TotalTime.tv_usec = 0;
152 (*list)->TimeLeft.tv_sec = 0;
153 (*list)->TimeLeft.tv_usec = 0;
154 (*list)->BackPointer = NULL;
162 register struct TM_Elem **list;
164 if (list == NULL || *list == NULL)
174 Inserts elem into the timer list pointed to by *tlistPtr.
178 TM_Insert(tlistPtr, elem)
179 struct TM_Elem *tlistPtr; /* pointer to head pointer of timer list */
180 struct TM_Elem *elem; /* element to be inserted */
182 register struct TM_Elem *next;
184 /* TimeLeft must be set for function IOMGR with infinite timeouts */
185 elem->TimeLeft = elem->TotalTime;
187 /* Special case -- infinite timeout */
188 if (blocking(elem)) {
189 openafs_insque(elem, tlistPtr->Prev);
193 /* Finite timeout, set expiration time */
194 FT_AGetTimeOfDay(&elem->expiration, 0);
195 add(&elem->expiration, &elem->TimeLeft);
197 FOR_ALL_ELTS(p, tlistPtr, {
199 || !(elem->TimeLeft.tv_sec > p->TimeLeft.tv_sec
200 || (elem->TimeLeft.tv_sec == p->TimeLeft.tv_sec
201 && elem->TimeLeft.tv_usec >=
202 p->TimeLeft.tv_usec))
204 next = p; /* Save ptr to element that will be after this one */
211 openafs_insque(elem, next->Prev);
215 Walks through the specified list and updates the TimeLeft fields in it.
216 Returns number of expired elements in the list.
221 struct TM_Elem *tlist; /* head pointer of timer list */
224 register int expired;
226 #ifndef AFS_DJGPP_ENV
227 FT_AGetTimeOfDay(&time, 0);
229 FT_GetTimeOfDay(&time, 0); /* we need a real time value */
232 FOR_ALL_ELTS(e, tlist, {
234 subtract(&e->TimeLeft, &e->expiration, &time);
235 if (0 > e->TimeLeft.tv_sec
236 || (0 == e->TimeLeft.tv_sec && 0 >= e->TimeLeft.tv_usec))
244 RETURNS POINTER TO earliest expired entry from tlist.
245 Returns 0 if no expired entries are present.
250 struct TM_Elem *tlist; /* head pointer of timer list */
252 FOR_ALL_ELTS(e, tlist, {
254 && (0 > e->TimeLeft.tv_sec
255 || (0 == e->TimeLeft.tv_sec
256 && 0 >= e->TimeLeft.tv_usec)))
263 Returns a pointer to the earliest unexpired element in tlist.
264 Its TimeLeft field will specify how much time is left.
265 Returns 0 if tlist is empty or if there are no unexpired elements.
269 TM_GetEarliest(tlist)
270 struct TM_Elem *tlist;
272 register struct TM_Elem *e;
275 return (e == tlist ? NULL : e);
278 /* This used to be in hputils.c, but it's only use is in the LWP package. */
280 * Emulate the vax instructions for queue insertion and deletion, somewhat.
281 * A std_queue structure is defined here and used by these routines. These
282 * routines use caddr_ts so they can operate on any structure. The std_queue
283 * structure is used rather than proc structures so that when the proc struct
284 * changes only process management code breaks. The ideal solution would be
285 * to define a std_queue as a global type which is part of all the structures
286 * which are manipulated by these routines. This would involve considerable
291 openafs_insque(struct TM_Elem *elementp, struct TM_Elem *quep)
293 elementp->Next = quep->Next;
294 elementp->Prev = quep;
296 quep->Next->Prev = elementp;
297 quep->Next = elementp;
301 openafs_remque(struct TM_Elem *elementp)
303 elementp->Next->Prev = elementp->Prev;
304 elementp->Prev->Next = elementp->Next;
305 elementp->Prev = elementp->Next = NULL;