From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <5764c029b688c1c0d24a2e97cd764f@gmail.com> X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id EDC1F7EE4B for ; Mon, 30 Sep 2013 20:30:27 +0200 (CEST) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of 5764c029b688c1c0d24a2e97cd764f@gmail.com) identity=pra; client-ip=74.125.82.41; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="5764c029b688c1c0d24a2e97cd764f@gmail.com"; x-sender="5764c029b688c1c0d24a2e97cd764f@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of 5764c029b688c1c0d24a2e97cd764f@gmail.com designates 74.125.82.41 as permitted sender) identity=mailfrom; client-ip=74.125.82.41; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="5764c029b688c1c0d24a2e97cd764f@gmail.com"; x-sender="5764c029b688c1c0d24a2e97cd764f@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-wg0-f41.google.com) identity=helo; client-ip=74.125.82.41; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="5764c029b688c1c0d24a2e97cd764f@gmail.com"; x-sender="postmaster@mail-wg0-f41.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: As4FAL3CSVJKfVIpm2dsb2JhbABZgh+KeLkoFg4BAQEBAQYLCwkUKIJTGQEbHAIDEhAWFhgDAgECARERAQUBFgwNCAIXh1gBAw8EnGaDA4xSgwqEFwoZJw1kiQABBQyTbgOQJ4EwhiiGM4lcQYRO X-IPAS-Result: As4FAL3CSVJKfVIpm2dsb2JhbABZgh+KeLkoFg4BAQEBAQYLCwkUKIJTGQEbHAIDEhAWFhgDAgECARERAQUBFgwNCAIXh1gBAw8EnGaDA4xSgwqEFwoZJw1kiQABBQyTbgOQJ4EwhiiGM4lcQYRO X-IronPort-AV: E=Sophos;i="4.90,1009,1371074400"; d="ml'?scan'208";a="28599091" Received: from mail-wg0-f41.google.com ([74.125.82.41]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/RC4-SHA; 30 Sep 2013 20:30:27 +0200 Received: by mail-wg0-f41.google.com with SMTP id l18so3911255wgh.4 for ; Mon, 30 Sep 2013 11:30:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject :content-type; bh=vAvAMmEzi0arz/kfeFjzsBf1jUPEzRAnLMlG5CFysaU=; b=ZhF267TWcq5SxuxgI0C/qwZK9DaD4z+J787Ul/8+MRBPqWGouonHH5Sf8irsUcXSlx IQ6+t0sQCGcOZehmsABarVhLY5vWkl5CBN6CcnLDOMBb5g4chqlo3KWKT0Cx8OxBbaUq O+w910/5+qMsJ/d6r/Zmvufe69PsZa5QisoQX+lmpAHHX5+gu593LwGGmTr0AVn9zACq gyt+iCccpfpBwy7tsQCpj1LnCceMZBdKjaDaHIWn46w4IZDUhVD1tHEDsmWmQ1VxEKOA FVp7xBPG9Ff8DCsnO2JSLaEA99PyS7W0aaJtVFzBFmZld+QOJgAwmVVsDyvxoZ/Cxp7I n0kQ== X-Received: by 10.180.189.9 with SMTP id ge9mr15009586wic.52.1380565827316; Mon, 30 Sep 2013 11:30:27 -0700 (PDT) Received: from [172.27.6.175] ([213.106.240.92]) by mx.google.com with ESMTPSA id jf2sm3544839wic.2.1969.12.31.16.00.00 (version=SSLv3 cipher=RC4-SHA bits=128/128); Mon, 30 Sep 2013 11:30:26 -0700 (PDT) Message-ID: <5249C348.9070408@gmail.com> Date: Mon, 30 Sep 2013 19:30:32 +0100 From: Matej Kosik <5764c029b688c1c0d24a2e97cd764f@gmail.com> User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12) Gecko/20130116 Icedove/10.0.12 MIME-Version: 1.0 To: caml-list X-Enigmail-Version: 1.4.1 Content-Type: multipart/mixed; boundary="------------090607000704010702030007" Subject: [Caml-list] semaphore puzzle This is a multi-part message in MIME format. --------------090607000704010702030007 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit 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. --------------090607000704010702030007 Content-Type: text/plain; name="semaphore.ml" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="semaphore.ml" 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 --------------090607000704010702030007--