crashappsec / libcon4m

Base Compiler and Runtime Support for con4m
Apache License 2.0
0 stars 0 forks source link

Move away from using __thread for thread-local storage in Hatrack #25

Closed orangematt closed 2 months ago

orangematt commented 2 months ago

The work here is mainly to remove the dependency on __thread in Hatrack. Dependencies in con4m itself remain, but will be addressed later. However, there are other, smaller related threading changes here as well. Overall, the goal is to be more friendly to many environments, including embedded environments that may not have pthreads or __thread support available.

There is a new config option to disable all pthread support. The core of Hatrack does not require it, but a handful of algorithms do use it. They'll be skipped if HATRACK_NO_PTHREAD is defined. If this is defined, the host must either define a tis access function, or not use the implicit tis APIs. The tis access function is new, as is the distinction between implicit and explicit tis APIs.

Mainly the work here is to split most of the public APIs into explicit / implicit versions. This means that the explicit versions are passed a thread-local struct as a parameter, while the implicit versions are not. The implicit versions use a tis access function that can be defined by the host to get the needed thread-local struct. The implicit versions are the same functions that always existed. It's the explicit functions that are new, and they all are named the same as the corresponding implicit function, but with a _mmm suffix.

For the explicit functions with the added mmm_thread_t * parameter, there's no great place to put the parameter that feels right for all cases. I've chosen to make it the second parameter in all cases. The rationale for this is that it's a fixed parameter, present for all functions, like the primary object being operated on. The primary object being operated on should always be the first parameter, so it follows that the second parameter should be the tis pointer. Everything after that is highly variable, dependent on the function.

By default, there is a tis acquisition function defined if pthread support is enabled (the default). This implementation uses the pthread API for thread-specific data and takes care of its own cleanup when threads exit.

Most users of the Hatrack API will use the implicit API with the default tis acquisition function, and so they need to do nothing special, nor concern themselves with any of this. Most of what's been done here is for atypical use cases.