Initial IBM OpenAFS 1.0 tree
[openafs.git] / src / rx / rx_event.h
1
2 /*
3 ****************************************************************************
4 *        Copyright IBM Corporation 1988, 1989 - All Rights Reserved        *
5 *                                                                          *
6 * Permission to use, copy, modify, and distribute this software and its    *
7 * documentation for any purpose and without fee is hereby granted,         *
8 * provided that the above copyright notice appear in all copies and        *
9 * that both that copyright notice and this permission notice appear in     *
10 * supporting documentation, and that the name of IBM not be used in        *
11 * advertising or publicity pertaining to distribution of the software      *
12 * without specific, written prior permission.                              *
13 *                                                                          *
14 * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
16 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY      *
17 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER  *
18 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING   *
19 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.    *
20 ****************************************************************************
21 */
22
23 /* Event package */ 
24
25 #ifndef _EVENT_
26 #define _EVENT_
27
28 #ifdef  KERNEL
29 #include "../rx/rx_queue.h"
30 #include "../rx/rx_clock.h"
31 #else /* KERNEL */
32 #include "rx_queue.h"
33 #include "rx_clock.h"
34 #endif /* KERNEL */
35
36 /* An event is something that will happen at (or after) a specified clock time, unless cancelled prematurely.  The user routine (*func)() is called with arguments (event, arg, arg1) when the event occurs.  Warnings:  (1) The user supplied routine should NOT cause process preemption.   (2) The event passed to the user is still on the event queue at that time.  The user must not remove (event_Cancel) it explicitly, but the user may remove or schedule any OTHER event at this time. */
37
38 struct rxevent {
39     struct rx_queue junk;    /* Events are queued */
40     struct clock eventTime; /* When this event times out (in clock.c units) */
41     void (*func)();         /* Function to call when this expires */
42     char *arg;              /* Argument to the function */
43     char *arg1;             /* Another argument */
44 };
45
46 /* We used to maintain a sorted list of events, but the amount of CPU
47  * required to maintain the list grew with the square of the number of
48  * connections. Now we keep a list of epochs, each epoch contains the
49  * events scheduled for a particular second. Each epoch contains a sorted
50  * list of the events scheduled for that epoch. */
51 struct rxepoch {
52     struct rx_queue junk;       /* Epochs are queued */
53     int epochSec;               /* each epoch spans one second */
54     struct rx_queue events;     /* list of events for this epoch */
55 };
56
57 /* Some macros to make macros more reasonable (this allows a block to be used within a macro which does not cause if statements to screw up).   That is, you can use "if (...) macro_name(); else ...;" without having things blow up on the semi-colon. */
58
59 #ifndef BEGIN
60 #define BEGIN do {
61 #define END } while(0)
62 #endif
63
64 /* This routine must be called to initialize the event package.  nEvents is the number of events to allocate in a batch whenever more are needed.  If this is 0, a default number (10) will be allocated. */
65 extern void rxevent_Init(/* nEvents, scheduler */);
66
67 /* Get the expiration time for the next event */
68 extern void exevent_NextEvent(/* when */);
69
70 /* Arrange for the indicated event at the appointed time.  When is a "struct clock", in the clock.c time base */
71 extern struct rxevent *rxevent_Post(/* when, func, arg, arg1 */);
72
73 /* Remove the indicated event from the event queue.  The event must be pending.  Also see the warning, above.  The event pointer supplied is zeroed. */
74 #ifdef RX_ENABLE_LOCKS
75 #ifdef RX_REFCOUNT_CHECK
76 extern void rxevent_Cancel_1(/* event_ptr, call , type*/);
77 #define rxevent_Cancel(event_ptr, call, type)                       \
78         BEGIN                                       \
79             if (event_ptr) {                        \
80                 rxevent_Cancel_1(event_ptr, call, type);            \
81                 event_ptr = (struct rxevent *) 0;           \
82             }                                       \
83         END
84 #else /* RX_REFCOUNT_CHECK */
85 extern void rxevent_Cancel_1(/* event_ptr, call*/);
86 #define rxevent_Cancel(event_ptr, call, type)                       \
87         BEGIN                                       \
88             if (event_ptr) {                        \
89                 rxevent_Cancel_1(event_ptr, call);          \
90                 event_ptr = (struct rxevent *) 0;           \
91             }                                       \
92         END
93 #endif /* RX_REFCOUNT_CHECK */
94 #else /* RX_ENABLE_LOCKS */
95 extern void rxevent_Cancel_1(/* event_ptr */);
96 #define rxevent_Cancel(event_ptr, call, type)                       \
97         BEGIN                                       \
98             if (event_ptr) {                        \
99                 rxevent_Cancel_1(event_ptr);        \
100                 event_ptr = (struct rxevent *) 0;           \
101             }                                       \
102         END
103 #endif /* RX_ENABLE_LOCKS */
104
105 /* The actions specified for each event that has reached the current clock time will be taken.  The current time returned by GetTime is used (warning:  this may be an old time if the user has not called clock_NewTime) */
106 extern int rxevent_RaiseEvents();
107
108 #endif /* _EVENT_ */