summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Blandy <jimb@red-bean.com>1997-06-23 00:51:35 +0000
committerJim Blandy <jimb@red-bean.com>1997-06-23 00:51:35 +0000
commit8417b6657fc026c87ca8432e83b6584c675c8b6a (patch)
treedfc4ea98a084412559ca40a38c6f2a4b39973bf1
parent91b28bb55d7efb3167af9d2c39908047814f4d64 (diff)
downloadguile-8417b6657fc026c87ca8432e83b6584c675c8b6a.tar.gz
* __scm.h: (SCM_FENCE): New macro: optimizer will not move code
across this. Only works on GCC. Otherwise, we hope for the best. (SCM_DEFER_INTS, SCM_ALLOW_INTS): Use FENCE appropriately. I have the feeling that real thread systems will not need this...
-rw-r--r--libguile/__scm.h28
1 files changed, 27 insertions, 1 deletions
diff --git a/libguile/__scm.h b/libguile/__scm.h
index f265e2104..b7508edb6 100644
--- a/libguile/__scm.h
+++ b/libguile/__scm.h
@@ -284,11 +284,34 @@ extern unsigned int scm_async_clock;
#endif
+/* Anthony Green writes:
+ When the compiler sees...
+ DEFER_INTS;
+ [critical code here]
+ ALLOW_INTS;
+ ...it doesn't actually promise to keep the critical code within the
+ boundries of the DEFER/ALLOW_INTS instructions. It may very well
+ schedule it outside of the magic defined in those macros.
+
+ However, GCC's volatile asm feature forms a barrier over which code is
+ never moved. So if you add...
+ asm volatile ("");
+ ...to each of the DEFER_INTS and ALLOW_INTS macros, the critical code
+ will always remain in place. */
+#ifdef __GNUC__
+#define SCM_FENCE asm volatile ("")
+#else
+#define SCM_FENCE
+#endif
+
#define SCM_DEFER_INTS \
{ \
+ SCM_FENCE; \
SCM_CHECK_NOT_DISABLED; \
SCM_THREAD_DEFER; \
+ SCM_FENCE; \
scm_ints_disabled = 1; \
+ SCM_FENCE; \
} \
@@ -301,10 +324,13 @@ extern unsigned int scm_async_clock;
#define SCM_ALLOW_INTS \
{ \
+ SCM_FENCE; \
SCM_CHECK_NOT_ENABLED; \
- SCM_THREAD_ALLOW; \
scm_ints_disabled = 0; \
+ SCM_FENCE; \
+ SCM_THREAD_ALLOW; \
SCM_ASYNC_TICK; \
+ SCM_FENCE; \
} \