1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162(*
* Copyright (C) Citrix Systems Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; version 2.1 only. with the special
* exception on linking described in file LICENSE.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*)typet={mutablen:int;m:Mutex.t;c:Condition.t;}letcreaten=ifn<=0theninvalid_arg(Printf.sprintf"Semaphore value must be positive, got %d"n);letm=Mutex.create()andc=Condition.create()in{n;m;c;}exceptionInconsistent_stateofstringletinconsistent_statefmt=Printf.kprintf(funmsg->raise(Inconsistent_statemsg))fmtletacquiresk=ifk<=0theninvalid_arg(Printf.sprintf"Semaphore acquisition requires a positive value, got %d"k);Mutex.locks.m;whiles.n<kdoCondition.waits.cs.m;done;ifnot(s.n>=k)theninconsistent_state"Semaphore value cannot be smaller than %d, got %d"ks.n;s.n<-s.n-k;Condition.signals.c;Mutex.unlocks.mletreleasesk=ifk<=0theninvalid_arg(Printf.sprintf"Semaphore release requires a positive value, got %d"k);Mutex.locks.m;s.n<-s.n+k;Condition.signals.c;Mutex.unlocks.mletexecute_with_weightskf=acquiresk;Xapi_stdext_pervasives.Pervasiveext.finallyf(fun()->releasesk)letexecutesf=execute_with_weights1f