aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2008-02-05 01:31:09 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-05 12:44:29 -0500
commitfce8c41c9f68b9af36f3076bae8f1d469a6e7aab (patch)
tree3580fd114bcef42a898c838f5a58ddcb2d29ae99 /arch/um
parent0983a88b9f0ceffb2116ce92c7b273ce2aec7b93 (diff)
uml: use barrier() instead of mb()
signals_enabled and pending have requirements on the order in which they are modified. This used to be done by declaring them volatile and putting an mb() where the ordering requirements were in effect. After getting a better (I hope) understanding of how to do this correctly, the volatile declarations are gone and the mb()'s replaced by barrier()'s. One of the mb()'s was deleted because I see no problematic writes that could be re-ordered past that point. Signed-off-by: Jeff Dike <jdike@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/os-Linux/signal.c28
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/* 33static int signals_enabled;
31 * These are used by both the signal handlers and 34static unsigned int pending;
32 * block/unblock_signals. I don't want modifications cached in a
33 * register - they must go straight to memory.
34 */
35static volatile int signals_enabled = 1;
36static volatile int pending = 0;
37 35
38void sig_handler(int sig, struct sigcontext *sc) 36void 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
204void unblock_signals(void) 202void 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