diff options
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r-- | arch/um/os-Linux/signal.c | 28 |
1 files changed, 8 insertions, 20 deletions
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 7ff8f57b7150..62a66f38a913 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c | |||
@@ -15,6 +15,9 @@ | |||
15 | #include "sysdep/sigcontext.h" | 15 | #include "sysdep/sigcontext.h" |
16 | #include "user.h" | 16 | #include "user.h" |
17 | 17 | ||
18 | /* Copied from linux/compiler-gcc.h since we can't include it directly */ | ||
19 | #define barrier() __asm__ __volatile__("": : :"memory") | ||
20 | |||
18 | /* | 21 | /* |
19 | * These are the asynchronous signals. SIGPROF is excluded because we want to | 22 | * These are the asynchronous signals. SIGPROF is excluded because we want to |
20 | * be able to profile all of UML, not just the non-critical sections. If | 23 | * be able to profile all of UML, not just the non-critical sections. If |
@@ -27,13 +30,8 @@ | |||
27 | #define SIGVTALRM_BIT 1 | 30 | #define SIGVTALRM_BIT 1 |
28 | #define SIGVTALRM_MASK (1 << SIGVTALRM_BIT) | 31 | #define SIGVTALRM_MASK (1 << SIGVTALRM_BIT) |
29 | 32 | ||
30 | /* | 33 | static int signals_enabled; |
31 | * These are used by both the signal handlers and | 34 | static unsigned int pending; |
32 | * block/unblock_signals. I don't want modifications cached in a | ||
33 | * register - they must go straight to memory. | ||
34 | */ | ||
35 | static volatile int signals_enabled = 1; | ||
36 | static volatile int pending = 0; | ||
37 | 35 | ||
38 | void sig_handler(int sig, struct sigcontext *sc) | 36 | void sig_handler(int sig, struct sigcontext *sc) |
39 | { | 37 | { |
@@ -198,7 +196,7 @@ void block_signals(void) | |||
198 | * This might matter if gcc figures out how to inline this and | 196 | * This might matter if gcc figures out how to inline this and |
199 | * decides to shuffle this code into the caller. | 197 | * decides to shuffle this code into the caller. |
200 | */ | 198 | */ |
201 | mb(); | 199 | barrier(); |
202 | } | 200 | } |
203 | 201 | ||
204 | void unblock_signals(void) | 202 | void unblock_signals(void) |
@@ -224,21 +222,11 @@ void unblock_signals(void) | |||
224 | * Setting signals_enabled and reading pending must | 222 | * Setting signals_enabled and reading pending must |
225 | * happen in this order. | 223 | * happen in this order. |
226 | */ | 224 | */ |
227 | mb(); | 225 | barrier(); |
228 | 226 | ||
229 | save_pending = pending; | 227 | save_pending = pending; |
230 | if (save_pending == 0) { | 228 | if (save_pending == 0) |
231 | /* | ||
232 | * This must return with signals enabled, so | ||
233 | * this barrier ensures that writes are | ||
234 | * flushed out before the return. This might | ||
235 | * matter if gcc figures out how to inline | ||
236 | * this (unlikely, given its size) and decides | ||
237 | * to shuffle this code into the caller. | ||
238 | */ | ||
239 | mb(); | ||
240 | return; | 229 | return; |
241 | } | ||
242 | 230 | ||
243 | pending = 0; | 231 | pending = 0; |
244 | 232 | ||