tags:

views:

187

answers:

3

I was going through a re-entrancy guide on recommended practices when writing re-entrant code.

What other references and resources cover this topic?

What lint-like tools can be used to check for these issues?

+1  A: 

None really. Writting non-reentering code is usually more difficult than re-entring. Just follow those simple guidelines and don't try to do anything too waky and you'll be fine.

Non-reentering code is usually written for high-performance issues.

Gianni
+1  A: 

The guide is sufficient.

My personal rule of thumbs are only 2 for re-reentering code:

  1. take only pass by value parameters, used only value passed in as parameters in the function.

  2. if I need to use any global parameters or pointer (for performance or storage sake), use a mutex or semaphore to control access to it.

ttchong
If you need complex types, make them immutable if possible
fmark
Hi fmark: can you explain a further? Or point me to something related to this statement?
ttchong
no No NO! Reentrancy != Threading. Mutexes and semaphores will deadlock reentrant code, or else silently fail to do their job and leave data corruption.
Ben Voigt
@Ben Voigt: agree to your point. "Both concepts of reentrancy and thread safety relate to the way functions handle resources. However, they are not the same.""Reentrancy is a more fundamental property than thread-safety and by definition, leads to thread-safety: Every reentrant function is thread-safe; however, not every thread-safe function is reentrant."
ttchong
The difference between thread safety and reentrancy: http://blogs.msdn.com/b/oldnewthing/archive/2004/06/29/168719.aspx?Ajax_CallBack=true
Adam Rosenfield
Just more clarification here:1. reentrancy - allow function to execute concurrently (e.g. by threads) without blocking on share resources (but a snapshot of the values) or do not need any share resources(result of multiplication of 2 numbers)2. thread safety - arbitrate access to share resources which will cause blocking/queuing in access to resource
ttchong
@ttchong: No, not every reentrant function is thread-safe. Reentrance is often *synchronous*, in that there are only a few controlled points in the code where recursion can occur (or even with asynchronous signals, they may be masked during portions of the code). And signals run fully before the original call resumes. But in concurrent (multi-threaded) environments a second instance of the function can exist anywhere in the execution and both can make progress at the same time, there's no chance for the second invocation to restore state before the first continues.
Ben Voigt
No, that's not what reentrancy means. Concurrency (threads) are not necessary for reentrance. Signals and callbacks are also sources of reentrance.
Ben Voigt
This other question also has a bunch of useful information: http://stackoverflow.com/questions/2799023/what-exactly-is-a-reentrant-function
Ben Voigt
@Ben Voigt: don't quite get your second comment. I do some research to make sure my understanding on concurrency before posting this inquiry. Can you clarify further or point me to something? Thanks.
ttchong
@Ben Voigt: OK got your link. Thanks.
ttchong
Also look at Raymond Chen's blog post that Adam linked to, there are more examples there of functions than are either reentrant or thread-safe but not both.
Ben Voigt
Here's another example of code that is reentrant but not thread-safe. Let's suppose I have two functions that adjust the FPU control word (one needs exceptions enabled, the other needs them disabled). Both functions save the current state of the FPU control word on entry and restore it on exit. Now, these two functions can mutually recurse all day long, you can use them safely from signal handlers too -- they are reentrant. But they are definitely not thread-safe.
Ben Voigt
+1  A: 
  • Do use local variables.
  • Don't use static locals or global variables, even TLS will not help you with recursion / reentrancy.
  • Restore all your invariants before doing callbacks.
  • Don't hold locks while you do callbacks. If you absolutely must (and I would still go looking for a way to avoid it) then make sure you know what happens if you try to re-enter your lock on the thread that already holds it. At a minimum you have to test for this, otherwise depending on the lock you'll get deadlocks or broken invariants (i.e. corruption).
Ben Voigt