Skip to content

[cpp] Typed Thread and TLS#12885

Open
Aidan63 wants to merge 2 commits intoHaxeFoundation:developmentfrom
Aidan63:cpp-typed-thread
Open

[cpp] Typed Thread and TLS#12885
Aidan63 wants to merge 2 commits intoHaxeFoundation:developmentfrom
Aidan63:cpp-typed-thread

Conversation

@Aidan63
Copy link
Copy Markdown
Contributor

@Aidan63 Aidan63 commented Apr 28, 2026

HaxeFoundation/hxcpp#1336

This is much the same as my other threading related updates, adding a typed api for threads and thread local storage on the cpp side and exposing them in haxe. The main changes are.

  • Typed hx::thread::Thread api for spawning, current thread, etc. This now supports the thread name setting which was recently added, although this is only implemented on Windows.

Important note on the Windows implementation, it uses the modern GetThreadDescription and SetThreadDescription Win32 api which was added in Windows 10. So this does add a Windows 10 hard dependency to hxcpp. I'm not fussed about this but it's probably worth mentioning in case anyone is.
There is also an implementation difference here which is also worth noting. In the old implementation hxcpp would immediately detach the thread, but we keep the thread attached now until the haxe object is finalised since you can't set the description of a detached thread. This was fine on Windows, but the hxcpp "haxe" tests (not haxe repo tests) on 32bit Linux were failing due to a "lack of resources" (creating too many threads). One of the tests spins up a bunch of threads and seems to be hitting a OS limit now that threads aren't detached until finalisation, since only name setting is implemented on Windows I've made it eagerly detach threads on other OS'.

  • Typed hx::thread::ThreadLocal api for thread local storage.

This implementation has changed slightly, instead of using an ever growing counter, TLS objects return their slot ID when finalised so they can be recycled. This should hopefully help reduce the TLS array from constantly growing in long lived programs.

  • New Scratch api

Something I've wanted for a while is to be able to create short lived (tied to the current scope) non GC memory for various introp cases (e.g. encoding haxe strings or arrays before passing to native code). Normally you would do this with c arrays or std::array but the constant / compile time size requirement makes this a pain in haxe.
The scratch api provides this sort of functionality, each thread contains a buffer which the scratch api simply bump allocates out of. Since this uses the cpp.Marshal.View type and stack only flags these scratch allocations can't escape the current thread so are safe to be reference counted.

For example the following is a code snipped which parses a date out of a string with zero GC allocations (and without needing to do all the manual string indexing you'd need to do).

class DateConverter {
	public static inline function toDate(string:String) {
		final view   = string.asCharView();
		final buffer = Scratch.alloc(Range.sizeof() * 3).view.reinterpret();

		switch view.length {
			case 8:
				if (3 != view.split(':'.code, buffer)) {
					throw new Exception("");
				}

				final hh = view.slice(buffer[0].start, buffer[0].end - buffer[0].start).parseInt(None);
				final mm = view.slice(buffer[1].start, buffer[1].end - buffer[1].start).parseInt(None);
				final ss = view.slice(buffer[2].start, buffer[2].end - buffer[2].start).parseInt(None);

				return
					Date.fromTime(
						hh * 3_600_000f64 + mm + 60_000f64 + ss * 1000f64);
			default:
				throw new NotImplementedException();
		}
	}
}

Like the others the hxcpp side needs to be merged before the cpp tests on the haxe side will pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant