123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107(* $Id$ *)classtypemtprovider=objectmethodsingle_threaded:boolmethodcreate_thread:'s't.('s->'t)->'s->threadmethodself:threadmethodyield:unit->unitmethodcreate_mutex:unit->mutexmethodcreate_condition:unit->conditionendandthread=objectmethod id:intmethod join:unit->unitmethod repr:exnendandmutex =objectmethodlock:unit->unitmethodunlock:unit->unitmethodtry_lock:unit->boolmethodrepr:exnendandcondition =objectmethod wait:mutex-> unitmethodsignal:unit->unitmethodbroadcast:unit ->unitmethodrepr:exnend(* single-threaded dummy stuff: *)exceptionDummyletstthread():thread=(objectmethod id=0methodjoin()=failwith"Netsys_oothr: join not possible in single-threaded program"methodrepr=Dummyend)letstmutex():mutex=(objectmethod lock()=()methodunlock()=()methodtry_lock()=truemethodrepr=Dummyend)letstcondition():condition=(objectmethodwait_=()methodsignal()=()methodbroadcast()=()methodrepr=Dummyend)letstprovider:mtprovider=(objectmethodsingle_threaded=truemethodcreate_thread:'s't.('s->'t)->'s->thread=fun__->failwith"Netsys_oothr: create_thread not possible in single-threaded program"methodself=stthread()methodyield()=()methodcreate_mutex()=stmutex()methodcreate_condition()=stcondition()end)letprovider=refstproviderletsingle_threaded=reffalse(* whether we know this for sure *)letst_init=reffalseletserializemutexfarg =if!single_threadedthen(farg)else(ifnot!st_initthen(single_threaded:=!provider#single_threaded;st_init:=true);mutex#lock();letr=tryfargwithe->mutex#unlock();raiseeinmutex#unlock();r)letatomic_initvarnew_val=letnew_val_opt=Some new_val inmatch!varwith|None->var:=new_val_opt;new_val|Some x->xletcompare_and_swapvarold_valuenew_value=!var==old_value&&(var:=new_value;true)