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