0ca9b5fea57fa6c70cc64106f32a8ef81ae7d832
[openafs.git] / src / lwp / preempt.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
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
8  */
9
10 /*******************************************************************\
11 *                                                                   *
12 *       Information Technology Center                               *
13 *       Carnegie-Mellon University                                  *
14 *                                                                   *
15 \*******************************************************************/
16 #include <afsconfig.h>
17 #include <afs/param.h>
18
19
20
21 #include "lwp.h"
22 #include "preempt.h"
23
24 #if defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
25 int PRE_Block = 0;
26
27
28 int
29 PRE_InitPreempt(struct timeval *slice)
30 {
31     return LWP_SUCCESS;
32 }
33
34 int
35 PRE_EndPreempt(void)
36 {
37     return LWP_SUCCESS;
38 }
39
40 #else
41 #include <sys/time.h>
42 #include <signal.h>
43 #ifdef HAVE_UCONTEXT_H
44 #include <ucontext.h>
45 #endif
46
47 #if defined(AFS_OSF_ENV) || defined(AFS_S390_LINUX20_ENV)
48 int PRE_Block = 0;              /* used in lwp.c and process.s */
49 #else
50 char PRE_Block = 0;             /* used in lwp.c and process.s */
51 #endif
52
53 #if HAVE_SIGACTION && defined(SA_SIGINFO)
54 static void
55 AlarmHandler(int sig, siginfo_t *st, ucontext_t *scp)
56 #else
57 static void
58 AlarmHandler(int sig, int code, struct sigcontext *scp)
59 #endif
60 {
61     if (PRE_Block == 0 && lwp_cpptr->level == 0) {
62         PRE_BeginCritical();
63 #if HAVE_SIGACTION && defined(SA_SIGINFO)
64         sigprocmask(SIG_SETMASK, &scp->uc_sigmask, NULL);
65 #else
66         sigsetmask(scp->sc_mask);
67 #endif
68         LWP_DispatchProcess();
69         PRE_EndCritical();
70     }
71
72 }
73
74 int
75 PRE_InitPreempt(struct timeval *slice)
76 {
77     struct itimerval itv;
78 #if HAVE_SIGACTION && defined(SA_SIGINFO)
79     struct sigaction action;
80 #else
81     struct sigvec vec;
82 #endif
83
84     if (lwp_cpptr == 0)
85         return (LWP_EINIT);
86
87     if (slice == 0) {
88         itv.it_interval.tv_sec = itv.it_value.tv_sec = DEFAULTSLICE;
89         itv.it_interval.tv_usec = itv.it_value.tv_usec = 0;
90     } else {
91         itv.it_interval = itv.it_value = *slice;
92     }
93
94 #if HAVE_SIGACTION && defined(SA_SIGINFO)
95     memset(&action, 0, sizeof(action));
96     action.sa_sigaction = AlarmHandler;
97     action.sa_flags = SA_SIGINFO;
98
99     if ((sigaction(SIGALRM, &action, NULL) == -1)
100         || (setitimer(ITIMER_REAL, &itv, NULL) == -1))
101         return (LWP_ESYSTEM);
102 #else
103     memset(&vec, 0, sizeof(vec));
104     vec.sv_handler = AlarmHandler;
105     vec.sv_mask = vec.sv_onstack = 0;
106
107     if ((sigvec(SIGALRM, &vec, (struct sigvec *)0) == -1)
108         || (setitimer(ITIMER_REAL, &itv, (struct itimerval *)0) == -1))
109         return (LWP_ESYSTEM);
110 #endif
111
112     return (LWP_SUCCESS);
113 }
114
115 int
116 PRE_EndPreempt()
117 {
118     struct itimerval itv;
119 #if HAVE_SIGACTION && defined(SA_SIGINFO)
120     struct sigaction action;
121 #else
122     struct sigvec vec;
123 #endif
124
125     if (lwp_cpptr == 0)
126         return (LWP_EINIT);
127
128     itv.it_value.tv_sec = itv.it_value.tv_usec = 0;
129
130 #if HAVE_SIGACTION && defined(SA_SIGINFO)
131     memset(&action, 0, sizeof(action));
132     action.sa_handler = SIG_DFL;
133
134     if ((setitimer(ITIMER_REAL, &itv, NULL) == -1)
135         || (sigaction(SIGALRM, &action, NULL) == -1))
136         return (LWP_ESYSTEM);
137
138 #else
139     memset(&vec, 0, sizeof(vec));
140     vec.sv_handler = SIG_DFL;
141     vec.sv_mask = vec.sv_onstack = 0;
142
143     if ((setitimer(ITIMER_REAL, &itv, (struct itimerval *)0) == -1)
144         || (sigvec(SIGALRM, &vec, (struct sigvec *)0) == -1))
145         return (LWP_ESYSTEM);
146 #endif
147     return (LWP_SUCCESS);
148 }
149
150 #endif /* AFS_LINUX20_ENV */