123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159(**************************************************************************)(* The OUnit library *)(* *)(* Copyright (C) 2002-2008 Maas-Maarten Zeeman. *)(* Copyright (C) 2010 OCamlCore SARL *)(* Copyright (C) 2013 Sylvain Le Gall *)(* *)(* The package OUnit is copyright by Maas-Maarten Zeeman, OCamlCore SARL *)(* and Sylvain Le Gall. *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining *)(* a copy of this document and the OUnit software ("the Software"), to *)(* deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, *)(* sublicense, and/or sell copies of the Software, and to permit persons *)(* to whom the Software is furnished to do so, subject to the following *)(* conditions: *)(* *)(* The above copyright notice and this permission notice shall be *)(* included in all copies or substantial portions of the Software. *)(* *)(* The Software is provided ``as is'', without warranty of any kind, *)(* express or implied, including but not limited to the warranties of *)(* merchantability, fitness for a particular purpose and noninfringement. *)(* In no event shall Maas-Maarten Zeeman be liable for any claim, damages *)(* or other liability, whether in an action of contract, tort or *)(* otherwise, arising from, out of or in connection with the Software or *)(* the use or other dealings in the software. *)(* *)(* See LICENSE.txt for details. *)(**************************************************************************)exceptionLock_failuretypescope=ScopeGlobal|ScopeProcesstype'ashared_noscope={lock:'a->unit;unlock:'a->unit;try_lock:'a->bool;}typeshared={global:intshared_noscope;process:intshared_noscope;}letget_scopedshared=function|ScopeGlobal->shared.global|ScopeProcess->shared.process(* Global variable that need to be set for threads. *)letmutex_create=ref(fun()->letr=reffalseinlettry_lock()=if!rthenbeginfalseendelsebeginr:=true;trueendinletlock()=ifnot(try_lock())thenraiseLock_failureinletunlock()=r:=falsein{lock=lock;try_lock=try_lock;unlock=unlock;})moduleMutex=structtypet=int*scopeletcreatescope=(Oo.id(objectend),scope)letlockshared(id,scope)=(get_scopedsharedscope).lockidlettry_lockshared(id,scope)=(get_scopedsharedscope).try_lockidletunlockshared(id,scope)=(get_scopedsharedscope).unlockidletwith_locksharedmutexf=tryletres=locksharedmutex;f()inunlocksharedmutex;reswithe->unlocksharedmutex;raiseeend(* A simple shared_noscope that works only for 1 process. *)letnoscope_create()=letstate=Hashtbl.create13inletstate_mutex=!mutex_create()inletget_mutexid=letmutex=state_mutex.lock();tryHashtbl.findstateidwithNot_found->letmutex=!mutex_create()inHashtbl.addstateidmutex;mutexinstate_mutex.unlock();mutexinlettry_lockid=(get_mutexid).try_lock()inletlockid=(get_mutexid).lock()inletunlockid=(get_mutexid).unlock()in{lock=lock;unlock=unlock;try_lock=try_lock;}(* Create a shared, for 1 process. *)letcreate()=letscoped=noscope_create()in{global=scoped;process=scoped;}