summaryrefslogtreecommitdiff
path: root/libguile/__scm.h
diff options
context:
space:
mode:
Diffstat (limited to 'libguile/__scm.h')
-rw-r--r--libguile/__scm.h128
1 files changed, 90 insertions, 38 deletions
diff --git a/libguile/__scm.h b/libguile/__scm.h
index bb6a60a34..3cb666398 100644
--- a/libguile/__scm.h
+++ b/libguile/__scm.h
@@ -446,53 +446,46 @@ do { \
#define SCM_FENCE
#endif
-#define SCM_DEFER_INTS \
-do { \
- SCM_FENCE; \
- SCM_CHECK_NOT_DISABLED; \
- SCM_CRITICAL_SECTION_START; \
- SCM_FENCE; \
- scm_ints_disabled = 1; \
- SCM_FENCE; \
+#define SCM_DEFER_INTS \
+do { \
+ SCM_FENCE; \
+ SCM_CHECK_NOT_DISABLED; \
+ SCM_REC_CRITICAL_SECTION_START (scm_i_defer); \
+ SCM_FENCE; \
+ scm_ints_disabled = 1; \
+ SCM_FENCE; \
} while (0)
-#define SCM_ALLOW_INTS_ONLY \
-do { \
- SCM_CRITICAL_SECTION_END; \
- scm_ints_disabled = 0; \
+#define SCM_ALLOW_INTS \
+do { \
+ SCM_FENCE; \
+ SCM_CHECK_NOT_ENABLED; \
+ SCM_REC_CRITICAL_SECTION_END (scm_i_defer); \
+ SCM_FENCE; \
+ scm_ints_disabled = 0; \
+ SCM_FENCE; \
+ SCM_THREAD_SWITCHING_CODE; \
+ SCM_FENCE; \
} while (0)
-#define SCM_ALLOW_INTS \
-do { \
- SCM_FENCE; \
- SCM_CHECK_NOT_ENABLED; \
- SCM_CRITICAL_SECTION_END; \
- SCM_FENCE; \
- scm_ints_disabled = 0; \
- SCM_FENCE; \
- SCM_THREAD_SWITCHING_CODE; \
- SCM_FENCE; \
+#define SCM_REDEFER_INTS \
+do { \
+ SCM_FENCE; \
+ SCM_REC_CRITICAL_SECTION_START (scm_i_defer); \
+ ++scm_ints_disabled; \
+ SCM_FENCE; \
} while (0)
-#define SCM_REDEFER_INTS \
-do { \
- SCM_FENCE; \
- SCM_CRITICAL_SECTION_START; \
- ++scm_ints_disabled; \
- SCM_FENCE; \
-} while (0)
-
-
-#define SCM_REALLOW_INTS \
-do { \
- SCM_FENCE; \
- SCM_CRITICAL_SECTION_END; \
- SCM_FENCE; \
- --scm_ints_disabled; \
- SCM_FENCE; \
+#define SCM_REALLOW_INTS \
+do { \
+ SCM_FENCE; \
+ SCM_REC_CRITICAL_SECTION_END (scm_i_defer); \
+ SCM_FENCE; \
+ --scm_ints_disabled; \
+ SCM_FENCE; \
} while (0)
@@ -504,6 +497,65 @@ do { \
+/* Critical sections */
+
+#define SCM_DECLARE_NONREC_CRITICAL_SECTION(prefix) \
+ extern scm_t_mutex prefix ## _mutex
+
+#define SCM_NONREC_CRITICAL_SECTION_START(prefix) \
+ do { scm_thread *t = scm_i_leave_guile (); \
+ scm_i_plugin_mutex_lock (&prefix ## _mutex); \
+ scm_i_enter_guile (t); \
+ } while (0)
+
+#define SCM_NONREC_CRITICAL_SECTION_END(prefix) \
+ do { scm_i_plugin_mutex_unlock (&prefix ## _mutex); \
+ } while (0)
+
+/* This could be replaced by a single call to scm_i_plugin_mutex_lock
+ on systems which support recursive mutecis (like LinuxThreads).
+ We should test for the presence of recursive mutecis in
+ configure.in.
+
+ Also, it is probably possible to replace recursive sections with
+ non-recursive ones, so don't worry about the complexity.
+ */
+
+#define SCM_DECLARE_REC_CRITICAL_SECTION(prefix) \
+ extern scm_t_mutex prefix ## _mutex; \
+ extern int prefix ## _count; \
+ extern scm_thread *prefix ## _owner
+
+#define SCM_REC_CRITICAL_SECTION_START(prefix) \
+ do { scm_i_plugin_mutex_lock (&scm_i_section_mutex); \
+ if (prefix ## _count && prefix ## _owner == SCM_CURRENT_THREAD) \
+ { \
+ ++prefix ## _count; \
+ scm_i_plugin_mutex_unlock (&scm_i_section_mutex); \
+ } \
+ else \
+ { \
+ scm_thread *t = scm_i_leave_guile (); \
+ scm_i_plugin_mutex_unlock (&scm_i_section_mutex); \
+ scm_i_plugin_mutex_lock (&prefix ## _mutex); \
+ prefix ## _count = 1; \
+ prefix ## _owner = t; \
+ scm_i_enter_guile (t); \
+ } \
+ } while (0)
+
+#define SCM_REC_CRITICAL_SECTION_END(prefix) \
+ do { scm_i_plugin_mutex_lock (&scm_i_section_mutex); \
+ if (!--prefix ## _count) \
+ { \
+ prefix ## _owner = 0; \
+ scm_i_plugin_mutex_unlock (&prefix ## _mutex); \
+ } \
+ scm_i_plugin_mutex_unlock (&scm_i_section_mutex); \
+ } while (0)
+
+/* Note: The following needs updating. */
+
/* Classification of critical sections
*
* When Guile moves to POSIX threads, it won't be possible to prevent