Add dual-license information.
[bertos.git] / kern / signal.c
1 /*!
2  * \file
3  * <!--
4  * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
5  * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
6  * This file is part of DevLib - See devlib/README for information.
7  * -->
8  *
9  * \brief IPC signals implementation.
10  *
11  * Each process can wait for just one signal.
12  * Multiple processes can wait for the same signal. In this
13  * case, each signal will wake-up one of them.
14  *
15  * \version $Id$
16  *
17  * \author Bernardo Innocenti <bernie@develer.com>
18  */
19
20 /*
21  * $Log$
22  * Revision 1.2  2004/06/03 11:27:09  bernie
23  * Add dual-license information.
24  *
25  * Revision 1.1  2004/05/23 17:27:00  bernie
26  * Import kern/ subdirectory.
27  *
28  */
29
30 #include "signal.h"
31 #include "proc.h"
32 #include "proc_p.h"
33 #include "hw.h"
34
35 // FIXME
36 #if CONFIG_KERN_SIGNALS
37
38 /*!
39  * Check if any of the signals in \a sigs has occurred and clear them.
40  * Return the signals that have occurred.
41  */
42 sigset_t sig_check(sigset_t sigs)
43 {
44         sigset_t result;
45
46         DISABLE_INTS;
47         result = CurrentProcess->sig_recv & sigs;
48         CurrentProcess->sig_recv &= ~sigs;
49         ENABLE_INTS;
50         return result;
51 }
52
53
54 /*!
55  * Sleep until any of the signals in \a sigs occurs.
56  * Return the signal(s) that have awaked the process.
57  */
58 sigset_t sig_wait(sigset_t sigs)
59 {
60         sigset_t result;
61
62         DISABLE_INTS;
63
64         for(;;)
65         {
66                 /* Check if we got at least one of the signals */
67                 if ((result = CurrentProcess->sig_recv & sigs))
68                 {
69                         /* Yes, clear signals and return */
70                         CurrentProcess->sig_recv &= ~sigs;
71                         ENABLE_INTS;
72                         return result;
73                 }
74
75                 /* No, go to sleep and proc_schedule() another process */
76                 CurrentProcess->sig_wait = sigs;
77                 proc_schedule();
78         }
79 }
80
81
82 /*!
83  * Send the signals \a sigs to the process \a proc.
84  * The process will be awaken if it was waiting for any of them.
85  *
86  * This call is interrupt safe (no \c DISABLE_INTS/ENABLE_INTS protection)
87  */
88 void _sig_signal(Process *proc, sigset_t sigs)
89 {
90         /* Set the signals */
91         proc->sig_recv |= sigs;
92
93         /* Check if process needs to be awaken */
94         if (proc->sig_recv & proc->sig_wait)
95         {
96                 /* Wake up process and enqueue in ready list */
97                 proc->sig_wait = 0;
98                 SCHED_ENQUEUE(proc);
99         }
100 }
101
102
103 /*!
104  * Same as _sig_signal() with interrupt protection.
105  *
106  * \note Inlined manually because some compilers are too
107  *       stupid to it automatically.
108  */
109 void sig_signal(Process *proc, sigset_t sigs)
110 {
111         DISABLE_INTS;
112
113         /* Set the signals */
114         proc->sig_recv |= sigs;
115
116         /* Check if process needs to be awaken */
117         if (proc->sig_recv & proc->sig_wait)
118         {
119                 /* Wake up process and enqueue in ready list */
120                 proc->sig_wait = 0;
121                 SCHED_ENQUEUE(proc);
122         }
123
124         ENABLE_INTS;
125 }
126
127 #endif /* CONFIG_KERN_SIGNALS */
128