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