Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file primus_wandering_main.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105openCore_kernelopenBap.StdopenMonads.StdopenBap_future.StdopenBap_primus.StdincludeSelf()typet={pending:Primus.Machine.idInt.Map.t;}letstate=Primus.Machine.State.declare~uuid:"99883d0e-94b2-41a4-bce6-1e4a949fd919"~name:"wandering-scheduler"(fun_->{pending=Int.Map.empty})moduleMake(Random:sigvalgenerator:Primus.generatorend)(Machine:Primus.Machine.S)=structopenMachine.SyntaxmoduleGenerate=Primus.Generator.Make(Machine)(** a number of attempts to pick a live state before the next
draw. *)letattempts=4type'am='aMachine.tletdropit={pending=Map.removet.pendingi}(** [reschedule n s] performs [n] attempts to choose a live clone,
from the contestants. If nothing was chosen, then draws a new
party of contestants and starts again.
The algorithm is guaranteed to terminate since it is guaranteed
that there is at least one live state, called the global state.
Note, a winner - the clone that was chosen, is removed from the
draw.*)letrecreschedulent=ifn>0&¬(Map.is_emptyt.pending)thenlet(max,_)=Map.max_elt_exnt.pendinginGenerate.nextRandom.generator>>=funi->leti=imod(max+1)inmatchMap.findt.pendingiwith|None->reschedule(n-1)t|Someid->Machine.statusid>>=function|`Dead->reschedule(n-1)(dropit)|_->Machine.switchid>>|fun()->dropitelseMachine.forks()>>|funfs->{pending=Seq.foldifs~init:Int.Map.empty~f:(funicsid->Map.setcs~key:i~data:id);}letschedulet=rescheduleattemptstletstep_blk=Machine.Local.getstate>>=schedule>>=Machine.Local.putstateletinit()=Primus.Interpreter.leave_pos>>>stependletregisterenabledseed=letmoduleRandom=structletgenerator=Primus.Generator.Random.lcgseedendinletmoduleScheduler=Make(Random)inifenabledthenbegininfo"enabling the scheduler, using %d as the seed"seed;Primus.Machine.add_component(moduleScheduler)[@warning"-D"];end;Primus.Components.register_generic"wondering-scheduler"(moduleScheduler)~package:"bap"~desc:"Enables the random wonderning scheduler (experimental). The \
scheduler will pick between the states randomly."openConfig;;manpage[`S"DESCRIPTION";`P"The random wandering scheduler will pick between the states randomly.";`P"The round-robin scheduler will switch the context after each basic block."];;letenabled=flag"scheduler"~doc:"Enable the scheduler."letseed=param~doc:"random generator seed"int"seed"let()=when_ready(fun{get=(!!)}->register!!enabled!!seed)