2 ****************************************************************************
3 * Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
5 * Permission to use, copy, modify, and distribute this software and its *
6 * documentation for any purpose and without fee is hereby granted, *
7 * provided that the above copyright notice appear in all copies and *
8 * that both that copyright notice and this permission notice appear in *
9 * supporting documentation, and that the name of IBM not be used in *
10 * advertising or publicity pertaining to distribution of the software *
11 * without specific, written prior permission. *
13 * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
14 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
15 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
16 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
17 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
18 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
19 ****************************************************************************
22 /*******************************************************************\
25 * Information Technology Center *
26 * Carnegie-Mellon University *
30 \*******************************************************************/
50 #define expiration TotalTime
52 #define new_elem() ((struct TM_Elem *) malloc(sizeof(struct TM_Elem)))
54 #define MILLION 1000000
56 static int globalInitDone
= 0;
61 subtract(struct timeval
*t1
,
65 int sec2
, usec2
, sec3
, usec3
;
68 usec2
= t2
-> tv_usec
;
70 usec3
= t3
-> tv_usec
;
72 /* Take care of the probably non-existent case where the
73 * usec field has more than 1 second in it. */
75 while (usec3
> usec2
) {
80 /* Check for a negative time and use zero for the answer,
81 * since the tv_sec field is unsigned */
85 t1
-> tv_sec
= (unsigned long) 0;
87 t1
-> tv_usec
= usec2
- usec3
;
88 t1
-> tv_sec
= sec2
- sec3
;
95 add(struct timeval
*t1
, struct timeval
*t2
)
97 t1
-> tv_usec
+= t2
-> tv_usec
;
98 t1
-> tv_sec
+= t2
-> tv_sec
;
99 if (t1
->tv_usec
>= MILLION
) {
101 t1
-> tv_usec
-= MILLION
;
108 TM_eql(struct timeval
*t1
, struct timeval
*t2
)
110 return (t1
->tv_usec
== t2
->tv_usec
) && (t1
->tv_sec
== t2
->tv_sec
);
116 obsolete, commentless procedure, all done by hand expansion now.
118 geq(struct timeval *t1, struct timeval *t2)
120 return (t1->tv_sec > t2->tv_sec) ||
121 (t1->tv_sec == t2->tv_sec && t1->tv_usec >= t2->tv_usec);
126 blocking(struct TM_Elem
*t
)
128 return (t
->TotalTime
.tv_sec
< 0 || t
->TotalTime
.tv_usec
< 0);
134 * Initializes a list -- returns -1 if failure, else 0.
138 TM_Init(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
= NIL
;
161 TM_Final(struct TM_Elem
**list
)
163 if (list
== NIL
|| *list
== NIL
)
173 * Inserts elem into the timer list pointed to by *tlistPtr.
177 TM_Insert(struct TM_Elem
*tlistPtr
, struct TM_Elem
*elem
)
178 /* pointer to head pointer of timer list */
179 /* element to be inserted */
181 struct TM_Elem
*next
;
183 /* TimeLeft must be set for function IOMGR with infinite timeouts */
184 elem
-> TimeLeft
= elem
-> TotalTime
;
186 /* Special case -- infinite timeout */
187 if (blocking(elem
)) {
188 lwp_insque(elem
, tlistPtr
->Prev
);
192 /* Finite timeout, set expiration time */
193 FT_AGetTimeOfDay(&elem
->expiration
, 0);
194 add(&elem
->expiration
, &elem
->TimeLeft
);
196 FOR_ALL_ELTS(p
, tlistPtr
, {
197 if (blocking(p
) || !(elem
->TimeLeft
.tv_sec
> p
->TimeLeft
.tv_sec
||
198 (elem
->TimeLeft
.tv_sec
== p
->TimeLeft
.tv_sec
&& elem
->TimeLeft
.tv_usec
>= p
->TimeLeft
.tv_usec
))
200 next
= p
; /* Save ptr to element that will be after this one */
205 if (next
== NIL
) next
= tlistPtr
;
206 lwp_insque(elem
, next
->Prev
);
210 * Walks through the specified list and updates the TimeLeft fields in it.
211 * Returns number of expired elements in the list.
215 TM_Rescan(struct TM_Elem
*tlist
)
216 /* head pointer of timer list */
221 FT_AGetTimeOfDay(&time
, 0);
223 FOR_ALL_ELTS(e
, tlist
, {
225 subtract(&e
->TimeLeft
, &e
->expiration
, &time
);
226 if (0 > e
->TimeLeft
.tv_sec
|| (0 == e
->TimeLeft
.tv_sec
&& 0 >=
227 e
->TimeLeft
.tv_usec
))
235 * RETURNS POINTER TO earliest expired entry from tlist.
236 * Returns 0 if no expired entries are present.
240 TM_GetExpired(struct TM_Elem
*tlist
)
241 /* head pointer of timer list */
243 FOR_ALL_ELTS(e
, tlist
, {
245 (0 > e
->TimeLeft
.tv_sec
|| (0 == e
->TimeLeft
.tv_sec
246 && 0 >= e
->TimeLeft
.tv_usec
)))
253 * Returns a pointer to the earliest unexpired element in tlist.
254 * Its TimeLeft field will specify how much time is left.
255 * Returns 0 if tlist is empty or if there are no unexpired elements.
259 TM_GetEarliest(struct TM_Elem
*tlist
)
264 return (e
== tlist
? NIL
: e
);