[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 17/24: Replace scm_make_mutex_with_flags
From: |
Andy Wingo |
Subject: |
[Guile-commits] 17/24: Replace scm_make_mutex_with_flags |
Date: |
Sun, 6 Nov 2016 18:00:46 +0000 (UTC) |
wingo pushed a commit to branch master
in repository guile.
commit 768246124164243059b0eeb772d3bb5bf1db0db9
Author: Andy Wingo <address@hidden>
Date: Sat Nov 5 11:14:17 2016 +0100
Replace scm_make_mutex_with_flags
* libguile/threads.c (enum fat_mutex_kind): New data type, replacing
separate flags.
(struct fat_mutex): Adapt.
(make_fat_mutex): Fat mutexes can only be one of three kinds, not one
of 4 kinds. (Recursive unowned mutexes are not a thing.)
(scm_make_mutex): Adapt.
(scm_make_mutex_with_kind): New function, replacing
scm_make_mutex_with_flags. Still bound to make-mutex.
(scm_make_recursive_mutex): Adapt.
(fat_mutex_lock, fat_mutex_unlock): Adapt.
* libguile/threads.h (scm_make_mutex_with_kind): New decl.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_mutex_with_flags): Deprecate.
---
libguile/deprecated.c | 22 +++++++++++++++
libguile/deprecated.h | 4 +++
libguile/threads.c | 75 +++++++++++++++++++++++++++++--------------------
libguile/threads.h | 2 +-
4 files changed, 72 insertions(+), 31 deletions(-)
diff --git a/libguile/deprecated.c b/libguile/deprecated.c
index c8d353f..fd671e9 100644
--- a/libguile/deprecated.c
+++ b/libguile/deprecated.c
@@ -680,6 +680,28 @@ scm_dynwind_critical_section (SCM mutex)
+SCM
+scm_make_mutex_with_flags (SCM flags)
+{
+ SCM kind = SCM_UNDEFINED;
+
+ scm_c_issue_deprecation_warning
+ ("'scm_make_mutex_with_flags' is deprecated. "
+ "Use 'scm_make_mutex_with_kind' instead.");
+
+ if (!scm_is_null (flags))
+ {
+ if (!scm_is_null (scm_cdr (flags)))
+ scm_misc_error (NULL, "too many mutex options: ~a", scm_list_1 (flags));
+ kind = scm_car (flags);
+ }
+
+ return scm_make_mutex_with_kind (kind);
+}
+
+
+
+
void
scm_i_init_deprecated ()
{
diff --git a/libguile/deprecated.h b/libguile/deprecated.h
index d8ce816..d20ff5b 100644
--- a/libguile/deprecated.h
+++ b/libguile/deprecated.h
@@ -238,6 +238,10 @@ SCM_DEPRECATED void scm_dynwind_critical_section (SCM
mutex);
+SCM_DEPRECATED SCM scm_make_mutex_with_flags (SCM flags);
+
+
+
void scm_i_init_deprecated (void);
#endif
diff --git a/libguile/threads.c b/libguile/threads.c
index 9d9b01a..d44d3b1 100644
--- a/libguile/threads.c
+++ b/libguile/threads.c
@@ -510,15 +510,31 @@ guilify_self_2 (SCM parent)
debugging.
*/
+enum fat_mutex_kind {
+ /* A standard mutex can only be locked once. If you try to lock it
+ again from the thread that locked it to begin with (the "owner"
+ thread), it throws an error. It can only be unlocked from the
+ thread that locked it in the first place. */
+ FAT_MUTEX_STANDARD,
+ /* A recursive mutex can be locked multiple times by its owner. It
+ then has to be unlocked the corresponding number of times, and like
+ standard mutexes can only be unlocked by the owner thread. */
+ FAT_MUTEX_RECURSIVE,
+ /* An unowned mutex is like a standard mutex, except that it can be
+ unlocked by any thread. A corrolary of this behavior is that a
+ thread's attempt to lock a mutex that it already owns will block
+ instead of signalling an error, as it could be that some other
+ thread unlocks the mutex, allowing the owner thread to proceed.
+ This kind of mutex is a bit strange and is here for use by
+ SRFI-18. */
+ FAT_MUTEX_UNOWNED
+};
+
typedef struct {
scm_i_pthread_mutex_t lock;
SCM owner;
int level; /* how much the owner owns us. <= 1 for non-recursive mutexes */
-
- int recursive; /* allow recursive locking? */
- int allow_external_unlock; /* is it an error to unlock a mutex that is not
- owned by the current thread? */
-
+ enum fat_mutex_kind kind;
SCM waiting; /* the threads waiting for this mutex. */
} fat_mutex;
@@ -1064,7 +1080,7 @@ fat_mutex_print (SCM mx, SCM port, scm_print_state
*pstate SCM_UNUSED)
}
static SCM
-make_fat_mutex (int recursive, int external_unlock)
+make_fat_mutex (enum fat_mutex_kind kind)
{
fat_mutex *m;
SCM mx;
@@ -1076,10 +1092,7 @@ make_fat_mutex (int recursive, int external_unlock)
memcpy (&m->lock, &lock, sizeof (m->lock));
m->owner = SCM_BOOL_F;
m->level = 0;
-
- m->recursive = recursive;
- m->allow_external_unlock = external_unlock;
-
+ m->kind = kind;
m->waiting = SCM_EOL;
SCM_NEWSMOB (mx, scm_tc16_mutex, (scm_t_bits) m);
m->waiting = make_queue ();
@@ -1088,32 +1101,34 @@ make_fat_mutex (int recursive, int external_unlock)
SCM scm_make_mutex (void)
{
- return scm_make_mutex_with_flags (SCM_EOL);
+ return scm_make_mutex_with_kind (SCM_UNDEFINED);
}
SCM_SYMBOL (allow_external_unlock_sym, "allow-external-unlock");
SCM_SYMBOL (recursive_sym, "recursive");
-SCM_DEFINE (scm_make_mutex_with_flags, "make-mutex", 0, 0, 1,
- (SCM flags),
- "Create a new mutex. ")
-#define FUNC_NAME s_scm_make_mutex_with_flags
+SCM_DEFINE (scm_make_mutex_with_kind, "make-mutex", 0, 1, 0,
+ (SCM kind),
+ "Create a new mutex. If @var{kind} is not given, the mutex\n"
+ "will be a standard non-recursive mutex. Otherwise pass\n"
+ "@code{recursive} to make a recursive mutex, or\n"
+ "@code{allow-external-unlock} to make a non-recursive mutex\n"
+ "that can be unlocked from any thread.")
+#define FUNC_NAME s_scm_make_mutex_with_kind
{
- int external_unlock = 0, recursive = 0;
+ enum fat_mutex_kind mkind = FAT_MUTEX_STANDARD;
- SCM ptr = flags;
- while (! scm_is_null (ptr))
+ if (!SCM_UNBNDP (kind))
{
- SCM flag = SCM_CAR (ptr);
- if (scm_is_eq (flag, allow_external_unlock_sym))
- external_unlock = 1;
- else if (scm_is_eq (flag, recursive_sym))
- recursive = 1;
+ if (scm_is_eq (kind, allow_external_unlock_sym))
+ mkind = FAT_MUTEX_UNOWNED;
+ else if (scm_is_eq (kind, recursive_sym))
+ mkind = FAT_MUTEX_RECURSIVE;
else
- SCM_MISC_ERROR ("unsupported mutex option: ~a", scm_list_1 (flag));
- ptr = SCM_CDR (ptr);
+ SCM_MISC_ERROR ("unsupported mutex kind: ~a", scm_list_1 (kind));
}
- return make_fat_mutex (recursive, external_unlock);
+
+ return make_fat_mutex (mkind);
}
#undef FUNC_NAME
@@ -1122,7 +1137,7 @@ SCM_DEFINE (scm_make_recursive_mutex,
"make-recursive-mutex", 0, 0, 0,
"Create a new recursive mutex. ")
#define FUNC_NAME s_scm_make_recursive_mutex
{
- return make_fat_mutex (1, 0);
+ return scm_make_mutex_with_kind (recursive_sym);
}
#undef FUNC_NAME
@@ -1147,9 +1162,9 @@ fat_mutex_lock (SCM mutex, scm_t_timespec *timeout, int
*ret)
*ret = 1;
break;
}
- else if (scm_is_eq (m->owner, new_owner) && !m->allow_external_unlock)
+ else if (scm_is_eq (m->owner, new_owner) && m->kind != FAT_MUTEX_UNOWNED)
{
- if (m->recursive)
+ if (m->kind == FAT_MUTEX_RECURSIVE)
{
m->level++;
*ret = 1;
@@ -1283,7 +1298,7 @@ fat_mutex_unlock (SCM mutex, SCM cond,
scm_i_pthread_mutex_unlock (&m->lock);
scm_misc_error (NULL, "mutex not locked", SCM_EOL);
}
- else if (!m->allow_external_unlock)
+ else if (m->kind != FAT_MUTEX_UNOWNED)
{
scm_i_pthread_mutex_unlock (&m->lock);
scm_misc_error (NULL, "mutex not locked by current thread", SCM_EOL);
diff --git a/libguile/threads.h b/libguile/threads.h
index 0aef61d..821d27c 100644
--- a/libguile/threads.h
+++ b/libguile/threads.h
@@ -150,7 +150,7 @@ SCM_API SCM scm_thread_p (SCM t);
SCM_API SCM scm_make_mutex (void);
SCM_API SCM scm_make_recursive_mutex (void);
-SCM_API SCM scm_make_mutex_with_flags (SCM flags);
+SCM_API SCM scm_make_mutex_with_kind (SCM kind);
SCM_API SCM scm_lock_mutex (SCM m);
SCM_API SCM scm_lock_mutex_timed (SCM m, SCM timeout, SCM owner);
SCM_API void scm_dynwind_lock_mutex (SCM mutex);
- [Guile-commits] 15/24: Recursively locking a SRFI-18 mutex blocks, (continued)
- [Guile-commits] 15/24: Recursively locking a SRFI-18 mutex blocks, Andy Wingo, 2016/11/06
- [Guile-commits] 19/24: Separate fat mutex unlock and wait operations, Andy Wingo, 2016/11/06
- [Guile-commits] 06/24: Update SRFI-18 documentation., Andy Wingo, 2016/11/06
- [Guile-commits] 11/24: Remove thread held pthread_mutex field, Andy Wingo, 2016/11/06
- [Guile-commits] 13/24: Move more functionality to SRFI-18 mutex-unlock!, Andy Wingo, 2016/11/06
- [Guile-commits] 03/24: SRFI-18 mutexes disjoint from Guile mutexes, Andy Wingo, 2016/11/06
- [Guile-commits] 16/24: Remove unchecked-unlock facility from Guile mutexes, Andy Wingo, 2016/11/06
- [Guile-commits] 24/24: Update NEWS., Andy Wingo, 2016/11/06
- [Guile-commits] 22/24: Update documentation on mutexes, Andy Wingo, 2016/11/06
- [Guile-commits] 20/24: Update mutex documentation, Andy Wingo, 2016/11/06
- [Guile-commits] 17/24: Replace scm_make_mutex_with_flags,
Andy Wingo <=
- [Guile-commits] 23/24: Minor editing in api-scheduling.texi, Andy Wingo, 2016/11/06