| 
									
										
										
										
											2016-02-18 17:49:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-01 12:54:41 +00:00
										 |  |  | class(#pointer,#final,#limited) Process(Object) | 
					
						
							| 
									
										
										
										
											2015-10-15 14:40:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-07-24 13:25:25 +00:00
										 |  |  | 	var(#get) initialContext, currentContext, id, state. | 
					
						
							| 
									
										
										
										
											2017-09-25 15:16:19 +00:00
										 |  |  | 	var sp. | 
					
						
							|  |  |  | 	var(#get) ps_prev, ps_next, sem_wait_prev, sem_wait_next. | 
					
						
							| 
									
										
										
										
											2017-07-24 13:25:25 +00:00
										 |  |  | 	var sem, perr, perrmsg. | 
					
						
							| 
									
										
										
										
											2015-10-15 14:40:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-25 15:20:58 +00:00
										 |  |  | 	method primError { ^self.perr } | 
					
						
							| 
									
										
										
										
											2017-05-16 02:04:18 +00:00
										 |  |  | 	method primErrorMessage { ^self.perrmsg } | 
					
						
							| 
									
										
										
										
											2015-10-18 15:06:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-25 15:16:19 +00:00
										 |  |  | 	method(#primitive) sp. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-16 02:04:18 +00:00
										 |  |  | 	method(#primitive) resume. | 
					
						
							|  |  |  | 	method(#primitive) yield. | 
					
						
							| 
									
										
										
										
											2017-09-25 15:16:19 +00:00
										 |  |  | 	method(#primitive) suspend. | 
					
						
							| 
									
										
										
										
											2017-05-16 02:04:18 +00:00
										 |  |  | 	method(#primitive) _terminate. | 
					
						
							| 
									
										
										
										
											2016-07-04 15:36:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | 	method terminate | 
					
						
							| 
									
										
										
										
											2016-07-01 16:31:47 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2017-07-24 13:25:25 +00:00
										 |  |  | 		## search from the top context of the process down to intial_context and find ensure blocks and execute them. | 
					
						
							| 
									
										
										
										
											2016-07-04 15:36:10 +00:00
										 |  |  | 		## if a different process calls 'terminate' on a process, | 
					
						
							|  |  |  | 		## the ensureblock is not executed in the context of the | 
					
						
							|  |  |  | 		## process being terminated, but in the context of terminatig process. | 
					
						
							|  |  |  | 		## | 
					
						
							|  |  |  | 		## 1) process termianted by another process | 
					
						
							|  |  |  | 		##   p := [  | 
					
						
							|  |  |  | 		##       [  1 to: 10000 by: 1 do: [:ex | System logNl: i asString] ] ensure: [System logNl: 'ensured....']  | 
					
						
							|  |  |  | 		##   ] newProcess. | 
					
						
							|  |  |  | 		##   p resume. | 
					
						
							|  |  |  | 		##   p terminate. | 
					
						
							|  |  |  | 		## | 
					
						
							|  |  |  | 		## 2) process terminated by itself | 
					
						
							|  |  |  | 		##   p := [  | 
					
						
							| 
									
										
										
										
											2016-07-05 15:22:29 +00:00
										 |  |  | 		##       [ thisProcess terminate. ] ensure: [System logNl: 'ensured....']  | 
					
						
							| 
									
										
										
										
											2016-07-04 15:36:10 +00:00
										 |  |  | 		##   ] newProcess. | 
					
						
							|  |  |  | 		##   p resume. | 
					
						
							|  |  |  | 		##   p terminate. | 
					
						
							|  |  |  | 		## ---------------------------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 		## the process must be frozen first. while unwinding is performed,  | 
					
						
							|  |  |  | 		## the process must not be scheduled. | 
					
						
							|  |  |  | 		## ---------------------------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-25 15:16:19 +00:00
										 |  |  | 		##if (Processor activeProcess ~~ self) { self suspend }. | 
					
						
							|  |  |  | 		if (thisProcess ~~ self) { self suspend }. | 
					
						
							| 
									
										
										
										
											2017-07-24 13:25:25 +00:00
										 |  |  | 		self.currentContext unwindTo: self.initialContext return: nil. | 
					
						
							| 
									
										
										
										
											2016-07-01 16:31:47 +00:00
										 |  |  | 		^self _terminate | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-10-15 14:40:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | class Semaphore(Object) | 
					
						
							| 
									
										
										
										
											2016-02-18 17:49:56 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-09-21 07:56:51 +00:00
										 |  |  | 	var waiting_head  := nil, | 
					
						
							| 
									
										
										
										
											2017-04-24 04:26:03 +00:00
										 |  |  | 	    waiting_tail  := nil, | 
					
						
							| 
									
										
										
										
											2017-10-30 01:11:18 +00:00
										 |  |  | 	    count         :=   0. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var(#get,#set) heapIndex := -1. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var fireTimeSec   :=   0, | 
					
						
							| 
									
										
										
										
											2017-04-24 04:26:03 +00:00
										 |  |  | 	    fireTimeNsec  :=   0, | 
					
						
							| 
									
										
										
										
											2017-12-25 18:35:23 +00:00
										 |  |  | 	    ioIndex       := nil, | 
					
						
							| 
									
										
										
										
											2017-07-21 16:54:43 +00:00
										 |  |  | 	    ioHandle      := nil, | 
					
						
							| 
									
										
										
										
											2017-12-25 18:35:23 +00:00
										 |  |  | 	    ioType        := nil. | 
					
						
							| 
									
										
										
										
											2017-09-21 14:22:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-08 15:40:32 +00:00
										 |  |  | 	var(#get,#set) signalAction := nil. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var(#get,#set) _group := nil,  | 
					
						
							|  |  |  | 	               _grm_next := nil, | 
					
						
							|  |  |  | 	               _grm_prev := nil. | 
					
						
							| 
									
										
										
										
											2016-02-18 17:49:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-24 14:58:47 +00:00
										 |  |  | 	## ================================================================== | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 04:58:02 +00:00
										 |  |  | 	method(#primitive) signal. | 
					
						
							| 
									
										
										
										
											2017-10-05 17:14:38 +00:00
										 |  |  | 	method(#primitive) _wait. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	method wait | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		| k | | 
					
						
							|  |  |  | 		k := self _wait. | 
					
						
							|  |  |  | 		if (self.signalAction notNil) { self.signalAction value: self }. | 
					
						
							|  |  |  | 		^k | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-24 14:58:47 +00:00
										 |  |  | 	## ================================================================== | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | 	method fireTime | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-03-22 14:18:07 +00:00
										 |  |  | 		^fireTimeSec | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | 	method fireTime: anInteger | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-03-22 14:18:07 +00:00
										 |  |  | 		self.fireTimeSec := anInteger. | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | 	method youngerThan: aSemaphore | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-03-22 14:18:07 +00:00
										 |  |  | 		^self.fireTimeSec < (aSemaphore fireTime) | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-21 16:54:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	method notYoungerThan: aSemaphore | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		^self.fireTimeSec >= (aSemaphore fireTime) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-09-21 07:56:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-29 15:03:54 +00:00
										 |  |  | class Mutex(Semaphore) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	method(#class) new | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		| s | | 
					
						
							|  |  |  | 		s := super new. | 
					
						
							|  |  |  | 		s signal. | 
					
						
							|  |  |  | 		^s. | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-02 01:22:49 +00:00
										 |  |  | (* | 
					
						
							|  |  |  | TODO: how to prohibit wait and signal??? | 
					
						
							|  |  |  | 	method(#prohibited) wait. | 
					
						
							|  |  |  | 	method(#prohibited) signal. | 
					
						
							|  |  |  | *) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	method lock  { ^super wait } | 
					
						
							|  |  |  | 	method unlock { ^super signal } | 
					
						
							| 
									
										
										
										
											2017-09-29 15:03:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	method critical: block | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		self wait. | 
					
						
							|  |  |  | 		^block ensure: [ self signal ] | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-09-21 07:56:51 +00:00
										 |  |  |   | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-22 13:45:37 +00:00
										 |  |  | class SemaphoreGroup(Object) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-09-21 07:56:51 +00:00
										 |  |  | 	var waiting_head  := nil, | 
					
						
							|  |  |  | 	    waiting_tail  := nil, | 
					
						
							| 
									
										
										
										
											2017-10-08 15:40:32 +00:00
										 |  |  | 	    first_sem := nil, | 
					
						
							|  |  |  | 	    last_sem := nil, | 
					
						
							|  |  |  | 	    first_sigsem := nil, | 
					
						
							| 
									
										
										
										
											2017-10-31 07:13:22 +00:00
										 |  |  | 	    last_sigsem := nil, | 
					
						
							|  |  |  | 	    sem_io_count := 0. | 
					
						
							| 
									
										
										
										
											2017-08-22 13:45:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | (* TODO: good idea to a shortcut way to prohibit a certain method in the heirarchy chain? | 
					
						
							|  |  |  | method(#class,#prohibited) new. | 
					
						
							|  |  |  | method(#class,#prohibited) new: size. | 
					
						
							|  |  |  | method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibility: #xxxx } | 
					
						
							|  |  |  | *) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-08 15:40:32 +00:00
										 |  |  | (* | 
					
						
							| 
									
										
										
										
											2017-08-22 13:45:37 +00:00
										 |  |  | 	method(#class) new { self messageProhibited: #new } | 
					
						
							|  |  |  | 	method(#class) new: size { self messageProhibited: #new: } | 
					
						
							| 
									
										
										
										
											2017-10-08 15:40:32 +00:00
										 |  |  | *) | 
					
						
							| 
									
										
										
										
											2017-08-22 13:45:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-24 17:40:20 +00:00
										 |  |  | 	method(#primitive) addSemaphore: sem. | 
					
						
							|  |  |  | 	method(#primitive) removeSemaphore: sem. | 
					
						
							| 
									
										
										
										
											2017-10-05 17:14:38 +00:00
										 |  |  | 	method(#primitive) _wait. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	method wait | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2017-10-31 07:13:22 +00:00
										 |  |  | 		| x | | 
					
						
							|  |  |  | 		x := self _wait. | 
					
						
							| 
									
										
										
										
											2018-04-13 10:14:12 +00:00
										 |  |  | 		if (x notError) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			## TODO: is it better to check if x is an instance of Semaphore/SemaphoreGroup? | 
					
						
							|  |  |  | 			if (x signalAction notNil) { x signalAction value: x }. | 
					
						
							|  |  |  | 		}. | 
					
						
							| 
									
										
										
										
											2017-10-31 07:13:22 +00:00
										 |  |  | 		^x | 
					
						
							| 
									
										
										
										
											2017-10-05 17:14:38 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-09-26 09:01:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	method waitWithTimeout: seconds | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		| s r | | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		## create an internal semaphore for timeout notification. | 
					
						
							|  |  |  | 		s := Semaphore new.  | 
					
						
							| 
									
										
										
										
											2017-10-31 07:13:22 +00:00
										 |  |  | 		self addSemaphore: s. | 
					
						
							| 
									
										
										
										
											2017-09-26 09:01:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-16 05:21:38 +00:00
										 |  |  | 		[  | 
					
						
							| 
									
										
										
										
											2017-12-16 16:14:23 +00:00
										 |  |  | 			## arrange the processor to notify upon timeout. | 
					
						
							|  |  |  | 			System signal: s afterSecs: seconds. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-21 09:15:22 +00:00
										 |  |  | 			## wait on the semaphore group. | 
					
						
							| 
									
										
										
										
											2017-12-16 05:21:38 +00:00
										 |  |  | 			r := self wait.  | 
					
						
							| 
									
										
										
										
											2017-09-26 09:01:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-16 05:21:38 +00:00
										 |  |  | 			## if the internal semaphore has been signaled,  | 
					
						
							|  |  |  | 			## arrange to return nil to indicate timeout. | 
					
						
							| 
									
										
										
										
											2017-12-16 16:14:23 +00:00
										 |  |  | 			if (r == s) { r := nil } ## timed out | 
					
						
							|  |  |  | 			elsif (r signalAction notNil) { r signalAction value: r }. ## run the signal action block | 
					
						
							| 
									
										
										
										
											2017-12-16 05:21:38 +00:00
										 |  |  | 		] ensure: [ | 
					
						
							| 
									
										
										
										
											2017-12-16 16:14:23 +00:00
										 |  |  | 			## System<<unsignal: doesn't thrown an exception even if the semaphore s is not | 
					
						
							|  |  |  | 			## register with System<<signal:afterXXX:. otherwise, i would do like this line | 
					
						
							|  |  |  | 			## commented out. | 
					
						
							|  |  |  | 			## [ System unsignal: s ] ensure: [ self removeSemaphore: s ]. | 
					
						
							| 
									
										
										
										
											2017-09-26 09:01:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-16 05:21:38 +00:00
										 |  |  | 			System unsignal: s. | 
					
						
							| 
									
										
										
										
											2017-12-16 16:14:23 +00:00
										 |  |  | 			self removeSemaphore: s | 
					
						
							| 
									
										
										
										
											2017-12-16 05:21:38 +00:00
										 |  |  | 		]. | 
					
						
							| 
									
										
										
										
											2017-09-26 09:01:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		^r. | 
					
						
							|  |  |  | 	}  | 
					
						
							| 
									
										
										
										
											2017-08-22 13:45:37 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | class SemaphoreHeap(Object) | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-04-19 16:46:44 +00:00
										 |  |  | 	var arr, size. | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | 	method initialize | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		self.size := 0. | 
					
						
							|  |  |  | 		self.arr := Array new: 100. | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | 	method size | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		^self.size | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | 	method at: anIndex | 
					
						
							| 
									
										
										
										
											2016-03-16 10:13:03 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		^self.arr at: anIndex. | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | 	method insert: aSemaphore | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2017-08-22 13:45:37 +00:00
										 |  |  | 		| index newarr newsize | | 
					
						
							| 
									
										
										
										
											2016-03-16 14:05:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		index := self.size. | 
					
						
							| 
									
										
										
										
											2017-08-22 13:45:37 +00:00
										 |  |  | 		if (index >= (self.arr size))  | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 			newsize := (self.arr size) * 2. | 
					
						
							|  |  |  | 			newarr := Array new: newsize. | 
					
						
							|  |  |  | 			newarr copy: self.arr. | 
					
						
							|  |  |  | 			self.arr := newarr. | 
					
						
							| 
									
										
										
										
											2017-08-22 13:45:37 +00:00
										 |  |  | 		}. | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-16 14:05:34 +00:00
										 |  |  | 		self.arr at: index put: aSemaphore. | 
					
						
							|  |  |  | 		aSemaphore heapIndex: index. | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 		self.size := self.size + 1. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-16 14:05:34 +00:00
										 |  |  | 		^self siftUp: index | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | 	method popTop | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		| top | | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-16 14:05:34 +00:00
										 |  |  | 		top := self.arr at: 0. | 
					
						
							|  |  |  | 		self deleteAt: 0. | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 		^top | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | 	method updateAt: anIndex with: aSemaphore | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-03-22 14:18:07 +00:00
										 |  |  | 		| item | | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		item := self.arr at: anIndex. | 
					
						
							|  |  |  | 		item heapIndex: -1. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		self.arr at: anIndex put: aSemaphore. | 
					
						
							|  |  |  | 		aSemaphore heapIndex: anIndex. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-21 16:54:43 +00:00
										 |  |  | 		^if (aSemaphore youngerThan: item) { self siftUp: anIndex } else { self siftDown: anIndex }. | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | 	method deleteAt: anIndex | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2017-07-21 16:54:43 +00:00
										 |  |  | 		| item xitem | | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		item := self.arr at: anIndex. | 
					
						
							|  |  |  | 		item heapIndex: -1. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-16 14:05:34 +00:00
										 |  |  | 		self.size := self.size - 1. | 
					
						
							| 
									
										
										
										
											2017-07-21 16:54:43 +00:00
										 |  |  | 		if (anIndex == self.size)  | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			## the last item | 
					
						
							|  |  |  | 			self.arr at: self.size put: nil. | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			xitem := self.arr at: self.size. | 
					
						
							|  |  |  | 			self.arr at: anIndex put: xitem. | 
					
						
							|  |  |  | 			xitem heapIndex: anIndex. | 
					
						
							|  |  |  | 			self.arr at: self.size put: nil. | 
					
						
							|  |  |  | 			if (xitem youngerThan: item) { self siftUp: anIndex } else { self siftDown: anIndex }. | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | 	method parentIndex: anIndex | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-03-16 14:05:34 +00:00
										 |  |  | 		^(anIndex - 1) quo: 2 | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | 	method leftChildIndex: anIndex | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-03-16 14:05:34 +00:00
										 |  |  | 		^(anIndex * 2) + 1. | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | 	method rightChildIndex: anIndex | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-03-16 14:05:34 +00:00
										 |  |  | 		 ^(anIndex * 2) + 2. | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | 	method siftUp: anIndex | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2017-07-21 16:54:43 +00:00
										 |  |  | 		| pindex cindex par item | | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-21 16:54:43 +00:00
										 |  |  | 		if (anIndex <= 0) { ^anIndex }. | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-16 10:13:03 +00:00
										 |  |  | 		pindex := anIndex. | 
					
						
							|  |  |  | 		item := self.arr at: anIndex. | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-21 16:54:43 +00:00
										 |  |  | 		while (true) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 			cindex := pindex. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-21 16:54:43 +00:00
										 |  |  | 			if (pindex <= 0) { break }. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			pindex := self parentIndex: cindex. | 
					
						
							|  |  |  | 			par := self.arr at: pindex. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (item notYoungerThan: par)  { break }. | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-21 16:54:43 +00:00
										 |  |  | 			## item is younger than the parent.  | 
					
						
							|  |  |  | 			## move the parent down | 
					
						
							|  |  |  | 			self.arr at: cindex put: par. | 
					
						
							|  |  |  | 			par heapIndex: cindex. | 
					
						
							|  |  |  | 		}. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		## place the item as high as it can | 
					
						
							| 
									
										
										
										
											2016-03-16 10:13:03 +00:00
										 |  |  | 		self.arr at: cindex put: item. | 
					
						
							|  |  |  | 		item heapIndex: cindex. | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		^cindex | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 09:53:40 +00:00
										 |  |  | 	method siftDown: anIndex | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2017-07-21 16:54:43 +00:00
										 |  |  | 		| base capa cindex item  | 
					
						
							|  |  |  | 		  left right younger xitem | | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-16 14:05:34 +00:00
										 |  |  | 		base := self.size quo: 2. | 
					
						
							| 
									
										
										
										
											2017-07-21 16:54:43 +00:00
										 |  |  | 		if (anIndex >= base) { ^anIndex }. | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		cindex := anIndex. | 
					
						
							|  |  |  | 		item := self.arr at: cindex. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-21 16:54:43 +00:00
										 |  |  | 		while (cindex < base)  | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 			left := self leftChildIndex: cindex. | 
					
						
							|  |  |  | 			right := self rightChildIndex: cindex. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-21 16:54:43 +00:00
										 |  |  | 			younger := if ((right < self.size) and: [(self.arr at: right) youngerThan: (self.arr at: left)]) { right } else { left }. | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			xitem := self.arr at: younger. | 
					
						
							| 
									
										
										
										
											2017-07-21 16:54:43 +00:00
										 |  |  | 			if (item youngerThan: xitem)  { break }. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			self.arr at: cindex put: xitem. | 
					
						
							|  |  |  | 			xitem heapIndex: cindex. | 
					
						
							|  |  |  | 			cindex := younger. | 
					
						
							|  |  |  | 		}. | 
					
						
							| 
									
										
										
										
											2016-03-16 02:27:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		self.arr at: cindex put: item. | 
					
						
							|  |  |  | 		item heapIndex: cindex. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		^cindex | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-02-18 17:49:56 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-01 12:54:41 +00:00
										 |  |  | class(#final,#limited) ProcessScheduler(Object) | 
					
						
							| 
									
										
										
										
											2015-10-15 14:40:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-08-20 14:43:34 +00:00
										 |  |  | 	var(#get) active, should_exit := false, total_count := 0. | 
					
						
							| 
									
										
										
										
											2017-07-25 15:26:04 +00:00
										 |  |  | 	var(#get) runnable_count := 0. | 
					
						
							| 
									
										
										
										
											2017-07-24 13:25:25 +00:00
										 |  |  | 	var runnable_head, runnable_tail. | 
					
						
							| 
									
										
										
										
											2017-07-25 15:26:04 +00:00
										 |  |  | 	var(#get) suspended_count := 0. | 
					
						
							| 
									
										
										
										
											2017-07-24 13:25:25 +00:00
										 |  |  | 	var suspended_head, suspended_tail. | 
					
						
							| 
									
										
										
										
											2015-10-15 14:40:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-31 16:46:52 +00:00
										 |  |  | 	method activeProcess { ^self.active } | 
					
						
							|  |  |  | 	method resume: aProcess { ^aProcess resume } | 
					
						
							| 
									
										
										
										
											2015-10-15 14:40:08 +00:00
										 |  |  | } |