summaryrefslogtreecommitdiffstats
path: root/otherlibs/threads/mutex.ml
diff options
context:
space:
mode:
Diffstat (limited to 'otherlibs/threads/mutex.ml')
-rw-r--r--otherlibs/threads/mutex.ml29
1 files changed, 24 insertions, 5 deletions
diff --git a/otherlibs/threads/mutex.ml b/otherlibs/threads/mutex.ml
index c9eb0f820..551bc5706 100644
--- a/otherlibs/threads/mutex.ml
+++ b/otherlibs/threads/mutex.ml
@@ -11,8 +11,27 @@
(* $Id$ *)
-type t
-external new: unit -> t = "csl_mutex_new"
-external lock: t -> unit = "csl_mutex_lock"
-external try_lock: t -> bool = "csl_mutex_try_lock"
-external unlock: t -> unit = "csl_mutex_unlock"
+type t = { mutable locked: bool; mutable waiting: Thread.t list }
+
+let new () = { locked = false; waiting = [] }
+
+let rec lock m =
+ if m.locked then begin (* test and set atomic *)
+ Thread.critical_section := true;
+ m.waiting <- Thread.self() :: m.waiting;
+ Thread.sleep();
+ lock m
+ end else begin
+ m.locked <- true (* test and set atomic *)
+ end
+
+let try_lock m = (* test and set atomic *)
+ if m.locked then false else begin m.locked <- true; true end
+
+let unlock m =
+ (* Don't play with Thread.critical_section here because of Condition.wait *)
+ let w = m.waiting in (* atomic *)
+ m.waiting <- []; (* atomic *)
+ m.locked <- false; (* atomic *)
+ List.iter Thread.wakeup w
+