caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Matej Kosik <5764c029b688c1c0d24a2e97cd764f@gmail.com>
To: caml-list <caml-list@inria.fr>
Subject: [Caml-list] semaphore puzzle
Date: Mon, 30 Sep 2013 19:30:32 +0100	[thread overview]
Message-ID: <5249C348.9070408@gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1000 bytes --]

Hi,

I am trying to find the most simple and, if possible, clean way to synchronize my threads.

In this particular case, semaphores would be ideal
(alternatively, unbounded channels)

  (* Create a new semaphore with a given initial value. *)
  val create : int -> t

  (* V *)
  val up : t -> unit

  (* P *)
  val down : t -> unit

  val try_down : t -> bool

The "down" or "try_down" are almost the solutions, but not quite.

"down" may block forever ---> there is no timeout at all
                              (I need some)

"try_down" --->  the timeout is zero
                 (I prefer a non-zero timeout)

Obviously, I could use "try_down" in a loop, checking the system time myself and then either give up or actually manage to decrement the semaphore.

Is there a better solution than this?

(There is a Unix module, there are signals, but I am not sure whether it is safe to use them in multithreaded program.
 At least, I did not have a luck.)

Thanks in advance for patience &| help.

[-- Attachment #2: semaphore.ml --]
[-- Type: text/plain, Size: 1075 bytes --]

exception Timeout

type t = {mutex : Mutex.t;
          condition_lock : Condition.t;
          mutable value : int}

let create initial_value =
  assert (0 <= initial_value);
  {mutex = Mutex.create ();
   condition_lock = Condition.create ();
   value = initial_value}

let up semaphore =
  Mutex.lock semaphore.mutex;
  semaphore.value <- succ semaphore.value;
  Mutex.unlock semaphore.mutex;
  Condition.signal semaphore.condition_lock

let down semaphore =
  Mutex.lock semaphore.mutex;
  assert (0 <= semaphore.value);
  while semaphore.value = 0 do
    Condition.wait semaphore.condition_lock semaphore.mutex
  done;
  semaphore.value <- pred semaphore.value;
  Mutex.unlock semaphore.mutex

(* If it is possible to decrement the semaphore, do it and return "true".
   Otherwise return "false". *)
let try_down semaphore =
  Mutex.lock semaphore.mutex;
  if 0 < semaphore.value then
    begin
      semaphore.value <- pred semaphore.value;
      Mutex.unlock semaphore.mutex;
      true
    end
  else
    begin
      Mutex.unlock semaphore.mutex;
      false
    end

             reply	other threads:[~2013-09-30 18:30 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-30 18:30 Matej Kosik [this message]
2013-10-01 11:30 ` Gerd Stolpmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5249C348.9070408@gmail.com \
    --to=5764c029b688c1c0d24a2e97cd764f@gmail.com \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).