ソースを参照

[std] Move target.vm.Thread (and friends) to sys.thread.Thread (#7999)

* [std] move all thread classes to sys.thread

* [neko] add @:coreApi

* [cpp] add @:coreApi

* [java] add @:coreApi

* [std] purge redundant documentation

* [std] document Deque and Lock

* [tests] fix java.vm leftovers

* [std] add deprecation typedefs

* [std] fix Tls

* [std] fix Deque

* [typer] error if we access sys.thread on non-threaded target

* [std] nobody saw that
Simon Krajewski 6 年 前
コミット
320fff2969
56 ファイル変更1295 行追加834 行削除
  1. 2 0
      extra/ImportAll.hx
  2. 1 0
      src/context/common.ml
  3. 5 5
      src/macro/eval/evalHash.ml
  4. 16 16
      src/macro/eval/evalStdLib.ml
  5. 1 0
      src/typing/typeload.ml
  6. 40 0
      std/cpp/_std/sys/thread/Deque.hx
  7. 37 0
      std/cpp/_std/sys/thread/Lock.hx
  8. 41 0
      std/cpp/_std/sys/thread/Mutex.hx
  9. 56 0
      std/cpp/_std/sys/thread/Thread.hx
  10. 45 0
      std/cpp/_std/sys/thread/Tls.hx
  11. 1 17
      std/cpp/vm/Deque.hx
  12. 1 14
      std/cpp/vm/Lock.hx
  13. 1 17
      std/cpp/vm/Mutex.hx
  14. 1 47
      std/cpp/vm/Thread.hx
  15. 1 21
      std/cpp/vm/Tls.hx
  16. 1 1
      std/eval/_std/sys/thread/Thread.hx
  17. 0 8
      std/eval/vm/Deque.hx
  18. 0 7
      std/eval/vm/Lock.hx
  19. 0 8
      std/eval/vm/Mutex.hx
  20. 0 6
      std/eval/vm/Tls.hx
  21. 6 6
      std/haxe/EntryPoint.hx
  22. 4 4
      std/haxe/io/FPHelper.hx
  23. 1 1
      std/hl/_std/sys/thread/Deque.hx
  24. 7 7
      std/hl/_std/sys/thread/Mutex.hx
  25. 1 1
      std/hl/_std/sys/thread/Thread.hx
  26. 3 3
      std/hl/_std/sys/thread/Tls.hx
  27. 92 0
      std/java/_std/sys/thread/Deque.hx
  28. 95 0
      std/java/_std/sys/thread/Lock.hx
  29. 49 0
      std/java/_std/sys/thread/Mutex.hx
  30. 112 0
      std/java/_std/sys/thread/Thread.hx
  31. 46 0
      std/java/_std/sys/thread/Tls.hx
  32. 2 72
      std/java/vm/Deque.hx
  33. 2 83
      std/java/vm/Lock.hx
  34. 2 40
      std/java/vm/Mutex.hx
  35. 2 89
      std/java/vm/Thread.hx
  36. 2 26
      std/java/vm/Tls.hx
  37. 48 0
      std/neko/_std/sys/thread/Deque.hx
  38. 43 0
      std/neko/_std/sys/thread/Lock.hx
  39. 48 0
      std/neko/_std/sys/thread/Mutex.hx
  40. 122 0
      std/neko/_std/sys/thread/Thread.hx
  41. 46 0
      std/neko/_std/sys/thread/Tls.hx
  42. 1 40
      std/neko/vm/Deque.hx
  43. 1 32
      std/neko/vm/Lock.hx
  44. 1 46
      std/neko/vm/Mutex.hx
  45. 1 113
      std/neko/vm/Thread.hx
  46. 1 37
      std/neko/vm/Tls.hx
  47. 59 0
      std/sys/thread/Deque.hx
  48. 80 0
      std/sys/thread/Lock.hx
  49. 59 0
      std/sys/thread/Mutex.hx
  50. 50 0
      std/sys/thread/Thread.hx
  51. 42 0
      std/sys/thread/Tls.hx
  52. 5 31
      tests/threads/src/import.hx
  53. 5 25
      tests/unit/src/unit/TestThreads.hx
  54. 3 3
      tests/unit/src/unit/issues/Issue3084.hx
  55. 2 6
      tests/unit/src/unit/issues/Issue3767.hx
  56. 2 2
      tests/unit/src/unit/issues/Issue4878.hx

+ 2 - 0
extra/ImportAll.hx

@@ -52,6 +52,8 @@ class ImportAll {
 			return;
 		case "sys":
 			if(!isSysTarget()) return;
+		case "sys.thread":
+			if ( !Context.defined("target.threaded") ) return;
 		case "java":
 			if( !Context.defined("java") ) return;
 		case "cs":

+ 1 - 0
src/context/common.ml

@@ -370,6 +370,7 @@ let get_config com =
 			default_config with
 			pf_capture_policy = CPWrapRef;
 			pf_pad_nulls = true;
+			pf_supports_threads = true;
 		}
 	| Eval ->
 		{

+ 5 - 5
src/macro/eval/evalHash.ml

@@ -116,13 +116,13 @@ let key_socket = hash "socket"
 let key_read = hash "read"
 let key_write = hash "write"
 let key_others = hash "others"
-let key_eval_vm_Thread = hash "eval.vm.Thread"
+let key_sys_net_Thread = hash "sys.thread.Thread"
 let key_haxe_zip_Compress = hash "haxe.zip.Compress"
 let key_haxe_zip_Uncompress = hash "haxe.zip.Uncompress"
 let key_done = hash "done"
 let key_eval_toplevel = hash "eval-toplevel"
 let key_haxe_iterators_map_key_value_iterator = hash "haxe.iterators.MapKeyValueIterator"
-let key_eval_vm_Mutex = hash "eval.vm.Mutex"
-let key_eval_vm_Lock = hash "eval.vm.Lock"
-let key_eval_vm_Tls = hash "eval.vm.Tls"
-let key_eval_vm_Deque = hash "eval.vm.Deque"
+let key_sys_net_Mutex = hash "sys.thread.Mutex"
+let key_sys_net_Lock = hash "sys.thread.Lock"
+let key_sys_net_Tls = hash "sys.thread.Tls"
+let key_sys_net_Deque = hash "sys.thread.Deque"

+ 16 - 16
src/macro/eval/evalStdLib.ml

@@ -2667,7 +2667,7 @@ module StdThread = struct
 
 	let self = vfun0 (fun () ->
 		let eval = get_eval (get_ctx()) in
-		encode_instance key_eval_vm_Thread ~kind:(IThread eval.thread)
+		encode_instance key_sys_net_Thread ~kind:(IThread eval.thread)
 	)
 
 	let readMessage = vfun1 (fun blocking ->
@@ -3163,7 +3163,7 @@ let init_constructors builtins =
 				encode_instance key_haxe_zip_Uncompress ~kind:(IZip { z = z; z_flush = Extc.Z_NO_FLUSH })
 			| _ -> assert false
 		);
-	add key_eval_vm_Thread
+	add key_sys_net_Thread
 		(fun vl -> match vl with
 			| [f] ->
 				let ctx = get_ctx() in
@@ -3210,33 +3210,33 @@ let init_constructors builtins =
 					tdeque = Deque.create();
 				} in
 				thread.tthread <- Thread.create f thread;
-				encode_instance key_eval_vm_Thread ~kind:(IThread thread)
+				encode_instance key_sys_net_Thread ~kind:(IThread thread)
 			| _ -> assert false
 		);
-	add key_eval_vm_Mutex
+	add key_sys_net_Mutex
 		(fun _ ->
 			let mutex = {
 				mmutex = Mutex.create();
 				mowner = None;
 			} in
-			encode_instance key_eval_vm_Mutex ~kind:(IMutex mutex)
+			encode_instance key_sys_net_Mutex ~kind:(IMutex mutex)
 		);
-	add key_eval_vm_Lock
+	add key_sys_net_Lock
 		(fun _ ->
 			let lock = {
 				ldeque = Deque.create();
 			} in
-			encode_instance key_eval_vm_Lock ~kind:(ILock lock)
+			encode_instance key_sys_net_Lock ~kind:(ILock lock)
 		);
 	let tls_counter = ref (-1) in
-	add key_eval_vm_Tls
+	add key_sys_net_Tls
 		(fun _ ->
 			incr tls_counter;
-			encode_instance key_eval_vm_Tls ~kind:(ITls !tls_counter)
+			encode_instance key_sys_net_Tls ~kind:(ITls !tls_counter)
 		);
-	add key_eval_vm_Deque
+	add key_sys_net_Deque
 		(fun _ ->
-			encode_instance key_eval_vm_Deque ~kind:(IDeque (Deque.create()))
+			encode_instance key_sys_net_Deque ~kind:(IDeque (Deque.create()))
 		)
 
 let init_empty_constructors builtins =
@@ -3362,7 +3362,7 @@ let init_standard_library builtins =
 		"getTime",StdDate.getTime;
 		"toString",StdDate.toString;
 	];
-	init_fields builtins (["eval";"vm"],"Deque") [] [
+	init_fields builtins (["sys";"thread"],"Deque") [] [
 		"add",StdDeque.add;
 		"push",StdDeque.push;
 		"pop",StdDeque.pop;
@@ -3445,7 +3445,7 @@ let init_standard_library builtins =
 		"hostToString",StdHost.hostToString;
 		"resolve",StdHost.resolve;
 	] [];
-	init_fields builtins (["eval";"vm"],"Lock") [] [
+	init_fields builtins (["sys";"thread"],"Lock") [] [
 		"release",StdLock.release;
 		"wait",StdLock.wait;
 	];
@@ -3485,7 +3485,7 @@ let init_standard_library builtins =
 		"encode",StdMd5.encode;
 		"make",StdMd5.make;
 	] [];
-	init_fields builtins (["eval";"vm"],"Mutex") [] [
+	init_fields builtins (["sys";"thread"],"Mutex") [] [
 		"acquire",StdMutex.acquire;
 		"tryAcquire",StdMutex.tryAcquire;
 		"release",StdMutex.release;
@@ -3604,7 +3604,7 @@ let init_standard_library builtins =
 		"systemName",StdSys.systemName;
 		"time",StdSys.time;
 	] [];
-	init_fields builtins (["eval";"vm"],"Thread") [
+	init_fields builtins (["sys";"thread"],"Thread") [
 		"delay",StdThread.delay;
 		"exit",StdThread.exit;
 		"join",StdThread.join;
@@ -3616,7 +3616,7 @@ let init_standard_library builtins =
 		"kill",StdThread.kill;
 		"sendMessage",StdThread.sendMessage;
 	];
-	init_fields builtins (["eval";"vm"],"Tls") [] [
+	init_fields builtins (["sys";"thread"],"Tls") [] [
 		"get_value",StdTls.get_value;
 		"set_value",StdTls.set_value;
 	];

+ 1 - 0
src/typing/typeload.ml

@@ -733,6 +733,7 @@ let load_core_class ctx c =
 			com2.defines.Define.values <- PMap.empty;
 			Common.define com2 Define.CoreApi;
 			Common.define com2 Define.Sys;
+			Define.raw_define_value com2.defines "target.threaded" "true"; (* hack because we check this in sys.thread classes *)
 			if ctx.in_macro then Common.define com2 Define.Macro;
 			com2.class_path <- ctx.com.std_path;
 			if com2.display.dms_check_core_api then com2.display <- {com2.display with dms_check_core_api = false};

+ 40 - 0
std/cpp/_std/sys/thread/Deque.hx

@@ -0,0 +1,40 @@
+/*
+ * 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;
+
+@:coreApi
+class Deque<T> {
+	var q : Dynamic;
+	public function new() {
+		q = untyped __global__.__hxcpp_deque_create();
+	}
+	public function add( i : T ):Void {
+		untyped __global__.__hxcpp_deque_add(q,i);
+	}
+	public function push( i : T ):Void {
+		untyped __global__.__hxcpp_deque_push(q,i);
+	}
+	public function pop( block : Bool ) : Null<T> {
+		return untyped __global__.__hxcpp_deque_pop(q,block);
+	}
+}
+

+ 37 - 0
std/cpp/_std/sys/thread/Lock.hx

@@ -0,0 +1,37 @@
+/*
+ * 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;
+
+@:coreApi
+class Lock {
+	var l : Dynamic;
+	public function new() {
+		l = untyped __global__.__hxcpp_lock_create();
+	}
+	public function wait( ?timeout : Float = -1) : Bool {
+		return untyped __global__.__hxcpp_lock_wait(l,timeout);
+	}
+	public function release():Void {
+		untyped __global__.__hxcpp_lock_release(l);
+	}
+}
+

+ 41 - 0
std/cpp/_std/sys/thread/Mutex.hx

@@ -0,0 +1,41 @@
+/*
+ * 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;
+
+@:coreApi
+class Mutex {
+	var m : Dynamic;
+
+	public function new() {
+		m = untyped __global__.__hxcpp_mutex_create();
+	}
+	public function acquire():Void {
+		untyped __global__.__hxcpp_mutex_acquire(m);
+	}
+	public function tryAcquire() : Bool {
+		return untyped __global__.__hxcpp_mutex_try(m);
+	}
+	public function release():Void {
+		untyped __global__.__hxcpp_mutex_release(m);
+	}
+}
+

+ 56 - 0
std/cpp/_std/sys/thread/Thread.hx

@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+typedef ThreadHandle = Dynamic;
+
+@:coreApi
+class Thread {
+
+	var handle(default,null) : ThreadHandle;
+
+	function new(h:ThreadHandle):Void {
+		handle = h;
+	}
+
+	public function sendMessage( msg : Dynamic ):Void {
+		untyped __global__.__hxcpp_thread_send(handle,msg);
+	}
+
+	public static function current():Thread {
+		return new Thread(untyped __global__.__hxcpp_thread_current());
+	}
+
+	public static function create( callb : Void -> Void ):Thread {
+		return new Thread(untyped __global__.__hxcpp_thread_create(callb));
+	}
+
+	public static function readMessage( block : Bool ) : Dynamic {
+		return untyped __global__.__hxcpp_thread_read_message(block);
+	}
+
+	@:keep function __compare(t:Thread) : Int {
+		return handle == t.handle ? 0 : 1;
+	}
+
+}
+

+ 45 - 0
std/cpp/_std/sys/thread/Tls.hx

@@ -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;
+
+@:coreApi
+class Tls<T> {
+
+	static var sFreeSlot = 0;
+	var mTLSID : Int;
+	public var value(get,set) : T;
+
+	public function new() {
+		mTLSID = sFreeSlot++;
+	}
+
+	function get_value() : T {
+		return untyped __global__.__hxcpp_tls_get(mTLSID);
+	}
+
+	function set_value( v : T ):T {
+		untyped __global__.__hxcpp_tls_set(mTLSID,v);
+		return v;
+	}
+
+}
+

+ 1 - 17
std/cpp/vm/Deque.hx

@@ -21,20 +21,4 @@
  */
 package cpp.vm;
 
-
-class Deque<T> {
-	var q : Dynamic;
-	public function new() {
-		q = untyped __global__.__hxcpp_deque_create();
-	}
-	public function add( i : T ) {
-		untyped __global__.__hxcpp_deque_add(q,i);
-	}
-	public function push( i : T ) {
-		untyped __global__.__hxcpp_deque_push(q,i);
-	}
-	public function pop( block : Bool ) : Null<T> {
-		return untyped __global__.__hxcpp_deque_pop(q,block);
-	}
-}
-
+@:deprecated typedef Deque<T> = sys.thread.Deque<T>;

+ 1 - 14
std/cpp/vm/Lock.hx

@@ -21,17 +21,4 @@
  */
 package cpp.vm;
 
-
-class Lock {
-	var l : Dynamic;
-	public function new() {
-		l = untyped __global__.__hxcpp_lock_create();
-	}
-	public function wait( ?timeout : Float = -1) : Bool {
-		return untyped __global__.__hxcpp_lock_wait(l,timeout);
-	}
-	public function release() {
-		untyped __global__.__hxcpp_lock_release(l);
-	}
-}
-
+@:deprecated typedef Lock = sys.thread.Lock;

+ 1 - 17
std/cpp/vm/Mutex.hx

@@ -21,20 +21,4 @@
  */
 package cpp.vm;
 
-class Mutex {
-	var m : Dynamic;
-
-	public function new() {
-		m = untyped __global__.__hxcpp_mutex_create();
-	}
-	public function acquire() {
-		untyped __global__.__hxcpp_mutex_acquire(m);
-	}
-	public function tryAcquire() : Bool {
-		return untyped __global__.__hxcpp_mutex_try(m);
-	}
-	public function release() {
-		untyped __global__.__hxcpp_mutex_release(m);
-	}
-}
-
+@:deprecated typedef Mutex = sys.thread.Mutex;

+ 1 - 47
std/cpp/vm/Thread.hx

@@ -21,50 +21,4 @@
  */
 package cpp.vm;
 
-typedef ThreadHandle = Dynamic;
-
-class Thread {
-
-	public var handle(default,null) : ThreadHandle;
-
-	function new(h) {
-		handle = h;
-	}
-
-	/**
-		Send a message to the thread queue. This message can be read by using `readMessage`.
-	**/
-	public function sendMessage( msg : Dynamic ) {
-		untyped __global__.__hxcpp_thread_send(handle,msg);
-	}
-
-
-	/**
-		Returns the current thread.
-	**/
-	public static function current() {
-		return new Thread(untyped __global__.__hxcpp_thread_current());
-	}
-
-	/**
-		Creates a new thread that will execute the `callb` function, then exit.
-	**/
-	public static function create( callb : Void -> Void ) {
-		return new Thread(untyped __global__.__hxcpp_thread_create(callb));
-	}
-
-	/**
-		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 {
-		return untyped __global__.__hxcpp_thread_read_message(block);
-	}
-
-	@:keep function __compare(t:Thread) : Int {
-		return handle == t.handle ? 0 : 1;
-	}
-
-}
-
+@:deprecated typedef Thread = sys.thread.Thread;

+ 1 - 21
std/cpp/vm/Tls.hx

@@ -21,24 +21,4 @@
  */
 package cpp.vm;
 
-class Tls<T> {
-
-	static var sFreeSlot = 0;
-	var mTLSID : Int;
-	public var value(get,set) : T;
-
-	public function new() {
-		mTLSID = sFreeSlot++;
-	}
-
-	function get_value() : T {
-		return untyped __global__.__hxcpp_tls_get(mTLSID);
-	}
-
-	function set_value( v : T ) {
-		untyped __global__.__hxcpp_tls_set(mTLSID,v);
-		return v;
-	}
-
-}
-
+@:deprecated typedef Tls<T> = sys.thread.Tls<T>;

+ 1 - 1
std/eval/vm/Thread.hx → std/eval/_std/sys/thread/Thread.hx

@@ -20,7 +20,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-package eval.vm;
+package sys.thread;
 
 /**
 	Experimental Thread API.

+ 0 - 8
std/eval/vm/Deque.hx

@@ -1,8 +0,0 @@
-package eval.vm;
-
-extern class Deque<T> {
-	function new():Void;
-	function add(i:T):Void;
-	function pop(block:Bool):Null<T>;
-	function push(i:T):Void;
-}

+ 0 - 7
std/eval/vm/Lock.hx

@@ -1,7 +0,0 @@
-package eval.vm;
-
-extern class Lock {
-	function new():Void;
-	function release():Void;
-	function wait(?timeout:Float):Bool;
-}

+ 0 - 8
std/eval/vm/Mutex.hx

@@ -1,8 +0,0 @@
-package eval.vm;
-
-extern class Mutex {
-	function new():Void;
-	function acquire():Void;
-	function tryAcquire():Bool;
-	function release():Void;
-}

+ 0 - 6
std/eval/vm/Tls.hx

@@ -1,6 +0,0 @@
-package eval.vm;
-
-extern class Tls<T> {
-	public var value(get, set):T;
-	function new():Void;
-}

+ 6 - 6
std/haxe/EntryPoint.hx

@@ -1,13 +1,13 @@
 package haxe;
 
 #if (neko && !macro && !interp)
-import neko.vm.Lock;
-import neko.vm.Mutex;
-import neko.vm.Thread;
+import sys.thread.Lock;
+import sys.thread.Mutex;
+import sys.thread.Thread;
 #elseif cpp
-import cpp.vm.Lock;
-import cpp.vm.Mutex;
-import cpp.vm.Thread;
+import sys.thread.Lock;
+import sys.thread.Mutex;
+import sys.thread.Thread;
 #elseif java
 import java.vm.Lock;
 import java.vm.Mutex;

+ 4 - 4
std/haxe/io/FPHelper.hx

@@ -30,7 +30,7 @@ class FPHelper {
 	#if neko_v21
 	// stored in helper
 	#elseif neko
-	static var i64tmp = new neko.vm.Tls<Int64>();
+	static var i64tmp = new sys.thread.Tls<Int64>();
 	#elseif !(java || cs || cpp)
 	static var i64tmp = Int64.ofInt(0);
 
@@ -111,10 +111,10 @@ class FPHelper {
 
 	#if neko
 		#if neko_v21
-		static var helpers = new neko.vm.Tls<neko.NativeArray<Dynamic>>();
+		static var helpers = new sys.thread.Tls<neko.NativeArray<Dynamic>>();
 		#else
-		static var helperf = new neko.vm.Tls<neko.NativeString>();
-		static var helperd = new neko.vm.Tls<neko.NativeString>();
+		static var helperf = new sys.thread.Tls<neko.NativeString>();
+		static var helperd = new sys.thread.Tls<neko.NativeString>();
 		static var _float_of_bytes = neko.Lib.load("std","float_of_bytes",2);
 		static var _double_of_bytes = neko.Lib.load("std","double_of_bytes",2);
 		static var _float_bytes = neko.Lib.load("std","float_bytes",2);

+ 1 - 1
std/hl/vm/Deque.hx → std/hl/_std/sys/thread/Deque.hx

@@ -19,7 +19,7 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
-package hl.vm;
+package sys.thread;
 
 /**
 	A message queue for multithread access.

+ 7 - 7
std/hl/vm/Mutex.hx → std/hl/_std/sys/thread/Mutex.hx

@@ -19,11 +19,11 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
-package hl.vm;
+package sys.thread;
 
 /**
-	Creates a mutex, which can be used to acquire a temporary lock 
-	to access some ressource. The main difference with a lock is 
+	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.
 **/
 abstract Mutex(hl.Abstract<"hl_mutex">) {
@@ -37,14 +37,14 @@ abstract Mutex(hl.Abstract<"hl_mutex">) {
 
 	/**
 		The current thread acquire the mutex or wait if not available.
-		The same thread can acquire several times the same mutex but 
+		The same thread can acquire several times the same mutex but
 		must release it as many times it has been acquired.
 	**/
 	@:hlNative("std","mutex_acquire") public function acquire() {
 	}
 
 	/**
-		Try to acquire the mutex, returns true if acquire or false 
+		Try to acquire the mutex, returns true if acquire or false
 		if it's already locked by another thread.
 	**/
 	@:hlNative("std","mutex_try_acquire") public function tryAcquire() : Bool {
@@ -52,7 +52,7 @@ abstract Mutex(hl.Abstract<"hl_mutex">) {
 	}
 
 	/**
-		Release a mutex that has been acquired by the current thread. 
+		Release a mutex that has been acquired by the current thread.
 		The behavior is undefined if the current thread does not own
 		the mutex.
 	**/
@@ -62,5 +62,5 @@ abstract Mutex(hl.Abstract<"hl_mutex">) {
 	@:hlNative("std","mutex_alloc") public static function alloc( b : Bool ) {
 		return null;
 	}
-	
+
 }

+ 1 - 1
std/hl/vm/Thread.hx → std/hl/_std/sys/thread/Thread.hx

@@ -19,7 +19,7 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
-package hl.vm;
+package sys.thread;
 
 typedef ThreadHandle = hl.Abstract<"hl_thread">;
 

+ 3 - 3
std/hl/vm/Tls.hx → std/hl/_std/sys/thread/Tls.hx

@@ -19,7 +19,7 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
-package hl.vm;
+package sys.thread;
 
 /**
 	Creates thread local storage.
@@ -32,8 +32,8 @@ abstract Tls<T>(hl.Abstract<"hl_tls">) {
 
 	/**
 		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 
+		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.
 	**/
 	public function new() {

+ 92 - 0
std/java/_std/sys/thread/Deque.hx

@@ -0,0 +1,92 @@
+/*
+ * 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;
+import java.Lib;
+
+@:coreApi
+@:native('haxe.java.vm.Deque')
+@:nativeGen class Deque<T>
+{
+	@:private var head:Node<T>;
+	@:private var tail:Node<T>;
+
+	public function new()
+	{
+		this.head = this.tail = new Node(null);
+	}
+
+	public function add(i : T):Void
+	{
+		var n = new Node(i);
+		untyped __lock__(this,
+		{
+			tail.next = n;
+			tail = n;
+			try { untyped this.notify(); } catch(e:Dynamic) { throw e; }
+		});
+	}
+
+	public function push(i : T):Void
+	{
+		var n = new Node(i);
+		untyped __lock__(this,
+		{
+			n.next = head.next;
+			head.next = n;
+			try { untyped this.notify(); } catch(e:Dynamic) { throw e; }
+		});
+	}
+
+	public function pop(block : Bool) : Null<T>
+	{
+		var ret = null;
+		untyped __lock__(this, {
+			var n = null;
+			do {
+				n = head.next;
+				if (n != null)
+				{
+					ret = n.value;
+					n.value = null;
+					head = n;
+				} else if (block) {
+					//block
+					try { untyped this.wait(); } catch(e:Dynamic) { throw e; }
+				}
+			} while( block && n == null );
+		});
+		return ret;
+	}
+}
+
+@:native('haxe.java.vm.DequeNode')
+@:nativeGen
+class Node<T>
+{
+	public var value:T;
+	public var next:Node<T>;
+
+	public function new(val)
+	{
+		this.value = val;
+	}
+}

+ 95 - 0
std/java/_std/sys/thread/Lock.hx

@@ -0,0 +1,95 @@
+/*
+ * 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;
+import java.Lib;
+import java.lang.System;
+using haxe.Int64;
+
+@:coreApi
+@:native('haxe.java.vm.Lock') class Lock
+{
+	@:private @:volatile var releasedCount = 0;
+
+	public function new()
+	{
+	}
+
+	public function wait(?timeout : Float) : Bool
+	{
+		var ret = false;
+		java.Lib.lock(this,
+		{
+			if (--releasedCount < 0)
+			{
+				if (timeout == null)
+				{
+					// since .notify() is asynchronous, this `while` is needed
+					// because there is a very remote possibility of release() awaking a thread,
+					// but before it releases, another thread calls wait - and since the release count
+					// is still positive, it will get the lock.
+					while( releasedCount < 0 )
+					{
+						try
+						{
+							untyped __java__("this.wait()");
+						}
+						catch(e:java.lang.InterruptedException)
+						{
+						}
+					}
+				} else {
+					var timeout:haxe.Int64 = cast timeout * 1000;
+					var cur = System.currentTimeMillis(),
+					    max = cur.add(timeout);
+					// see above comment about this while loop
+					while ( releasedCount < 0 && cur.compare(max) < 0 )
+					{
+						try
+						{
+							var t = max.sub(cur);
+							untyped __java__("this.wait({0})",t);
+							cur = System.currentTimeMillis();
+						}
+						catch(e:java.lang.InterruptedException)
+						{
+						}
+					}
+				}
+			}
+			ret = this.releasedCount >= 0;
+			if (!ret)
+				this.releasedCount++; //timed out
+		});
+		return ret;
+	}
+
+	public function release():Void
+	{
+		untyped __lock__(this,
+		{
+			if (++releasedCount >= 0)
+			{
+				untyped this.notify();
+			}
+		});
+	}
+}

+ 49 - 0
std/java/_std/sys/thread/Mutex.hx

@@ -0,0 +1,49 @@
+/*
+ * 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;
+import java.util.concurrent.locks.ReentrantLock;
+
+@:coreApi
+@:native('haxe.java.vm.Mutex') class Mutex
+{
+	@:private var lock:ReentrantLock;
+
+	public function new()
+	{
+		this.lock = new ReentrantLock();
+	}
+
+	public function tryAcquire():Bool
+	{
+		return this.lock.tryLock();
+	}
+
+	public function acquire():Void
+	{
+		this.lock.lock();
+	}
+
+	public function release():Void
+	{
+		this.lock.unlock();
+	}
+}

+ 112 - 0
std/java/_std/sys/thread/Thread.hx

@@ -0,0 +1,112 @@
+/*
+ * 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;
+import java.Lib;
+
+@:coreApi
+@:native('haxe.java.vm.Thread') class Thread
+{
+
+	@:private static var javaThreadToHaxe = new haxe.ds.WeakMap<java.lang.Thread, sys.thread.Thread>();
+	@:private static var mainJavaThread = java.lang.Thread.currentThread();
+	@:private static var mainHaxeThread = {
+		var ret = new Thread();
+		javaThreadToHaxe.set(mainJavaThread, ret);
+		ret;
+	};
+
+
+	private static function getThread(jt:java.lang.Thread):Thread
+	{
+		if (Std.is(jt, HaxeThread))
+		{
+			var t:HaxeThread = cast jt;
+			return t.threadObject;
+		}
+		else if (jt == mainJavaThread)
+		{
+			return mainHaxeThread;
+		}
+		else
+		{
+			var ret = null;
+			untyped __lock__(javaThreadToHaxe, {
+				ret = javaThreadToHaxe.get(jt);
+				if (ret == null)
+				{
+					ret = new Thread();
+					javaThreadToHaxe.set(jt, ret);
+				}
+
+			});
+			return ret;
+		}
+	}
+
+	private var messages:Deque<Dynamic>;
+
+  function new()
+	{
+		this.messages = new Deque();
+	}
+
+	public function sendMessage(msg:Dynamic):Void
+	{
+		messages.add(msg);
+	}
+
+	public static function current():Thread
+	{
+		return getThread( java.lang.Thread.currentThread() );
+	}
+
+	public static function readMessage(block : Bool) : Dynamic
+	{
+		return current().messages.pop(block);
+	}
+
+	public static function create(callb:Void->Void):Thread
+	{
+		var ret = new Thread();
+		var t = new HaxeThread(ret, callb);
+		t.start();
+		return ret;
+	}
+}
+
+@:native('haxe.java.vm.HaxeThread')
+private class HaxeThread extends java.lang.Thread
+{
+	public var threadObject(default, null):Thread;
+	private var runFunction:Void->Void;
+	@:overload override public function run():Void
+	{
+		runFunction();
+	}
+	public function new(hxThread:Thread, run:Void->Void)
+	{
+		super();
+		threadObject = hxThread;
+		runFunction = run;
+		setDaemon(true);
+	}
+}

+ 46 - 0
std/java/_std/sys/thread/Tls.hx

@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+// @:coreApi // causes some overload error...
+@:native('haxe.java.vm.Tls') class Tls<T>
+{
+	var t : java.lang.ThreadLocal<T>;
+	public var value(get,set):T;
+
+	public function new()
+	{
+		this.t = new java.lang.ThreadLocal();
+	}
+
+	inline private function get_value():T
+	{
+		return t.get();
+	}
+
+	inline private function set_value(v:T):T
+	{
+		t.set(v);
+		return v;
+	}
+
+}

+ 2 - 72
std/java/vm/Deque.hx

@@ -19,76 +19,6 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
- package java.vm;
-import java.Lib;
+package java.vm;
 
-/**
-	A Lock-free Queue implementation
-**/
-@:native('haxe.java.vm.Deque')
-@:nativeGen class Deque<T>
-{
-	@:private var head:Node<T>;
-	@:private var tail:Node<T>;
-
-	public function new()
-	{
-		this.head = this.tail = new Node(null);
-	}
-
-	public function add(i : T)
-	{
-		var n = new Node(i);
-		untyped __lock__(this,
-		{
-			tail.next = n;
-			tail = n;
-			try { untyped this.notify(); } catch(e:Dynamic) { throw e; }
-		});
-	}
-
-	public function push(i : T)
-	{
-		var n = new Node(i);
-		untyped __lock__(this,
-		{
-			n.next = head.next;
-			head.next = n;
-			try { untyped this.notify(); } catch(e:Dynamic) { throw e; }
-		});
-	}
-
-	public function pop(block : Bool) : Null<T>
-	{
-		var ret = null;
-		untyped __lock__(this, {
-			var n = null;
-			do {
-				n = head.next;
-				if (n != null)
-				{
-					ret = n.value;
-					n.value = null;
-					head = n;
-				} else if (block) {
-					//block
-					try { untyped this.wait(); } catch(e:Dynamic) { throw e; }
-				}
-			} while( block && n == null );
-		});
-		return ret;
-	}
-}
-
-@:native('haxe.java.vm.DequeNode')
-@:nativeGen
-class Node<T>
-{
-	public var value:T;
-	public var next:Node<T>;
-
-	public function new(val)
-	{
-		this.value = val;
-	}
-}
+@:deprecated typedef Deque<T> = sys.thread.Deque<T>;

+ 2 - 83
std/java/vm/Lock.hx

@@ -19,87 +19,6 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
- package java.vm;
-import java.Lib;
-import java.lang.System;
-using haxe.Int64;
+package java.vm;
 
-@:native('haxe.java.vm.Lock') class Lock
-{
-	@:private @:volatile var releasedCount = 0;
-
-	/**
-		Creates a new lock, which is initially locked
-	**/
-	public function new()
-	{
-	}
-
-	/**
-		Waits for a lock to be released and acquire it.
-		If `timeout` (in seconds) is not null and expires then the returned value is false
-	**/
-	public function wait(?timeout : Float) : Bool
-	{
-		var ret = false;
-		java.Lib.lock(this,
-		{
-			if (--releasedCount < 0)
-			{
-				if (timeout == null)
-				{
-					// since .notify() is asynchronous, this `while` is needed
-					// because there is a very remote possibility of release() awaking a thread,
-					// but before it releases, another thread calls wait - and since the release count
-					// is still positive, it will get the lock.
-					while( releasedCount < 0 )
-					{
-						try
-						{
-							untyped __java__("this.wait()");
-						}
-						catch(e:java.lang.InterruptedException)
-						{
-						}
-					}
-				} else {
-					var timeout:haxe.Int64 = cast timeout * 1000;
-					var cur = System.currentTimeMillis(),
-					    max = cur.add(timeout);
-					// see above comment about this while loop
-					while ( releasedCount < 0 && cur.compare(max) < 0 )
-					{
-						try
-						{
-							var t = max.sub(cur);
-							untyped __java__("this.wait({0})",t);
-							cur = System.currentTimeMillis();
-						}
-						catch(e:java.lang.InterruptedException)
-						{
-						}
-					}
-				}
-			}
-			ret = this.releasedCount >= 0;
-			if (!ret)
-				this.releasedCount++; //timed out
-		});
-		return ret;
-	}
-
-	/**
-		Release a lock. The thread does not need to own the lock to be able to release it.
-		If a lock is released several times, it can be acquired as many times
-	**/
-	public function release()
-	{
-		untyped __lock__(this,
-		{
-			if (++releasedCount >= 0)
-			{
-				untyped this.notify();
-			}
-		});
-	}
-}
+@:deprecated typedef Lock = sys.thread.Lock;

+ 2 - 40
std/java/vm/Mutex.hx

@@ -19,44 +19,6 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
- package java.vm;
-import java.util.concurrent.locks.ReentrantLock;
+package java.vm;
 
-@:native('haxe.java.vm.Mutex') class Mutex
-{
-	@:private var lock:ReentrantLock;
-
-	/**
-		Creates a mutex, which can be used to acquire a temporary lock to access some resource.
-		The main difference with a lock is that a mutex must always be released by the owner thread
-	**/
-	public function new()
-	{
-		this.lock = new ReentrantLock();
-	}
-
-	/**
-		Try to acquire the mutex, returns true if acquire or false if it's already locked by another thread.
-	**/
-	public function tryAcquire():Bool
-	{
-		return this.lock.tryLock();
-	}
-
-	/**
-		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.
-	**/
-	public function acquire():Void
-	{
-		this.lock.lock();
-	}
-
-	/**
-		Release a mutex that has been acquired by the current thread. If the current thread does not own the mutex, an exception will be thrown
-	**/
-	public function release():Void
-	{
-		this.lock.unlock();
-	}
-}
+@:deprecated typedef Mutex = sys.thread.Mutex;

+ 2 - 89
std/java/vm/Thread.hx

@@ -19,93 +19,6 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
- package java.vm;
-import java.Lib;
+package java.vm;
 
-@:native('haxe.java.vm.Thread') class Thread
-{
-
-	@:private static var javaThreadToHaxe = new haxe.ds.WeakMap<java.lang.Thread, java.vm.Thread>();
-	@:private static var mainJavaThread = java.lang.Thread.currentThread();
-	@:private static var mainHaxeThread = {
-		var ret = new Thread();
-		javaThreadToHaxe.set(mainJavaThread, ret);
-		ret;
-	};
-
-
-	private static function getThread(jt:java.lang.Thread):Thread
-	{
-		if (Std.is(jt, HaxeThread))
-		{
-			var t:HaxeThread = cast jt;
-			return t.threadObject;
-		}
-		else if (jt == mainJavaThread)
-		{
-			return mainHaxeThread;
-		}
-		else
-		{
-			var ret = null;
-			untyped __lock__(javaThreadToHaxe, {
-				ret = javaThreadToHaxe.get(jt);
-				if (ret == null)
-				{
-					ret = new Thread();
-					javaThreadToHaxe.set(jt, ret);
-				}
-
-			});
-			return ret;
-		}
-	}
-
-	private var messages:Deque<Dynamic>;
-
-  function new()
-	{
-		this.messages = new Deque();
-	}
-
-	public function sendMessage(obj:Dynamic)
-	{
-		messages.add(obj);
-	}
-
-	public static function current():Thread
-	{
-		return getThread( java.lang.Thread.currentThread() );
-	}
-
-	public static function readMessage(block : Bool) : Dynamic
-	{
-		return current().messages.pop(block);
-	}
-
-	public static function create(fn:Void->Void):Thread
-	{
-		var ret = new Thread();
-		var t = new HaxeThread(ret, fn);
-		t.start();
-		return ret;
-	}
-}
-
-@:native('haxe.java.vm.HaxeThread')
-private class HaxeThread extends java.lang.Thread
-{
-	public var threadObject(default, null):Thread;
-	private var runFunction:Void->Void;
-	@:overload override public function run():Void
-	{
-		runFunction();
-	}
-	public function new(hxThread:Thread, run:Void->Void)
-	{
-		super();
-		threadObject = hxThread;
-		runFunction = run;
-		setDaemon(true);
-	}
-}
+@:deprecated typedef Thread = sys.thread.Thread;

+ 2 - 26
std/java/vm/Tls.hx

@@ -19,30 +19,6 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
- package java.vm;
+package java.vm;
 
-/**
-	Thread-local Storage implementation
-**/
-@:native('haxe.java.vm.Tls') class Tls<T>
-{
-	var t : java.lang.ThreadLocal<T>;
-	public var value(get,set):T;
-
-	public function new()
-	{
-		this.t = new java.lang.ThreadLocal();
-	}
-
-	inline private function get_value():T
-	{
-		return t.get();
-	}
-
-	inline private function set_value(v:T):T
-	{
-		t.set(v);
-		return v;
-	}
-
-}
+@:deprecated typedef Tls<T> = sys.thread.Tls<T>;

+ 48 - 0
std/neko/_std/sys/thread/Deque.hx

@@ -0,0 +1,48 @@
+/*
+ * 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;
+
+@:coreApi
+class Deque<T> {
+	var q : Dynamic;
+
+	public function new() {
+		q = deque_create();
+	}
+
+	public function add( i : T ):Void {
+		deque_add(q,i);
+	}
+
+	public function push( i : T ):Void {
+		deque_push(q,i);
+	}
+
+	public function pop( block : Bool ) : Null<T> {
+		return deque_pop(q,block);
+	}
+
+	static var deque_create = neko.Lib.loadLazy("std","deque_create",0);
+	static var deque_add = neko.Lib.loadLazy("std","deque_add",2);
+	static var deque_push = neko.Lib.loadLazy("std","deque_push",2);
+	static var deque_pop = neko.Lib.loadLazy("std","deque_pop",2);
+}

+ 43 - 0
std/neko/_std/sys/thread/Lock.hx

@@ -0,0 +1,43 @@
+/*
+ * 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;
+
+@:coreApi
+class Lock {
+	var l : Dynamic;
+
+	public function new() {
+		l = lock_create();
+	}
+
+	public function wait( ?timeout : Float ) : Bool {
+		return lock_wait(l,timeout);
+	}
+
+	public function release():Void {
+		lock_release(l);
+	}
+
+	static var lock_create = neko.Lib.load("std","lock_create",0);
+	static var lock_release = neko.Lib.load("std","lock_release",1);
+	static var lock_wait = neko.Lib.load("std","lock_wait",2);
+}

+ 48 - 0
std/neko/_std/sys/thread/Mutex.hx

@@ -0,0 +1,48 @@
+/*
+ * 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;
+
+@:coreApi
+class Mutex {
+	var m : Dynamic;
+
+	public function new():Void {
+		m = mutex_create();
+	}
+
+	public function acquire():Void {
+		mutex_acquire(m);
+	}
+
+	public function tryAcquire() : Bool {
+		return mutex_try(m);
+	}
+
+	public function release():Void {
+		mutex_release(m);
+	}
+
+	static var mutex_create = neko.Lib.loadLazy("std","mutex_create",0);
+	static var mutex_release = neko.Lib.loadLazy("std","mutex_release",1);
+	static var mutex_acquire = neko.Lib.loadLazy("std","mutex_acquire",1);
+	static var mutex_try = neko.Lib.loadLazy("std","mutex_try",1);
+}

+ 122 - 0
std/neko/_std/sys/thread/Thread.hx

@@ -0,0 +1,122 @@
+/*
+ * 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;
+
+@:callable
+@:coreType
+abstract ThreadHandle {
+}
+
+@:coreApi
+class Thread {
+
+	var handle : ThreadHandle;
+
+	function new(h:ThreadHandle):Void {
+		handle = h;
+	}
+
+	public function sendMessage( msg : Dynamic ):Void {
+		thread_send(handle,msg);
+	}
+
+	public static function current():Thread {
+		return new Thread(thread_current());
+	}
+
+	public static function create( callb : Void -> Void ):Thread {
+		return new Thread(thread_create(function(_) { return callb(); },null));
+	}
+
+	public static function readMessage( block : Bool ) : Dynamic {
+		return thread_read_message(block);
+	}
+
+	@:keep function __compare(t:Dynamic):Int {
+		return untyped __dollar__compare(handle,t.handle);
+	}
+
+	/**
+		Starts an OS message loop after [osInitialize] has been done.
+		In that state, the UI handled by this thread will be updated and
+		[sync] calls can be performed. The loop returns when [exitLoop] is
+		called for this thread.
+	**
+	public static function osLoop() {
+		if( os_loop == null ) throw "Please call osInitialize() first";
+		os_loop();
+	}
+
+	/**
+		The function [f] will be called by this thread if it's in [osLoop].
+		[sync] returns immediately. See [osInitialize] remarks.
+	**
+	public function sync( f : Void -> Void ) {
+		os_sync(handle,f);
+	}
+
+	/**
+		The function [f] will be called by this thread and the calling thread
+		will wait until the result is available then return its value.
+	**
+	public function syncResult<T>( f : Void -> T ) : T {
+		if( this == current() )
+			return f();
+		var v = new neko.vm.Lock();
+		var r = null;
+		sync(function() {
+			r = f();
+			v.release();
+		});
+		v.wait();
+		return r;
+	}
+
+	/**
+		Exit from [osLoop].
+	**
+	public function exitLoop() {
+		os_loop_stop(handle);
+	}
+
+	/**
+		If you want to use the [osLoop], [sync] and [syncResult] methods, you
+		need to call [osInitialize] before creating any thread or calling [current].
+		This will load [os.ndll] library and initialize UI methods for each thread.
+	**
+	public static function osInitialize() {
+		os_loop = neko.Lib.load("os","os_loop",0);
+		os_loop_stop = neko.Lib.load("os","os_loop_stop",1);
+		os_sync = neko.Lib.load("os","os_sync",2);
+	}
+
+	static var os_loop = null;
+	static var os_loop_stop = null;
+	static var os_sync = null;
+	*/
+
+	static var thread_create = neko.Lib.load("std","thread_create",2);
+	static var thread_current = neko.Lib.load("std","thread_current",0);
+	static var thread_send = neko.Lib.load("std","thread_send",2);
+	static var thread_read_message = neko.Lib.load("std","thread_read_message",1);
+
+}

+ 46 - 0
std/neko/_std/sys/thread/Tls.hx

@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+@:coreApi
+class Tls<T> {
+
+	var t : Dynamic;
+	public var value(get,set) : T;
+
+	public function new() {
+		t = tls_create();
+	}
+
+	function get_value() : T {
+		return tls_get(t);
+	}
+
+	function set_value( v : T ):T {
+		tls_set(t,v);
+		return v;
+	}
+
+	static var tls_create = neko.Lib.load("std","tls_create",0);
+	static var tls_get = neko.Lib.load("std","tls_get",1);
+	static var tls_set = neko.Lib.load("std","tls_set",2);
+}

+ 1 - 40
std/neko/vm/Deque.hx

@@ -21,43 +21,4 @@
  */
 package neko.vm;
 
-/**
-	A message queue for multithread access.
-*/
-class Deque<T> {
-	var q : Dynamic;
-
-	/**
-		Create a message queue for multithread access.
-	**/
-	public function new() {
-		q = deque_create();
-	}
-
-	/**
-		Add a message at the end of the queue.
-	**/
-	public function add( i : T ) {
-		deque_add(q,i);
-	}
-
-	/**
-		Add a message at the head of the queue.
-	**/
-	public function push( i : T ) {
-		deque_push(q,i);
-	}
-
-	/**
-		Pop a message from the queue head. Either block until a message 
-		is available or return immediately with `null`.
-	**/
-	public function pop( block : Bool ) : Null<T> {
-		return deque_pop(q,block);
-	}
-
-	static var deque_create = neko.Lib.loadLazy("std","deque_create",0);
-	static var deque_add = neko.Lib.loadLazy("std","deque_add",2);
-	static var deque_push = neko.Lib.loadLazy("std","deque_push",2);
-	static var deque_pop = neko.Lib.loadLazy("std","deque_pop",2);
-}
+@:deprecated typedef Deque<T> = sys.thread.Deque<T>;

+ 1 - 32
std/neko/vm/Lock.hx

@@ -21,35 +21,4 @@
  */
 package neko.vm;
 
-class Lock {
-	var l : Dynamic;
-
-	/**
-		Creates a lock which is initially locked.
-	**/
-	public function new() {
-		l = lock_create();
-	}
-
-	/**
-		Waits for a lock to be released and acquire it. If timeout 
-		(in seconds) is not `null` and expires then the returned 
-		value is `false`.
-	**/
-	public function wait( ?timeout : Float ) : Bool {
-		return lock_wait(l,timeout);
-	}
-	
-	/**
-		Release a lock. The thread does not need to own the lock 
-		to be able to release it. If a lock is released several 
-		times, it can be acquired as many times.
-	**/
-	public function release() {
-		lock_release(l);
-	}
-
-	static var lock_create = neko.Lib.load("std","lock_create",0);
-	static var lock_release = neko.Lib.load("std","lock_release",1);
-	static var lock_wait = neko.Lib.load("std","lock_wait",2);
-}
+@:deprecated typedef Lock = sys.thread.Lock;

+ 1 - 46
std/neko/vm/Mutex.hx

@@ -21,49 +21,4 @@
  */
 package neko.vm;
 
-/**
-	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.
-*/
-class Mutex {
-	var m : Dynamic;
-
-	/**
-		Creates a mutex.
-	**/
-	public function new() {
-		m = mutex_create();
-	}
-
-	/**
-		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.
-	**/
-	public function acquire() {
-		mutex_acquire(m);
-	}
-
-	/**
-		Try to acquire the mutex, returns true if acquire or false 
-		if it's already locked by another thread.
-	**/
-	public function tryAcquire() : Bool {
-		return mutex_try(m);
-	}
-
-	/**
-		Release a mutex that has been acquired by the current thread. 
-		The behavior is undefined if the current thread does not own
-		the mutex.
-	**/
-	public function release() {
-		mutex_release(m);
-	}
-
-	static var mutex_create = neko.Lib.loadLazy("std","mutex_create",0);
-	static var mutex_release = neko.Lib.loadLazy("std","mutex_release",1);
-	static var mutex_acquire = neko.Lib.loadLazy("std","mutex_acquire",1);
-	static var mutex_try = neko.Lib.loadLazy("std","mutex_try",1);
-}
+@:deprecated typedef Mutex = sys.thread.Mutex;

+ 1 - 113
std/neko/vm/Thread.hx

@@ -21,116 +21,4 @@
  */
 package neko.vm;
 
-@:callable
-@:coreType
-abstract ThreadHandle {
-}
-
-class Thread {
-
-	var handle : ThreadHandle;
-
-	function new(h) {
-		handle = h;
-	}
-
-	/**
-		Send a message to the thread queue. This message can be read by using `readMessage`.
-	**/
-	public function sendMessage( msg : Dynamic ) {
-		thread_send(handle,msg);
-	}
-
-
-	/**
-		Returns the current thread.
-	**/
-	public static function current() {
-		return new Thread(thread_current());
-	}
-
-	/**
-		Creates a new thread that will execute the `callb` function, then exit.
-	**/
-	public static function create( callb : Void -> Void ) {
-		return new Thread(thread_create(function(_) { return callb(); },null));
-	}
-
-	/**
-		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 {
-		return thread_read_message(block);
-	}
-
-	@:keep function __compare(t:Dynamic) {
-		return untyped __dollar__compare(handle,t.handle);
-	}
-
-	/**
-		Starts an OS message loop after [osInitialize] has been done.
-		In that state, the UI handled by this thread will be updated and
-		[sync] calls can be performed. The loop returns when [exitLoop] is
-		called for this thread.
-	**
-	public static function osLoop() {
-		if( os_loop == null ) throw "Please call osInitialize() first";
-		os_loop();
-	}
-
-	/**
-		The function [f] will be called by this thread if it's in [osLoop].
-		[sync] returns immediately. See [osInitialize] remarks.
-	**
-	public function sync( f : Void -> Void ) {
-		os_sync(handle,f);
-	}
-
-	/**
-		The function [f] will be called by this thread and the calling thread
-		will wait until the result is available then return its value.
-	**
-	public function syncResult<T>( f : Void -> T ) : T {
-		if( this == current() )
-			return f();
-		var v = new neko.vm.Lock();
-		var r = null;
-		sync(function() {
-			r = f();
-			v.release();
-		});
-		v.wait();
-		return r;
-	}
-
-	/**
-		Exit from [osLoop].
-	**
-	public function exitLoop() {
-		os_loop_stop(handle);
-	}
-
-	/**
-		If you want to use the [osLoop], [sync] and [syncResult] methods, you
-		need to call [osInitialize] before creating any thread or calling [current].
-		This will load [os.ndll] library and initialize UI methods for each thread.
-	**
-	public static function osInitialize() {
-		os_loop = neko.Lib.load("os","os_loop",0);
-		os_loop_stop = neko.Lib.load("os","os_loop_stop",1);
-		os_sync = neko.Lib.load("os","os_sync",2);
-	}
-
-	static var os_loop = null;
-	static var os_loop_stop = null;
-	static var os_sync = null;
-	*/
-
-	static var thread_create = neko.Lib.load("std","thread_create",2);
-	static var thread_current = neko.Lib.load("std","thread_current",0);
-	static var thread_send = neko.Lib.load("std","thread_send",2);
-	static var thread_read_message = neko.Lib.load("std","thread_read_message",1);
-
-}
+@:deprecated typedef Thread = sys.thread.Thread;

+ 1 - 37
std/neko/vm/Tls.hx

@@ -21,40 +21,4 @@
  */
 package neko.vm;
 
-/**
-	Creates thread local storage.
-*/
-class Tls<T> {
-
-	var t : Dynamic;
-	public 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.
-	**/
-	public function new() {
-		t = tls_create();
-	}
-
-	/**
-		Returns the value set by tls_set for the local thread.
-	**/
-	function get_value() : T {
-		return tls_get(t);
-	}
-
-	/**
-		Set the value of the TLS for the local thread.
-	**/
-	function set_value( v : T ) {
-		tls_set(t,v);
-		return v;
-	}
-
-	static var tls_create = neko.Lib.load("std","tls_create",0);
-	static var tls_get = neko.Lib.load("std","tls_get",1);
-	static var tls_set = neko.Lib.load("std","tls_set",2);
-}
+@:deprecated typedef Tls<T> = sys.thread.Tls<T>;

+ 59 - 0
std/sys/thread/Deque.hx

@@ -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
+
+/**
+	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.
+	**/
+	public function new():Void;
+
+	/**
+		Adds an element at the end of `this` Deque.
+	**/
+	public function add(i:T):Void;
+
+	/**
+		Adds an element at the front of `this` Deque.
+	**/
+	public 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.
+	**/
+	public function pop(block:Bool):Null<T>;
+}

+ 80 - 0
std/sys/thread/Lock.hx

@@ -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:
+
+	```
+		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.
+	**/
+	public 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.
+	**/
+	public 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.
+	**/
+	public function release():Void;
+}

+ 59 - 0
std/sys/thread/Mutex.hx

@@ -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.
+	**/
+	public 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.
+	**/
+	public function acquire():Void;
+
+	/**
+		Try to acquire the mutex, returns true if acquire or false
+		if it's already locked by another thread.
+	**/
+	public 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.
+	**/
+	public function release():Void;
+}

+ 50 - 0
std/sys/thread/Thread.hx

@@ -0,0 +1,50 @@
+/*
+ * 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
+extern class Thread {
+	/**
+		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 `f` function, then exit.
+	**/
+	public static function create(callb:Void->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;
+}

+ 42 - 0
std/sys/thread/Tls.hx

@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+extern class Tls<T> {
+	public 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.
+	**/
+	public function new():Void;
+}

+ 5 - 31
tests/threads/src/import.hx

@@ -1,31 +1,5 @@
-#if neko
-import neko.vm.Thread;
-import neko.vm.Deque;
-import neko.vm.Lock;
-import neko.vm.Tls;
-import neko.vm.Mutex;
-#elseif cpp
-import cpp.vm.Thread;
-import cpp.vm.Deque;
-import cpp.vm.Lock;
-import cpp.vm.Tls;
-import cpp.vm.Mutex;
-#elseif java
-import java.vm.Thread;
-import java.vm.Deque;
-import java.vm.Lock;
-import java.vm.Tls;
-import java.vm.Mutex;
-#elseif eval
-import eval.vm.Thread;
-import eval.vm.Deque;
-import eval.vm.Lock;
-import eval.vm.Tls;
-import eval.vm.Mutex;
-#elseif hl
-import hl.vm.Thread;
-import hl.vm.Deque;
-// import hl.vm.Lock; // TODO
-import hl.vm.Tls;
-import hl.vm.Mutex;
-#end
+import sys.thread.Thread;
+import sys.thread.Deque;
+import sys.thread.Lock;
+import sys.thread.Tls;
+import sys.thread.Mutex;

+ 5 - 25
tests/unit/src/unit/TestThreads.hx

@@ -1,30 +1,10 @@
 package unit;
 import utest.Assert;
-#if neko
-import neko.vm.Thread;
-import neko.vm.Deque;
-import neko.vm.Lock;
-import neko.vm.Tls;
-import neko.vm.Mutex;
-#elseif cpp
-import cpp.vm.Thread;
-import cpp.vm.Deque;
-import cpp.vm.Lock;
-import cpp.vm.Tls;
-import cpp.vm.Mutex;
-#elseif java
-import java.vm.Thread;
-import java.vm.Deque;
-import java.vm.Lock;
-import java.vm.Tls;
-import java.vm.Mutex;
-#elseif eval
-import eval.vm.Thread;
-import eval.vm.Deque;
-import eval.vm.Lock;
-import eval.vm.Tls;
-import eval.vm.Mutex;
-#end
+import sys.thread.Thread;
+import sys.thread.Deque;
+import sys.thread.Lock;
+import sys.thread.Tls;
+import sys.thread.Mutex;
 
 class TestThreads extends Test
 {

+ 3 - 3
tests/unit/src/unit/issues/Issue3084.hx

@@ -8,13 +8,13 @@ class Issue3084 extends Test
 	{
 		for (i in 0...40)
 		{
-			var m = new java.vm.Mutex();
-			java.vm.Thread.create(function():Void {
+			var m = new sys.thread.Mutex();
+			sys.thread.Thread.create(function():Void {
 				m.acquire();
 				Sys.sleep(0.01);
 				m.release();
 			});
-			java.vm.Thread.create(function():Void {
+			sys.thread.Thread.create(function():Void {
 				m.acquire();
 				Sys.sleep(0.01);
 				m.release();

+ 2 - 6
tests/unit/src/unit/issues/Issue3767.hx

@@ -1,11 +1,7 @@
 package unit.issues;
 import unit.Test;
-#if java
-import java.vm.*;
-#elseif neko
-import neko.vm.*;
-#elseif cpp
-import cpp.vm.*;
+#if (java || neko || cpp)
+import sys.thread.*;
 #end
 
 class Issue3767 extends Test

+ 2 - 2
tests/unit/src/unit/issues/Issue4878.hx

@@ -1,7 +1,7 @@
 package unit.issues;
 #if java
-import java.vm.Thread;
-import java.vm.Mutex;
+import sys.thread.Thread;
+import sys.thread.Mutex;
 #end
 
 class Issue4878 extends Test {