4
$\begingroup$

I am interested in the subject of thread-local contexts, which is a feature that I use quite often in solutions, but seems to lack first-class support in any languages I have used.

Quite often in programming - especially if you are implementing a solution that repeatedly processes similar inputs - it is useful to have access to a thread-local context.

I am sure many are familiar with this problem: the typical case I am taking about is where you have a processing engine taking input messages/requests (e.g., an MDB or a Servlet in Java) that is instantiated individually for several threads, and this engine repeatedly processes the messages using some resources or context that it owns. These resources could be expensive to recreate (and therefore we would like to reuse them), or alternatively, they need to be retained across requests in the thread, but do not need global scope in the application.

In this case, code needs to be able to access that context in an efficient way, but due to the stack+heap-based approach of most languages this is difficult. The current solutions are to either use something like ThreadLocal in Java or to pass a pointer to the context down the stack, both which are not really language constructs, and both of which impose some overhead (and in the second case have practical issues).

It occurs to me that such a thread context is a bit like a second stack. A stack has thread scope and can be efficiently accessed by the thread.

Possibly solutions to implement this in-language might be to maintain the context at the base of the stack; however, this would have to be a fixed size. For a variable sized context, a reference could be stored at the base, but with some loss of efficiency for minimalist requirements. Other options might be possible if the hardware supported multiple stacks per thread.

As a trivial example of what I mean to illustrate the performance impact of existing solutions would be to imagine each "engine" receives a message and then increments a counter (counting the number of messages processed per for each thread). Using ThreadLocal would be many times less efficient that simply incrementing the contents of a known memory address. Even a global counter would require some synchronization and therefore would create a choke point.

A more practical example would be the maintenance of a resource pool such as an object pool where expensive-to-create objects or buffers can be re-used across invocations.

To be clear: this is not really a multi-threading issue, so solutions such as semaphores, etc. are not the solution - on the contrary, they are part of the problem.

A thread-local resource does not need to be shared between threads. It is local, so any solution adding the overhead of synchronization is adding an unnecessary performance penalty.

It would be interesting to know how this might be done (or if it has been done already), with particular consideration to the hardware support available to make it efficient.

$\endgroup$
  • $\begingroup$ I don't fully understand what the question is asking; "thread-local" contexts seem to be covered by almost all procedures that deal with values, rather than references. Additionally, the multi-threaded counter you brought up might not be the best thing if they increment the counter often; updating one memory location over and over again and having behavior dependent on the speed that one can update the memory can theoretically be problematic, right? Having a hierarchy of threads rather than a flat "all-to-one"-like solution can be advantageous in certain situations, right? $\endgroup$ – CinchBlue Apr 19 '16 at 2:17
  • $\begingroup$ @VermillionAzure the counter is not "multithreaded". There is one per thread. It is just an example, but something that is hard to do on existing systems. $\endgroup$ – rghome Apr 19 '16 at 16:39
  • $\begingroup$ Comments are not for extended discussion; this conversation has been moved to chat. $\endgroup$ – Gilles 'SO- stop being evil' Apr 22 '16 at 10:02
2
$\begingroup$

One example of a language system built from bottom up to support this kind of situation is Erlang. It is well worth looking into.

It is built around the concept that you create a lot of tasks. The tasks never share variables and only communicates via messages. The task has a "thread-local" context which is maintained using a very specific construct of tail-recursion. It is not uncommon to have thousands or even millions of task in a Erlang system.

Erlang comes with a set of constructs and tools known as OTP which helps in handling a number of common situation in soft real time systems. I especially like how it allows you to update the programs in a running system on the fly.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.