package Ġcom . github . da em ont us . j af ra ĊĊ Ċ /** Ċ Ġ* Ċ Ġ* ĠMan ages Ġtermination Ġdetection Ġin Ġcurrent Ġprocess Ġusing Ġgiven Ġmess enger . Ċ Ġ* Ċ Ġ* Ċ Ġ* ĠTermin ators Ġare Ġcreated Ġeither Ġby Ġstatic Ġmethod Ġor Ġfactory . ĠThis Ġensures Ċ Ġ* Ġthat Ġappropriate Ġtermin ator Ġimplementations Ġare Ġused . Ċ Ġ* Ċ Ġ* Ċ Ġ* ĠAll Ġtermin ators Ġare Ġinitially Ġmarked Ġas Ġworking . ĠSo Ġeven Ġif Ġno Ċ Ġ* Ġmessages Ġare Ġsent / received Ġand Ġonly Ġlocal Ġwork Ġhas Ġbeen Ġperformed , Ċ Ġ* Ġyou Ġshould Ġcall Ġset Done Ġat Ġleast Ġonce . Ġ( This Ġprevents Ġ" immediate " Ġtermination Ġafter Ġcreation ) Ċ Ġ* Ċ Ġ* Ċ Ġ* ĠTermin ators Ġare Ġnot Ġre usable . ĠOnce Ġ[ waitFor Termination ][. waitFor Termination ] Ġreturns , Ċ Ġ* Ġtermin ator Ġis Ġmarked Ġas Ġfinished Ġand Ġshould Ġnot Ġbe Ġused Ġagain . Ċ Ġ*/ Ċ abstract Ġclass ĠTermin ator Ċ /** Ġpackage Ġprivate Ġconstructor Ġ- Ġnew Ġtermin ators Ġshould Ġbe Ġcreated Ġusing Ġstatic Ġfactory . Ġ Ġ*/ Ċ constructor ( protected Ġval Ġmess enger : ĠToken Messenger ) Ġ{ ĊĊĠĠĠ Ġprotected Ġvar Ġflag : ĠInt Ġ= Ġ 0 ĊĠĠĠ Ġprotected Ġvar Ġcount : ĠInt Ġ= Ġ 0 ĊĊĠĠĠ Ġprotected Ġvar Ġfinal ized : ĠBoolean Ġ= Ġfalse ĊĠĠĠ Ġvar Ġworking : ĠBoolean Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠTell Ġtermin ator Ġthat Ġlocal Ġwork Ġis Ġdone Ġand Ġhe Ġcan Ġresume Ġoperations . Ġ( i . e . Ġafter Ġmessage Ġhas Ġbeen Ġreceived Ġand Ġprocessed ) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Synchron ized Ġopen Ġfun Ġset Done () Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow If Final ized () ĊĠĠĠĠĠĠĠ Ġthrow IfNot Working () ĊĠĠĠĠĠĠĠ Ġworking Ġ= Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIndic ate Ġthat Ġmessage Ġhas Ġbeen Ġsent Ġfrom Ġthis Ġprocess . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Synchron ized Ġfun Ġmessage Sent () Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow If Final ized () ĊĠĠĠĠĠĠĠ Ġthrow IfNot Working () ĊĠĠĠĠĠĠĠ Ġcount ++ ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIndic ate Ġthat Ġmessage Ġhas Ġbeen Ġreceived Ġand Ġthis Ġprocess Ġis Ġcurrently Ġprocessing Ġit . ĊĠĠĠĠ Ġ* ĠWARNING : ĠIn Ġorder Ġfor Ġtermin ator Ġto Ġproperly Ġfinish , Ġany Ġsequence Ġof ĊĠĠĠĠ Ġ* Ġmessage Received Ġcalls Ġmust Ġend Ġwith Ġat Ġleast Ġone Ġset Done Ġcall . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Synchron ized Ġfun Ġmessage Received () Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow If Final ized () ĊĠĠĠĠĠĠĠ Ġcount -- ĊĠĠĠĠĠĠĠ Ġ// status Ġ= ĠBlack ĊĠĠĠĠĠĠĠ Ġflag Ġ= Ġ 1 ĊĠĠĠĠĠĠĠ Ġworking Ġ= Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠStart Ġtermination Ġdetection Ġprocess Ġand Ġwait Ġfor Ġsuccessful Ġtermination . ĊĠĠĠĠ Ġ* ĠTermin ator Ġcan Ġreceive Ġmessages Ġeven Ġbefore Ġthis Ġcall Ġand Ġwill Ġpreserve Ġthem Ġas Ġinternal Ġstate , ĊĠĠĠĠ Ġ* Ġbut Ġonly Ġafter Ġthis Ġcall Ġwill Ġit Ġstart Ġto Ġexchange Ġinfo Ġwith Ġother Ġprocesses . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun ĠwaitFor Termination () Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow If Final ized () ĊĠĠĠĠĠĠĠ Ġtermination Loop () ĊĠĠĠĠĠĠĠ Ġfinal ized Ġ= Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġmethod Ġactually Ġdetect s Ġthe Ġtermination Ġby Ġex changing Ġinfo Ġwith Ġother Ġprocesses Ġuntil Ġfix Ġpoint Ġis Ġreached . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprotected Ġabstract Ġfun Ġtermination Loop () ĊĊĠĠĠ Ġprivate Ġfun Ġthrow If Final ized (): ĠUnit Ġ= Ġif Ġ( final ized ) Ġthrow ĠIllegalStateException (" This Ġtermin ator Ġhas Ġbeen Ġalready Ġfinal ized .") Ġelse Ġ{} ĊĠĠĠ Ġprivate Ġfun Ġthrow IfNot Working (): ĠUnit Ġ= Ġif Ġ(! working ) Ġthrow ĠIllegalStateException (" This Ġtermin ator Ġis Ġnot Ġworking .") Ġelse Ġ{} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠCreate Ġnew Ġtermin ator Ġaccording Ġto Ġgiven Ġmess enger . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġmess enger ĠMess enger Ġthat Ġshould Ġbe Ġused Ġfor Ġcommunication . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return ĠUs able Ġtermin ator Ġinstance . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġcreate New ( messenger : ĠToken Messenger ): ĠTermin ator Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( messenger . is Master ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠMaster Termin ator ( messenger ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠSl ave Termin ator ( messenger ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCreates Ġnew Ġtermin ators Ġbased Ġon Ġgiven Ġtoken Ġpassing Ġinterface . ĊĊĠĠĠĠ Ġ* Ġ( Great Ġfor Ġmulti - round Ġalgorithms , Ġwhere Ġeach Ġround Ġuses ĊĠĠĠĠ Ġ* Ġsame Ġmess enger , Ġbut Ġnew Ġtermin ator .) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġclass ĠFactory ( private Ġval Ġmess enger : ĠToken Messenger ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġfun Ġcreate New (): ĠTermin ator Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠTermin ator . createNew ( messenger ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ } Ċ Ċ /** Ċ Ġ* ĠTermin ator Ġrunning Ġon Ġa Ġslave Ġmachine . Ċ Ġ* ĠImplements ĠS af ra 's Ġalgorithm ( http :// fmt . cs . ut w ente . nl / courses / cd p / slides / cd p - 8 - mpi - 2 - 4 up . pdf ) Ġfor Ġtermination Ġdetection . Ċ Ġ*/ Ċ private Ġclass ĠSl ave Termin ator ( m : ĠToken Messenger ) Ġ: ĠTermin ator ( m ) Ġ{ ĊĊĠĠĠ Ġprivate Ġvar Ġpending Token : ĠToken ? Ġ= Ġnull ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġprivate Ġfun Ġprocess Token ( token : ĠToken ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// working Ġis Ġfalse Ġhere ĊĠĠĠĠĠĠĠ Ġif Ġ( token Ġ!= Ġnull ) Ġ{ Ġ// node Ġis Ġidle Ġand Ġhas Ġun processed Ġtokens ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// non Ġblocking Ġsend Ġ( so Ġthat Ġwe Ġdo Ġnot Ġend Ġup Ġstuck Ġin Ġsynchronized Ġsection ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmess enger . send To Next Async ( Token ( Math . min ( token . flag Ġ+ Ġflag , Ġ 1 ), Ġtoken . count Ġ+ Ġcount )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// status Ġ= ĠWhite ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflag Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġtermination Loop () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// wait Ġfor Ġtoken Ġfrom Ġmaster ĊĠĠĠĠĠĠĠ Ġvar Ġtoken Ġ= Ġmess enger . receive From Previous () ĊĠĠĠĠĠĠĠ Ġwhile Ġ( token . flag Ġ< Ġ 2 ) Ġ{ ĠĠ Ġ// while Ġthis Ġis Ġnot Ġa Ġterminating Ġtoken ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized Ġ( this @ Slave Termin ator ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( working ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// if Ġnode Ġis Ġactive , Ġsave Ġtoken Ġfor Ġlater ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpending Token Ġ= Ġtoken ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// else Ġpass Ġtoken Ġto Ġnext Ġnode Ġright Ġaway ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess Token ( token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtoken Ġ= Ġmess enger . receive From Previous () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// termination Ġmessage Ġhas Ġbeen Ġreceived Ġ- Ġwe Ġpass Ġthis Ġto Ġnext Ġnode Ġand Ġfinish Ġourselves ĊĠĠĠĠĠĠĠ Ġmess enger . send To Next Async ( token ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġoverride Ġfun Ġset Done () Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . set Done () ĊĠĠĠĠĠĠĠ Ġprocess Token ( pending Token ) ĊĠĠĠĠĠĠĠ Ġpending Token Ġ= Ġnull ĊĠĠĠ Ġ} Ċ Ċ } Ċ Ċ /** Ċ Ġ* ĠTermin ator Ġrunning Ġon Ġa Ġmaster Ġmachine . Ċ Ġ* ĠImplements ĠS af ra 's Ġalgorithm ( http :// fmt . cs . ut w ente . nl / courses / cd p / slides / cd p - 8 - mpi - 2 - 4 up . pdf ) Ġfor Ġtermination Ġdetection . Ċ Ġ*/ Ċ private Ġclass ĠMaster Termin ator ( m : ĠToken Messenger ) Ġ: ĠTermin ator ( m ) Ġ{ ĊĊĠĠĠ Ġprivate Ġvar Ġwaiting For Token Ġ= Ġfalse ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġprivate Ġfun Ġinit Probe () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// status Ġ= ĠWhite ĊĠĠĠĠĠĠĠ Ġflag Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġwaiting For Token Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġmess enger . send To Next Async ( Token ( 0 , Ġ 0 )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġoverride Ġfun Ġset Done () Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . set Done () ĊĠĠĠĠĠĠĠ Ġif Ġ(! waiting For Token ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// at Ġthis Ġpoint , Ġworking Ġis Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// if Ġnode Ġis Ġidle Ġand Ġno Ġtoken Ġis Ġalready Ġin Ġthe Ġsystem ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Note : ĠIt Ġis Ġok Ġto Ġsend Ġa Ġprobe Ġeven Ġwhen Ġmain Ġtask Ġhas Ġnot Ġfinished Ġyet , Ġbecause ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// probe Ġwill Ġreturn Ġonly Ġafter Ġall Ġmain Ġtasks Ġare Ġfinished Ġand Ġif Ġany Ġmessages ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// are Ġsent / received Ġduring Ġthis Ġperiod , Ġflag / count Ġwill Ġreflect Ġthis Ġand Ġprocess Ġwon 't Ġterminate ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinit Probe () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġvar Ġlast Ġ= ĠInt . MIN _ VALUE ĊĊĠĠĠ Ġoverride Ġfun Ġtermination Loop () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// we Ġdon 't Ġtry Ġto Ġsend Ġa Ġprobe Ġhere , Ġbecause Ġset Done ĊĠĠĠĠĠĠĠ Ġ// has Ġto Ġbe Ġcalled Ġat Ġleast Ġonce , Ġtherefore Ġiniti ating Ġprobe ĊĊĠĠĠĠĠĠĠ Ġ// wait Ġfor Ġtoken Ġto Ġgo Ġthrough Ġall Ġother Ġprocesses . ĊĠĠĠĠĠĠĠ Ġvar Ġtoken Ġ= Ġmess enger . receive From Previous () ĊĠĠĠĠĠĠĠ Ġwhile Ġ( token . flag Ġ< Ġ 2 ) Ġ{ Ġ Ġ// while Ġthis Ġis Ġnot Ġa Ġtermination Ġtoken ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized Ġ( this ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! waiting For Token ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// if Ġwe Ġare Ġnot Ġexpecting Ġa Ġtoken , Ġsomething Ġis Ġreally Ġwrong ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" Master Ġreceived Ġa Ġtoken Ġhe Ġwas Ġnot Ġwaiting Ġfor !") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwaiting For Token Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( flag Ġ== Ġ 0 Ġ&& Ġtoken . flag Ġ== Ġ 0 Ġ&& Ġtoken . count Ġ+ Ġcount Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// if Ġtermination Ġcriteria Ġare Ġmet , Ġfinish Ġthis Ġwhole Ġthing ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Sl aves Ġshould Ġpass Ġthis Ġand Ġreturn Ġit Ġto Ġus Ġ( that Ġwill Ġterminate Ġthis Ġwhile Ġloop ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmess enger . send To Next Async ( Token ( 2 , Ġ 0 )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! working ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// if Ġnode Ġis Ġidle , Ġjust Ġgo Ġfor Ġanother Ġround ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinit Probe () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ// if Ġwe Ġare Ġworking , Ġjust Ġwait Ġ- Ġset Done Ġwill Ġinit Ġthe Ġprobe ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( last Ġ== Ġtoken . count ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ Ġthrow ĠIllegalStateException (" aaaa ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlast Ġ= Ġtoken . count ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// wait Ġfor Ġanother Ġtoken ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtoken Ġ= Ġmess enger . receive From Previous () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ