7

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?

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
Fanatic23
  • 3,378
  • 2
  • 28
  • 51
  • That guide pretty much has everything you need to know. It's not a very subtle thing. Don't use data that you weren't passed in the function call, don't store any state in the function. – Stephen Canon Jul 14 '10 at 02:13
  • 2
    That guide has numerous errors in it, from a definition of reentrancy that's actually multithreading (though the signal processing examples are true reentrancy) to bad advice (mutexes... hello deadlock) to just plain bugginess (`sigsuspend(&zeromask)` .. you've just allowed processing interrupts that your caller disabled for a reason, try `sigsuspend(&oldmask)` instead). – Ben Voigt Jul 14 '10 at 02:22

4 Answers4

2
  • 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
  • 277,958
  • 43
  • 419
  • 720
1

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
  • 4,300
  • 18
  • 24
0
  1. A reentrant function may not use variables in a non-atomic way unless they are stored on the stack of the calling task or are the private variables of that task.
  2. A reentrant function may not call other functions which are not reentrant.
  3. A reentrant function may not use the hardware in a non-atomic way.

Ref: Page 462 [AN INTRODUCTION USING THE RENESAS RX62N MICROCONTROLLER] [James M. Conrad]

Osaid
  • 557
  • 1
  • 8
  • 23
0

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
  • 307
  • 2
  • 9
  • If you need complex types, make them immutable if possible – fmark Jul 14 '10 at 02:06
  • Hi fmark: can you explain a further? Or point me to something related to this statement? – ttchong Jul 14 '10 at 02:09
  • 10
    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 Jul 14 '10 at 02:16
  • @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 Jul 14 '10 at 02:26
  • The difference between thread safety and reentrancy: http://blogs.msdn.com/b/oldnewthing/archive/2004/06/29/168719.aspx?Ajax_CallBack=true – Adam Rosenfield Jul 14 '10 at 02:29
  • 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 Jul 14 '10 at 02:33
  • @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 Jul 14 '10 at 02:34
  • No, that's not what reentrancy means. Concurrency (threads) are not necessary for reentrance. Signals and callbacks are also sources of reentrance. – Ben Voigt Jul 14 '10 at 02:36
  • This other question also has a bunch of useful information: http://stackoverflow.com/questions/2799023/what-exactly-is-a-reentrant-function – Ben Voigt Jul 14 '10 at 02:40
  • @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 Jul 14 '10 at 02:41
  • @Ben Voigt: OK got your link. Thanks. – ttchong Jul 14 '10 at 02:42
  • 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 Jul 14 '10 at 02:53
  • 2
    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 Jul 14 '10 at 03:05
  • @BenVoigt it depends on the definition of re-entrant code. If it include re-entry from other threads, it would imply that re-entrant code are automatically thread safe. – Chethan Mar 21 '13 at 09:36
  • 2
    @Chethan: If you use incorrect definitions of standard terminology, you can make any statement correct. But also meaningless. – Ben Voigt Mar 21 '13 at 16:45
  • @BenVoigt as wikipaedia says, the term was defined long ago there there were only single threaded environments and interrupts. If you want to stick to that definition - sure. Please read the re-entrancy guide in the Q. – Chethan Mar 22 '13 at 09:23
  • @Chethan: Please read my comment on this Q. That guide is not worth the bits it's encoded in. – Ben Voigt Mar 22 '13 at 14:23
  • Point number 2 in this answer is dangerous! If your function needs to take a mutex then it is not re-entrant (consider the case where a signal arrives while your function holds the mutex, and then the signal handler calls your function). – Gareth Rees Feb 21 '15 at 13:09