2/19/2009

02-19-09 - Thread Safety Levels

I am trying to mark up my code with explicit comments about 3 levels of thread safety. I think this is a good concept that I haven't really seen discussed much :

Completely Thread-Safe (CTS) :

This function touches only local variables, objects through locks, objects which are intentionally & safely lock-free, TLS variables, and other stuff that is totally thread safe.

Object Thread-Safe (OTS) :

These functions can touch anything that is CTS, and also can touch any objects passed into them. If the objects passed into them are completely owned by the caller, then they are CTS. Class member functions should typically be OTS for example.

Not Thread-Safe (NTS) :

These functions touch globals or something and are just not thread safe. You must ensure they are run in sequential order.

So, for example, most of my init & shutdown code is NTS. I assume that you do inits, then start threads, then kill threads, then do shutdowns.

It would be really awesome if I could mark up functions in C++ with extra constraints. Then I could stick "CTS" on a function decl and the compiler could tell me if it does anything that doesn't comply with the CTS constraint. OTS can call CTS. NTS can call anything. If CTS calls NTS, it's a compile error.

Another thing that would sure be handy is a way to find all statics and globals. Fucking C++ has reused the reserved words so much, there's no word at all for globals, and "static" is used for so many things it's not a very useful search.

BTW another level that might be needed is Single-Thread-Safe :

These functions are thread-safe only if they are always called from the same thread. That does not necessarilly mean that they are only touching data which that thread exclusively owns - they may be touching shared data, but in a careful way that works only if only one thread is writing the data. One obvious example is the lock-free single-producer data structures. They are not really CTS because if you call Push on them from any thread but the owner you are borked.

9 comments:

Brian said...

A bunch of people are working on pluggable type systems to do this kind of checking. But most of those are for Java.

castano said...

One of the cool things about C# is that you can attach attributes to methods and write analysis tools that process the resulting assemblies and verify those properties.

One of the reasons why I like Qt is because all the classes are properly annotated as reentrant or thread-safe. In Qt terminology reentrant means OTS and thread-safe means CTS.

http://cartan.cas.suffolk.edu/qtdocs/threads.html#reentrancy-and-thread-safety

While this is not the most common definition of "reentrant", it's the one that I like the most.

MH said...

Yeah, I wish C++2xxx had generalized macro language like Ruby or lisp. Just remove the current textual macro beast and replace it with a language level system with similar syntax. Poof.

OpenC++ is supposed to provide something like that, but its ugly.

C#'s is ok, but I dont think you can check this stuff at compile time, only runtime which is nice for some things, but not as useful for others.

cbloom said...

"Yeah, I wish C++2xxx had generalized macro language like Ruby or lisp. Just remove the current textual macro beast and replace it with a language level system with similar syntax. Poof."

Yeah, I often wish for this, and it would be fun to play with, but at the same time I am absolutely terrified of what reading other people's code would be like with this. Code sharing would become much harder as everybody would develop their own metalanguages.

castano said...

"C#'s is ok, but I dont think you can check this stuff at compile time, only runtime which is nice for some things, but not as useful for other"

No, in C# you can easily write your own tool that inspects the compiled assemblies using the .net reflection API or the more powerful Cecil library:

http://www.mono-project.com/Cecil

See for example gendarme:

http://www.mono-project.com/Gendarme.Rules.Concurrency

MH said...

Oh nice, I should have thought of using those tools to write an offline tool to do that kind of checking.

I already use heavy reflection and Attributes in my home apps to do magical things like automatically building network packets, save/load, easy state machines, etc.

Mike said...
This comment has been removed by the author.
Mike said...

RE: Marking functions as thread safe etc

Not sure if you've seen this link.

http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB!207.entry

Hopefully its of use.

Autodidactic Asphyxiation said...

http://www.ibm.com/developerworks/java/library/j-jtp09263.html

People in my neck of the words have started to use terms like hostile, compatible, or safe w.r.t. threads.

old rants