Initial OpenBSD support. Most of user space builds. No kernel module yet.
[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 #if defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) || defined(AFS_DJGPP_ENV)
23 int PRE_Block = 0;
24 #else
25 #include <sys/time.h>
26 #include <signal.h>
27 #include <ucontext.h>
28 #include "lwp.h"
29 #include "preempt.h"
30
31 #if defined(AFS_OSF_ENV) || defined(AFS_S390_LINUX20_ENV)
32 int PRE_Block = 0;              /* used in lwp.c and process.s */
33 #else
34 char PRE_Block = 0;             /* used in lwp.c and process.s */
35 #endif
36
37 static void AlarmHandler(sig, st, scp)
38     int sig;
39     siginfo_t *st;
40     ucontext_t *scp;
41     {
42     if (PRE_Block == 0 && lwp_cpptr->level == 0)
43         {
44         PRE_BeginCritical();
45         sigprocmask(SIG_SETMASK, &scp->uc_sigmask, NULL);
46         LWP_DispatchProcess();
47         PRE_EndCritical();
48         }
49     
50     }
51
52 int PRE_InitPreempt(slice)
53     struct timeval *slice;
54     {
55     struct itimerval itv;
56     struct sigaction action;
57
58     if (lwp_cpptr == 0) return (LWP_EINIT);
59     
60     if (slice == 0)
61         {
62         itv.it_interval.tv_sec = itv.it_value.tv_sec = DEFAULTSLICE;
63         itv.it_interval.tv_usec = itv.it_value.tv_usec = 0;
64         }
65     else
66         {
67         itv.it_interval = itv.it_value = *slice;
68         }
69
70     memset((char *)&action, 0, sizeof(action));
71     action.sa_sigaction = AlarmHandler;
72     action.sa_flags = SA_SIGINFO;
73
74     if ((sigaction(SIGALRM, &action, (struct sigaction *)0) == -1) ||
75         (setitimer(ITIMER_REAL, &itv, (struct itimerval *) 0) == -1))
76         return(LWP_ESYSTEM);
77
78     return(LWP_SUCCESS);
79     }
80
81 int PRE_EndPreempt()
82     {
83     struct itimerval itv;
84     struct sigaction action;
85
86     if (lwp_cpptr == 0) return (LWP_EINIT);
87     
88     itv.it_value.tv_sec = itv.it_value.tv_usec = 0;
89
90     memset((char *)&action, 0, sizeof(action));
91     action.sa_handler = SIG_DFL;
92
93     if ((setitimer(ITIMER_REAL, &itv, (struct itimerval *) 0) == -1) ||
94         (sigaction(SIGALRM, &action, (struct sigaction *)0) == -1))
95         return(LWP_ESYSTEM);
96
97     return(LWP_SUCCESS);
98     }
99
100 #endif /* AFS_LINUX20_ENV */