(nnpfs_block_open): better cleanup on failure
[arla.git] / lwp / timer.c
blobed6da5534c4e8002a8d44bd46232b2c33dd62213
1 /*
2 ****************************************************************************
3 * Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
4 * *
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. *
12 * *
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 /*******************************************************************\
23 * *
24 * *
25 * Information Technology Center *
26 * Carnegie-Mellon University *
27 * *
28 * *
29 * *
30 \*******************************************************************/
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 RCSID("$Id$");
35 #endif
37 #include <sys/time.h>
38 #define _TIMER_IMPL_
39 #include "timer.h"
40 #include "q.h"
42 #include <stdlib.h>
43 #include <stdio.h>
45 #define FALSE 0
46 #define TRUE 1
48 #define NIL 0
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;
58 /* t1 = t2 - t3 */
60 static void
61 subtract(struct timeval *t1,
62 struct timeval *t2,
63 struct timeval *t3)
65 int sec2, usec2, sec3, usec3;
67 sec2 = t2 -> tv_sec;
68 usec2 = t2 -> tv_usec;
69 sec3 = t3 -> tv_sec;
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) {
76 usec2 += MILLION;
77 sec2--;
80 /* Check for a negative time and use zero for the answer,
81 * since the tv_sec field is unsigned */
83 if (sec3 > sec2) {
84 t1 -> tv_usec = 0;
85 t1 -> tv_sec = (unsigned long) 0;
86 } else {
87 t1 -> tv_usec = usec2 - usec3;
88 t1 -> tv_sec = sec2 - sec3;
92 /* t1 += t2; */
94 static void
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) {
100 t1 -> tv_sec ++;
101 t1 -> tv_usec -= MILLION;
105 /* t1 == t2 */
107 bool
108 TM_eql(struct timeval *t1, struct timeval *t2)
110 return (t1->tv_usec == t2->tv_usec) && (t1->tv_sec == t2->tv_sec);
113 /* t1 >= t2 */
116 obsolete, commentless procedure, all done by hand expansion now.
117 static bool
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);
125 static bool
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.
137 int
138 TM_Init(struct TM_Elem **list)
140 if (!globalInitDone) {
141 FT_Init (0, 0);
142 globalInitDone = 1;
144 *list = new_elem();
145 if (*list == NIL)
146 return -1;
147 else {
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;
156 return 0;
161 TM_Final(struct TM_Elem **list)
163 if (list == NIL || *list == NIL)
164 return -1;
165 else {
166 free(*list);
167 *list = NIL;
168 return 0;
173 * Inserts elem into the timer list pointed to by *tlistPtr.
176 void
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);
189 return;
192 /* Finite timeout, set expiration time */
193 FT_AGetTimeOfDay(&elem->expiration, 0);
194 add(&elem->expiration, &elem->TimeLeft);
195 next = NIL;
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 */
201 break;
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 */
218 struct timeval time;
219 int expired;
221 FT_AGetTimeOfDay(&time, 0);
222 expired = 0;
223 FOR_ALL_ELTS(e, tlist, {
224 if (!blocking(e)) {
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))
228 expired++;
231 return expired;
235 * RETURNS POINTER TO earliest expired entry from tlist.
236 * Returns 0 if no expired entries are present.
239 struct TM_Elem *
240 TM_GetExpired(struct TM_Elem *tlist)
241 /* head pointer of timer list */
243 FOR_ALL_ELTS(e, tlist, {
244 if (!blocking(e) &&
245 (0 > e->TimeLeft.tv_sec || (0 == e->TimeLeft.tv_sec
246 && 0 >= e->TimeLeft.tv_usec)))
247 return e;
249 return NIL;
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.
258 struct TM_Elem *
259 TM_GetEarliest(struct TM_Elem *tlist)
261 struct TM_Elem *e;
263 e = tlist -> Next;
264 return (e == tlist ? NIL : e);