diff options
Diffstat (limited to 'otherlibs/threads/mutex.ml')
-rw-r--r-- | otherlibs/threads/mutex.ml | 29 |
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 + |