forked from LeenkxTeam/LNXSDK
		
	Update Files
This commit is contained in:
		
							
								
								
									
										63
									
								
								Kha/Tools/linux_arm64/std/sys/thread/Deque.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								Kha/Tools/linux_arm64/std/sys/thread/Deque.hx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | ||||
| /* | ||||
|  * Copyright (C)2005-2019 Haxe Foundation | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a | ||||
|  * copy of this software and associated documentation files (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 THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS 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. | ||||
|  */ | ||||
|  | ||||
| package sys.thread; | ||||
|  | ||||
| #if (!target.threaded) | ||||
| #error "This class is not available on this target" | ||||
| #end | ||||
|  | ||||
| /** | ||||
| 	A Deque is a double-ended queue with a `pop` method that can block until | ||||
| 	an element is available. It is commonly used to synchronize threads. | ||||
|  */ | ||||
| @:coreApi extern class Deque<T> { | ||||
| 	/** | ||||
| 		Create a new Deque instance which is initially empty. | ||||
| 	**/ | ||||
| 	function new():Void; | ||||
|  | ||||
| 	/** | ||||
| 		Adds an element at the end of `this` Deque. | ||||
|  | ||||
| 		(Java,Jvm): throws `java.lang.NullPointerException` if `i` is `null`. | ||||
| 	**/ | ||||
| 	function add(i:T):Void; | ||||
|  | ||||
| 	/** | ||||
| 		Adds an element at the front of `this` Deque. | ||||
|  | ||||
| 		(Java,Jvm): throws `java.lang.NullPointerException` if `i` is `null`. | ||||
| 	**/ | ||||
| 	function push(i:T):Void; | ||||
|  | ||||
| 	/** | ||||
| 		Tries to retrieve an element from the front of `this` Deque. | ||||
|  | ||||
| 		If an element is available, it is removed from the queue and returned. | ||||
|  | ||||
| 		If no element is available and `block` is `false`, `null` is returned. | ||||
|  | ||||
| 		Otherwise, execution blocks until an element is available and returns it. | ||||
| 	**/ | ||||
| 	function pop(block:Bool):Null<T>; | ||||
| } | ||||
							
								
								
									
										198
									
								
								Kha/Tools/linux_arm64/std/sys/thread/ElasticThreadPool.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								Kha/Tools/linux_arm64/std/sys/thread/ElasticThreadPool.hx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,198 @@ | ||||
| /* | ||||
|  * Copyright (C)2005-2019 Haxe Foundation | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a | ||||
|  * copy of this software and associated documentation files (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 THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS 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. | ||||
|  */ | ||||
|  | ||||
| package sys.thread; | ||||
|  | ||||
| #if (!target.threaded) | ||||
| #error "This class is not available on this target" | ||||
| #end | ||||
|  | ||||
| import haxe.Exception; | ||||
|  | ||||
| /** | ||||
| 	Thread pool with a varying amount of threads. | ||||
|  | ||||
| 	A new thread is spawned every time a task is submitted while all existing | ||||
| 	threads are busy. | ||||
| **/ | ||||
| @:coreApi | ||||
| class ElasticThreadPool implements IThreadPool { | ||||
| 	/* Amount of alive threads in this pool. */ | ||||
| 	public var threadsCount(get,null):Int; | ||||
| 	/* Maximum amount of threads in this pool. */ | ||||
| 	public var maxThreadsCount:Int; | ||||
| 	/** Indicates if `shutdown` method of this pool has been called. */ | ||||
| 	public var isShutdown(get,never):Bool; | ||||
| 	var _isShutdown = false; | ||||
| 	function get_isShutdown():Bool return _isShutdown; | ||||
|  | ||||
| 	final pool:Array<Worker> = []; | ||||
| 	final queue = new Deque<()->Void>(); | ||||
| 	final mutex = new Mutex(); | ||||
| 	final threadTimeout:Float; | ||||
|  | ||||
| 	/** | ||||
| 		Create a new thread pool with `threadsCount` threads. | ||||
|  | ||||
| 		If a worker thread does not receive a task for `threadTimeout` seconds it | ||||
| 		is terminated. | ||||
| 	**/ | ||||
| 	public function new(maxThreadsCount:Int, threadTimeout:Float = 60):Void { | ||||
| 		if(maxThreadsCount < 1) | ||||
| 			throw new ThreadPoolException('ElasticThreadPool needs maxThreadsCount to be at least 1.'); | ||||
| 		this.maxThreadsCount = maxThreadsCount; | ||||
| 		this.threadTimeout = threadTimeout; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 		Submit a task to run in a thread. | ||||
|  | ||||
| 		Throws an exception if the pool is shut down. | ||||
| 	**/ | ||||
| 	public function run(task:()->Void):Void { | ||||
| 		if(_isShutdown) | ||||
| 			throw new ThreadPoolException('Task is rejected. Thread pool is shut down.'); | ||||
| 		if(task == null) | ||||
| 			throw new ThreadPoolException('Task to run must not be null.'); | ||||
|  | ||||
| 		mutex.acquire(); | ||||
| 		var submitted = false; | ||||
| 		var deadWorker = null; | ||||
| 		for(worker in pool) { | ||||
| 			if(deadWorker == null && worker.dead) { | ||||
| 				deadWorker = worker; | ||||
| 			} | ||||
| 			if(worker.task == null) { | ||||
| 				submitted = true; | ||||
| 				worker.wakeup(task); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		if(!submitted) { | ||||
| 			if(deadWorker != null) { | ||||
| 				deadWorker.wakeup(task); | ||||
| 			} else if(pool.length < maxThreadsCount) { | ||||
| 				var worker = new Worker(queue, threadTimeout); | ||||
| 				pool.push(worker); | ||||
| 				worker.wakeup(task); | ||||
| 			} else { | ||||
| 				queue.add(task); | ||||
| 			} | ||||
| 		} | ||||
| 		mutex.release(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 		Initiates a shutdown. | ||||
| 		All previousely submitted tasks will be executed, but no new tasks will | ||||
| 		be accepted. | ||||
|  | ||||
| 		Multiple calls to this method have no effect. | ||||
| 	**/ | ||||
| 	public function shutdown():Void { | ||||
| 		if(_isShutdown) return; | ||||
| 		mutex.acquire(); | ||||
| 		_isShutdown = true; | ||||
| 		for(worker in pool) { | ||||
| 			worker.shutdown(); | ||||
| 		} | ||||
| 		mutex.release(); | ||||
| 	} | ||||
|  | ||||
| 	function get_threadsCount():Int { | ||||
| 		var result = 0; | ||||
| 		for(worker in pool) | ||||
| 			if(!worker.dead) | ||||
| 				++result; | ||||
| 		return result; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| private class Worker { | ||||
| 	public var task(default,null):Null<()->Void>; | ||||
| 	public var dead(default,null) = false; | ||||
|  | ||||
| 	final deathMutex = new Mutex(); | ||||
| 	final waiter = new Lock(); | ||||
| 	final queue:Deque<()->Void>; | ||||
| 	final timeout:Float; | ||||
| 	var thread:Thread; | ||||
| 	var isShutdown = false; | ||||
|  | ||||
| 	public function new(queue:Deque<()->Void>, timeout:Float) { | ||||
| 		this.queue = queue; | ||||
| 		this.timeout = timeout; | ||||
| 		start(); | ||||
| 	} | ||||
|  | ||||
| 	public function wakeup(task:()->Void) { | ||||
| 		deathMutex.acquire(); | ||||
| 		if(dead) | ||||
| 			start(); | ||||
| 		this.task = task; | ||||
| 		waiter.release(); | ||||
| 		deathMutex.release(); | ||||
| 	} | ||||
|  | ||||
| 	public function shutdown() { | ||||
| 		isShutdown = true; | ||||
| 		waiter.release(); | ||||
| 	} | ||||
|  | ||||
| 	function start() { | ||||
| 		dead = false; | ||||
| 		thread = Thread.create(loop); | ||||
| 	} | ||||
|  | ||||
| 	function loop() { | ||||
| 		try { | ||||
| 			while(waiter.wait(timeout)) { | ||||
| 				switch task { | ||||
| 					case null: | ||||
| 						if(isShutdown) | ||||
| 							break; | ||||
| 					case fn: | ||||
| 						fn(); | ||||
| 						//if more tasks were added while all threads were busy | ||||
| 						while(true) { | ||||
| 							switch queue.pop(false) { | ||||
| 								case null: break; | ||||
| 								case fn: fn(); | ||||
| 							} | ||||
| 						} | ||||
| 						task = null; | ||||
| 				} | ||||
| 			} | ||||
| 			deathMutex.acquire(); | ||||
| 			//in case a task was submitted right after the lock timed out | ||||
| 			if(task != null) | ||||
| 				start() | ||||
| 			else | ||||
| 				dead = true; | ||||
| 			deathMutex.release(); | ||||
| 		} catch(e) { | ||||
| 			task = null; | ||||
| 			start(); | ||||
| 			throw e; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										275
									
								
								Kha/Tools/linux_arm64/std/sys/thread/EventLoop.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										275
									
								
								Kha/Tools/linux_arm64/std/sys/thread/EventLoop.hx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,275 @@ | ||||
| package sys.thread; | ||||
|  | ||||
| /** | ||||
| 	When an event loop has an available event to execute. | ||||
| **/ | ||||
| enum NextEventTime { | ||||
| 	/** There's already an event waiting to be executed */ | ||||
| 	Now; | ||||
| 	/** No new events are expected. */ | ||||
| 	Never; | ||||
| 	/** | ||||
| 		An event is expected to arrive at any time. | ||||
| 		If `time` is specified, then the event will be ready at that time for sure. | ||||
| 	*/ | ||||
| 	AnyTime(time:Null<Float>); | ||||
| 	/** An event is expected to be ready for execution at `time`. */ | ||||
| 	At(time:Float); | ||||
| } | ||||
|  | ||||
| /** | ||||
| 	An event loop implementation used for `sys.thread.Thread` | ||||
| **/ | ||||
| @:coreApi | ||||
| class EventLoop { | ||||
| 	final mutex = new Mutex(); | ||||
| 	final oneTimeEvents = new Array<Null<()->Void>>(); | ||||
| 	var oneTimeEventsIdx = 0; | ||||
| 	final waitLock = new Lock(); | ||||
| 	var promisedEventsCount = 0; | ||||
| 	var regularEvents:Null<RegularEvent>; | ||||
|  | ||||
| 	public function new():Void {} | ||||
|  | ||||
| 	/** | ||||
| 		Schedule event for execution every `intervalMs` milliseconds in current loop. | ||||
| 	**/ | ||||
| 	public function repeat(event:()->Void, intervalMs:Int):EventHandler { | ||||
| 		mutex.acquire(); | ||||
| 		var interval = 0.001 * intervalMs; | ||||
| 		var event = new RegularEvent(event, Sys.time() + interval, interval); | ||||
| 		inline insertEventByTime(event); | ||||
| 		waitLock.release(); | ||||
| 		mutex.release(); | ||||
| 		return event; | ||||
| 	} | ||||
|  | ||||
| 	function insertEventByTime(event:RegularEvent):Void { | ||||
| 		switch regularEvents { | ||||
| 			case null: | ||||
| 				regularEvents = event; | ||||
| 			case current: | ||||
| 				var previous = null; | ||||
| 				while(true) { | ||||
| 					if(current == null) { | ||||
| 						previous.next = event; | ||||
| 						event.previous = previous; | ||||
| 						break; | ||||
| 					} else if(event.nextRunTime < current.nextRunTime) { | ||||
| 						event.next = current; | ||||
| 						current.previous = event; | ||||
| 						switch previous { | ||||
| 							case null: | ||||
| 								regularEvents = event; | ||||
| 								case _: | ||||
| 								event.previous = previous; | ||||
| 								previous.next = event; | ||||
| 								current.previous = event; | ||||
| 						} | ||||
| 						break; | ||||
| 					} else { | ||||
| 						previous = current; | ||||
| 						current = current.next; | ||||
| 					} | ||||
| 				} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 		Prevent execution of a previously scheduled event in current loop. | ||||
| 	**/ | ||||
| 	public function cancel(eventHandler:EventHandler):Void { | ||||
| 		mutex.acquire(); | ||||
| 		var event:RegularEvent = eventHandler; | ||||
| 		event.cancelled = true; | ||||
| 		if(regularEvents == event) { | ||||
| 			regularEvents = event.next; | ||||
| 		} | ||||
| 		switch event.next { | ||||
| 			case null: | ||||
| 			case e: e.previous = event.previous; | ||||
| 		} | ||||
| 		switch event.previous { | ||||
| 			case null: | ||||
| 			case e: e.next = event.next; | ||||
| 		} | ||||
| 		mutex.release(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 		Notify this loop about an upcoming event. | ||||
| 		This makes the thread to stay alive and wait for as many events as many times | ||||
| 		`.promise()` was called. These events should be added via `.runPromised()` | ||||
| 	**/ | ||||
| 	public function promise():Void { | ||||
| 		mutex.acquire(); | ||||
| 		++promisedEventsCount; | ||||
| 		mutex.release(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 		Execute `event` as soon as possible. | ||||
| 	**/ | ||||
| 	public function run(event:()->Void):Void { | ||||
| 		mutex.acquire(); | ||||
| 		oneTimeEvents[oneTimeEventsIdx++] = event; | ||||
| 		waitLock.release(); | ||||
| 		mutex.release(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 		Add previously promised `event` for execution. | ||||
| 	**/ | ||||
| 	public function runPromised(event:()->Void):Void { | ||||
| 		mutex.acquire(); | ||||
| 		oneTimeEvents[oneTimeEventsIdx++] = event; | ||||
| 		--promisedEventsCount; | ||||
| 		waitLock.release(); | ||||
| 		mutex.release(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 		Executes all pending events. | ||||
|  | ||||
| 		The returned time stamps can be used with `Sys.time()` for calculations. | ||||
|  | ||||
| 		Depending on a target platform this method may be non-reentrant. It must | ||||
| 		not be called from event callbacks. | ||||
| 	**/ | ||||
| 	public function progress():NextEventTime { | ||||
| 		return switch __progress(Sys.time(), [], []) { | ||||
| 			case {nextEventAt:-2}: Now; | ||||
| 			case {nextEventAt:-1, anyTime:false}: Never; | ||||
| 			case {nextEventAt:-1, anyTime:true}: AnyTime(null); | ||||
| 			case {nextEventAt:time, anyTime:true}: AnyTime(time); | ||||
| 			case {nextEventAt:time, anyTime:false}: At(time); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 		Blocks until a new event is added or `timeout` (in seconds) to expires. | ||||
|  | ||||
| 		Depending on a target platform this method may also automatically execute arriving | ||||
| 		events while waiting. However if any event is executed it will stop waiting. | ||||
|  | ||||
| 		Returns `true` if more events are expected. | ||||
| 		Returns `false` if no more events expected. | ||||
|  | ||||
| 		Depending on a target platform this method may be non-reentrant. It must | ||||
| 		not be called from event callbacks. | ||||
| 	**/ | ||||
| 	public function wait(?timeout:Float):Bool { | ||||
| 		return waitLock.wait(timeout); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 		Execute all pending events. | ||||
| 		Wait and execute as many events as many times `promiseEvent()` was called. | ||||
| 		Runs until all repeating events are cancelled and no more events is expected. | ||||
|  | ||||
| 		Depending on a target platform this method may be non-reentrant. It must | ||||
| 		not be called from event callbacks. | ||||
| 	**/ | ||||
| 	public function loop():Void { | ||||
| 		var recycleRegular = []; | ||||
| 		var recycleOneTimers = []; | ||||
| 		while(true) { | ||||
| 			var r = __progress(Sys.time(), recycleRegular, recycleOneTimers); | ||||
| 			switch r { | ||||
| 				case {nextEventAt:-2}: | ||||
| 				case {nextEventAt:-1, anyTime:false}: | ||||
| 					break; | ||||
| 				case {nextEventAt:-1, anyTime:true}: | ||||
| 					waitLock.wait(); | ||||
| 				case {nextEventAt:time}: | ||||
| 					var timeout = time - Sys.time(); | ||||
| 					waitLock.wait(Math.max(0, timeout)); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 		`.progress` implementation with a reusable array for internal usage. | ||||
| 		The `nextEventAt` field of the return value denotes when the next event | ||||
| 		is expected to run: | ||||
| 		* -1 - never | ||||
| 		* -2 - now | ||||
| 		* other values - at specified time | ||||
| 	**/ | ||||
| 	inline function __progress(now:Float, recycleRegular:Array<RegularEvent>, recycleOneTimers:Array<()->Void>):{nextEventAt:Float, anyTime:Bool} { | ||||
| 		var regularsToRun = recycleRegular; | ||||
| 		var eventsToRunIdx = 0; | ||||
| 		// When the next event is expected to run | ||||
| 		var nextEventAt:Float = -1; | ||||
|  | ||||
| 		mutex.acquire(); | ||||
| 		//reset waitLock | ||||
| 		while(waitLock.wait(0.0)) {} | ||||
| 		// Collect regular events to run | ||||
| 		var current = regularEvents; | ||||
| 		while(current != null) { | ||||
| 			if(current.nextRunTime <= now) { | ||||
| 				regularsToRun[eventsToRunIdx++] = current; | ||||
| 				current.nextRunTime += current.interval; | ||||
| 				nextEventAt = -2; | ||||
| 			} else if(nextEventAt == -1 || current.nextRunTime < nextEventAt) { | ||||
| 				nextEventAt = current.nextRunTime; | ||||
| 			} | ||||
| 			current = current.next; | ||||
| 		} | ||||
| 		mutex.release(); | ||||
|  | ||||
| 		// Run regular events | ||||
| 		for(i in 0...eventsToRunIdx) { | ||||
| 			if(!regularsToRun[i].cancelled)  | ||||
| 				regularsToRun[i].run(); | ||||
| 			regularsToRun[i] = null; | ||||
| 		} | ||||
| 		eventsToRunIdx = 0; | ||||
|  | ||||
| 		var oneTimersToRun = recycleOneTimers; | ||||
| 		// Collect pending one-time events | ||||
| 		mutex.acquire(); | ||||
| 		for(i => event in oneTimeEvents) { | ||||
| 			switch event { | ||||
| 				case null: | ||||
| 					break; | ||||
| 				case _: | ||||
| 					oneTimersToRun[eventsToRunIdx++] = event; | ||||
| 					oneTimeEvents[i] = null; | ||||
| 			} | ||||
| 		} | ||||
| 		oneTimeEventsIdx = 0; | ||||
| 		var hasPromisedEvents = promisedEventsCount > 0; | ||||
| 		mutex.release(); | ||||
|  | ||||
| 		//run events | ||||
| 		for(i in 0...eventsToRunIdx) { | ||||
| 			oneTimersToRun[i](); | ||||
| 			oneTimersToRun[i] = null; | ||||
| 		} | ||||
|  | ||||
| 		// Some events were executed. They could add new events to run. | ||||
| 		if(eventsToRunIdx > 0) { | ||||
| 			nextEventAt = -2; | ||||
| 		} | ||||
| 		return {nextEventAt:nextEventAt, anyTime:hasPromisedEvents} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| abstract EventHandler(RegularEvent) from RegularEvent to RegularEvent {} | ||||
|  | ||||
| private class RegularEvent { | ||||
| 	public var nextRunTime:Float; | ||||
| 	public final interval:Float; | ||||
| 	public final run:()->Void; | ||||
| 	public var next:Null<RegularEvent>; | ||||
| 	public var previous:Null<RegularEvent>; | ||||
| 	public var cancelled:Bool = false; | ||||
|  | ||||
| 	public function new(run:()->Void, nextRunTime:Float, interval:Float) { | ||||
| 		this.run = run; | ||||
| 		this.nextRunTime = nextRunTime; | ||||
| 		this.interval = interval; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										116
									
								
								Kha/Tools/linux_arm64/std/sys/thread/FixedThreadPool.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								Kha/Tools/linux_arm64/std/sys/thread/FixedThreadPool.hx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,116 @@ | ||||
| /* | ||||
|  * Copyright (C)2005-2019 Haxe Foundation | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a | ||||
|  * copy of this software and associated documentation files (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 THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS 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. | ||||
|  */ | ||||
|  | ||||
| package sys.thread; | ||||
|  | ||||
| #if (!target.threaded) | ||||
| #error "This class is not available on this target" | ||||
| #end | ||||
|  | ||||
| import haxe.Exception; | ||||
|  | ||||
| /** | ||||
| 	Thread pool with a constant amount of threads. | ||||
| 	Threads in the pool will exist until the pool is explicitly shut down. | ||||
| **/ | ||||
| @:coreApi | ||||
| class FixedThreadPool implements IThreadPool { | ||||
| 	/* Amount of threads in this pool. */ | ||||
| 	public var threadsCount(get,null):Int; | ||||
| 	function get_threadsCount():Int return threadsCount; | ||||
|  | ||||
| 	/** Indicates if `shutdown` method of this pool has been called. */ | ||||
| 	public var isShutdown(get,never):Bool; | ||||
| 	var _isShutdown = false; | ||||
| 	function get_isShutdown():Bool return _isShutdown; | ||||
|  | ||||
| 	final pool:Array<Worker>; | ||||
| 	final poolMutex = new Mutex(); | ||||
| 	final queue = new Deque<()->Void>(); | ||||
|  | ||||
| 	/** | ||||
| 		Create a new thread pool with `threadsCount` threads. | ||||
| 	**/ | ||||
| 	public function new(threadsCount:Int):Void { | ||||
| 		if(threadsCount < 1) | ||||
| 			throw new ThreadPoolException('FixedThreadPool needs threadsCount to be at least 1.'); | ||||
| 		this.threadsCount = threadsCount; | ||||
| 		pool = [for(i in 0...threadsCount) new Worker(queue)]; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 		Submit a task to run in a thread. | ||||
|  | ||||
| 		Throws an exception if the pool is shut down. | ||||
| 	**/ | ||||
| 	public function run(task:()->Void):Void { | ||||
| 		if(_isShutdown) | ||||
| 			throw new ThreadPoolException('Task is rejected. Thread pool is shut down.'); | ||||
| 		if(task == null) | ||||
| 			throw new ThreadPoolException('Task to run must not be null.'); | ||||
| 		queue.add(task); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 		Initiates a shutdown. | ||||
| 		All previousely submitted tasks will be executed, but no new tasks will | ||||
| 		be accepted. | ||||
|  | ||||
| 		Multiple calls to this method have no effect. | ||||
| 	**/ | ||||
| 	public function shutdown():Void { | ||||
| 		if(_isShutdown) return; | ||||
| 		_isShutdown = true; | ||||
| 		for(_ in pool) { | ||||
| 			queue.add(shutdownTask); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	static function shutdownTask():Void { | ||||
| 		throw new ShutdownException(''); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| private class ShutdownException extends Exception {} | ||||
|  | ||||
| private class Worker { | ||||
| 	var thread:Thread; | ||||
| 	final queue:Deque<Null<()->Void>>; | ||||
|  | ||||
| 	public function new(queue:Deque<Null<()->Void>>) { | ||||
| 		this.queue = queue; | ||||
| 		thread = Thread.create(loop); | ||||
| 	} | ||||
|  | ||||
| 	function loop() { | ||||
| 		try { | ||||
| 			while(true) { | ||||
| 				var task = queue.pop(true); | ||||
| 				task(); | ||||
| 			} | ||||
| 		} catch(_:ShutdownException) { | ||||
| 		} catch(e) { | ||||
| 			thread = Thread.create(loop); | ||||
| 			throw e; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										51
									
								
								Kha/Tools/linux_arm64/std/sys/thread/IThreadPool.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								Kha/Tools/linux_arm64/std/sys/thread/IThreadPool.hx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | ||||
| /* | ||||
|  * Copyright (C)2005-2019 Haxe Foundation | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a | ||||
|  * copy of this software and associated documentation files (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 THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS 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. | ||||
|  */ | ||||
|  | ||||
| package sys.thread; | ||||
|  | ||||
| /** | ||||
| 	A thread pool interface. | ||||
| **/ | ||||
| interface IThreadPool { | ||||
|  | ||||
| 	/** Amount of alive threads in this pool. */ | ||||
| 	var threadsCount(get,never):Int; | ||||
|  | ||||
| 	/** Indicates if `shutdown` method of this pool has been called. */ | ||||
| 	var isShutdown(get,never):Bool; | ||||
|  | ||||
| 	/** | ||||
| 		Submit a task to run in a thread. | ||||
|  | ||||
| 		Throws an exception if the pool is shut down. | ||||
| 	**/ | ||||
| 	function run(task:()->Void):Void; | ||||
|  | ||||
| 	/** | ||||
| 		Initiates a shutdown. | ||||
| 		All previousely submitted tasks will be executed, but no new tasks will | ||||
| 		be accepted. | ||||
|  | ||||
| 		Multiple calls to this method have no effect. | ||||
| 	**/ | ||||
| 	function shutdown():Void; | ||||
| } | ||||
							
								
								
									
										80
									
								
								Kha/Tools/linux_arm64/std/sys/thread/Lock.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								Kha/Tools/linux_arm64/std/sys/thread/Lock.hx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,80 @@ | ||||
| /* | ||||
|  * Copyright (C)2005-2019 Haxe Foundation | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a | ||||
|  * copy of this software and associated documentation files (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 THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS 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. | ||||
|  */ | ||||
|  | ||||
| package sys.thread; | ||||
|  | ||||
| #if (!target.threaded) | ||||
| #error "This class is not available on this target" | ||||
| #end | ||||
|  | ||||
| /** | ||||
| 	A Lock allows blocking execution until it has been unlocked. It keeps track | ||||
| 	of how often `release` has been called, and blocks exactly as many `wait` | ||||
| 	calls. | ||||
|  | ||||
| 	The order of the `release` and `wait` calls is irrelevant. That is, a Lock | ||||
| 	can be released before anyone waits for it. In that case, the `wait` call | ||||
| 	will execute immediately. | ||||
|  | ||||
| 	Usage example: | ||||
|  | ||||
| 	```haxe | ||||
| 	var lock = new Lock(); | ||||
| 	var elements = [1, 2, 3]; | ||||
| 	for (element in elements) { | ||||
| 		// Create one thread per element | ||||
| 		new Thread(function() { | ||||
| 			trace(element); | ||||
| 			Sys.sleep(1); | ||||
| 			// Release once per thread = 3 times | ||||
| 			lock.release(); | ||||
| 		}); | ||||
| 	} | ||||
| 	for (_ in elements) { | ||||
| 		// Wait 3 times | ||||
| 		lock.wait(); | ||||
| 	} | ||||
| 	trace("All threads finished"); | ||||
| 	``` | ||||
| **/ | ||||
| extern class Lock { | ||||
| 	/** | ||||
| 		Creates a new Lock which is initially locked. | ||||
| 	**/ | ||||
| 	function new():Void; | ||||
|  | ||||
| 	/** | ||||
| 		Waits for the lock to be released, or `timeout` (in seconds) | ||||
| 		to expire. Returns `true` if the lock is released and `false` | ||||
| 		if a time-out occurs. | ||||
| 	**/ | ||||
| 	function wait(?timeout:Float):Bool; | ||||
|  | ||||
| 	/** | ||||
| 		Releases the lock once. | ||||
|  | ||||
| 		The thread does not need to own the lock in order to release | ||||
| 		it. Each call to `release` allows exactly one call to `wait` | ||||
| 		to execute. | ||||
| 	**/ | ||||
| 	function release():Void; | ||||
| } | ||||
							
								
								
									
										59
									
								
								Kha/Tools/linux_arm64/std/sys/thread/Mutex.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								Kha/Tools/linux_arm64/std/sys/thread/Mutex.hx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | ||||
| /* | ||||
|  * Copyright (C)2005-2019 Haxe Foundation | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a | ||||
|  * copy of this software and associated documentation files (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 THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS 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. | ||||
|  */ | ||||
|  | ||||
| package sys.thread; | ||||
|  | ||||
| #if (!target.threaded) | ||||
| #error "This class is not available on this target" | ||||
| #end | ||||
|  | ||||
| /** | ||||
| 	Creates a mutex, which can be used to acquire a temporary lock | ||||
| 	to access some ressource. The main difference with a lock is | ||||
| 	that a mutex must always be released by the owner thread. | ||||
| **/ | ||||
| extern class Mutex { | ||||
| 	/** | ||||
| 		Creates a mutex. | ||||
| 	**/ | ||||
| 	function new():Void; | ||||
|  | ||||
| 	/** | ||||
| 		The current thread acquire the mutex or wait if not available. | ||||
| 		The same thread can acquire several times the same mutex but | ||||
| 		must release it as many times it has been acquired. | ||||
| 	**/ | ||||
| 	function acquire():Void; | ||||
|  | ||||
| 	/** | ||||
| 		Try to acquire the mutex, returns true if acquire or false | ||||
| 		if it's already locked by another thread. | ||||
| 	**/ | ||||
| 	function tryAcquire():Bool; | ||||
|  | ||||
| 	/** | ||||
| 		Release a mutex that has been acquired by the current thread. | ||||
| 		The behavior is undefined if the current thread does not own | ||||
| 		the mutex. | ||||
| 	**/ | ||||
| 	function release():Void; | ||||
| } | ||||
| @ -0,0 +1,9 @@ | ||||
| package sys.thread; | ||||
|  | ||||
| import haxe.Exception; | ||||
|  | ||||
| class NoEventLoopException extends Exception { | ||||
| 	public function new(msg:String = 'Event loop is not available. Refer to sys.thread.Thread.runWithEventLoop.', ?previous:Exception) { | ||||
| 		super(msg, previous); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										83
									
								
								Kha/Tools/linux_arm64/std/sys/thread/Thread.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								Kha/Tools/linux_arm64/std/sys/thread/Thread.hx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,83 @@ | ||||
| /* | ||||
|  * Copyright (C)2005-2019 Haxe Foundation | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a | ||||
|  * copy of this software and associated documentation files (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 THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS 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. | ||||
|  */ | ||||
|  | ||||
| package sys.thread; | ||||
|  | ||||
| #if (!target.threaded) | ||||
| #error "This class is not available on this target" | ||||
| #end | ||||
|  | ||||
| private typedef ThreadImpl = {}; | ||||
|  | ||||
| extern abstract Thread(ThreadImpl) from ThreadImpl { | ||||
| 	/** | ||||
| 		Event loop of this thread (if available). | ||||
|  | ||||
| 		Note that by default event loop is only available in the main thread. | ||||
| 		To setup an event loop in other threads use `sys.thread.Thread.runWithEventLoop` | ||||
| 		or create new threads with built-in event loops using `sys.thread.Thread.createWithEventLoop` | ||||
| 	**/ | ||||
| 	public var events(get,never):EventLoop; | ||||
|  | ||||
| 	/** | ||||
| 		Send a message to the thread queue. This message can be read by using `readMessage`. | ||||
| 	**/ | ||||
| 	public function sendMessage(msg:Dynamic):Void; | ||||
|  | ||||
| 	/** | ||||
| 		Returns the current thread. | ||||
| 	**/ | ||||
| 	public static function current():Thread; | ||||
|  | ||||
| 	/** | ||||
| 		Creates a new thread that will execute the `job` function, then exit. | ||||
|  | ||||
| 		This function does not setup an event loop for a new thread. | ||||
| 	**/ | ||||
| 	public static function create(job:()->Void):Thread; | ||||
|  | ||||
| 	/** | ||||
| 		Simply execute `job` if current thread already has an event loop. | ||||
|  | ||||
| 		But if current thread does not have an event loop: setup event loop, | ||||
| 		run `job` and then destroy event loop. And in this case this function | ||||
| 		does not return until no more events left to run. | ||||
| 	**/ | ||||
| 	public static function runWithEventLoop(job:()->Void):Void; | ||||
|  | ||||
| 	/** | ||||
| 		This is logically equal to `Thread.create(() -> Thread.runWithEventLoop(job));` | ||||
| 	**/ | ||||
| 	public static function createWithEventLoop(job:()->Void):Thread; | ||||
|  | ||||
| 	/** | ||||
| 		Reads a message from the thread queue. If `block` is true, the function | ||||
| 		blocks until a message is available. If `block` is false, the function | ||||
| 		returns `null` if no message is available. | ||||
| 	**/ | ||||
| 	public static function readMessage(block:Bool):Dynamic; | ||||
|  | ||||
| 	/** | ||||
| 		Run event loop of the current thread | ||||
| 	**/ | ||||
| 	private static function processEvents():Void; | ||||
| } | ||||
| @ -0,0 +1,6 @@ | ||||
| package sys.thread; | ||||
|  | ||||
| import haxe.Exception; | ||||
|  | ||||
| class ThreadPoolException extends Exception { | ||||
| } | ||||
							
								
								
									
										45
									
								
								Kha/Tools/linux_arm64/std/sys/thread/Tls.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								Kha/Tools/linux_arm64/std/sys/thread/Tls.hx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | ||||
| /* | ||||
|  * Copyright (C)2005-2019 Haxe Foundation | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a | ||||
|  * copy of this software and associated documentation files (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 THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS 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. | ||||
|  */ | ||||
|  | ||||
| package sys.thread; | ||||
|  | ||||
| #if (!target.threaded) | ||||
| #error "This class is not available on this target" | ||||
| #end | ||||
|  | ||||
| /** | ||||
| 	Creates thread local storage. | ||||
|  | ||||
| 	(hl) Warning: At the moment `Tls` does not protect the value from being | ||||
| 	garbage collected. Keep the value reachable to avoid crashes. | ||||
| **/ | ||||
| extern class Tls<T> { | ||||
| 	var value(get, set):T; | ||||
|  | ||||
| 	/** | ||||
| 		Creates thread local storage. This is placeholder that can store | ||||
| 		a value that will be different depending on the local thread. | ||||
| 		Set the tls value to `null` before exiting the thread | ||||
| 		or the memory will never be collected. | ||||
| 	**/ | ||||
| 	function new():Void; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user