Page 1 of 1

reentrancy and display functions

Posted: Fri Sep 19, 2008 6:38 pm
by uglyoldbob
Is it theoretically possible for a display function to be re-entrant?
I know that it can be thread-safe. Maybe I am having a hard time differentiating between reentrant and thread safe. I have looked around and seen explanations for it, but still don't quite understand it.

re-entrant. Code should refer to global or static or non-reentrant code.
thread-safe. Code can refer to anything, as long as protection mechanisms are used (spinlocks).

How can a running function be re-entered without the use of two threads?

I'm thinking it can only go like this.
re-entrant function
int whatever(int a)
{a += 5; return a;}

main{
whatever(4);
...a += 5;
-----interrupt happens during middle of whatever()
whatever(2);
iret
-----back from interrupt
...return a;


Is this even close? Obviously if whatever() uses spinlocks, execution will stop when the interrupt tries to call it.

Re: reentrancy and display functions

Posted: Sat Sep 20, 2008 1:46 am
by cyr1x
No, it can't be reentrant as the display is a global "object".
Functions using global objects can never be reentrant. (read-only is another story)

Re: reentrancy and display functions

Posted: Sat Sep 20, 2008 3:55 am
by bewing
AFAIK, reentrant code never needs locks, or any other concurrency trickery. And that is the difference between reentrance and thread-safe.

Re: reentrancy and display functions

Posted: Sun Sep 21, 2008 7:45 am
by JamesM
uglyoldbob wrote:Is it theoretically possible for a display function to be re-entrant?
I know that it can be thread-safe. Maybe I am having a hard time differentiating between reentrant and thread safe. I have looked around and seen explanations for it, but still don't quite understand it.

re-entrant. Code should refer to global or static or non-reentrant code.
thread-safe. Code can refer to anything, as long as protection mechanisms are used (spinlocks).

How can a running function be re-entered without the use of two threads?

I'm thinking it can only go like this.
re-entrant function
int whatever(int a)
{a += 5; return a;}

main{
whatever(4);
...a += 5;
-----interrupt happens during middle of whatever()
whatever(2);
iret
-----back from interrupt
...return a;


Is this even close? Obviously if whatever() uses spinlocks, execution will stop when the interrupt tries to call it.
Hi,

Bewing and Cyrix have answered your original question, however I believe you still need some clarification of what exactly reentrancy is and where it applies.

Imagine I have the following function:

Code: Select all

int myGlobal = 0; // Global variable
int myfunc(int param)
{
  myGlobal = param;
  param++;
  return myGlobal;
}
Obviously this function is extremely poorly written, however of course as in any example the ideas behind this trivial case extend to less trivial cases also.

Imagine two threads, A & B, are running. Both run this function.

A: Call myfunc(4)
A: myGlobal = 4;
--- Scheduler interrupt - thread is preempted. Thread B now runs.
B: Call myfunc(6)
B: myGlobal = 6;
B: myGlobal++; (myGlobal now = 7);
B: Return myGlobal; (returns 7).
--- Scheduler interrupt, thread A now runs.
A: myGlobal++; (myGlobal now = 8)
A: Return myGlobal; (returns 8).

Notice that because of the race condition, Thread A returns 8 from this function instead of 5, as it should.

This can happen in any function or piece of code that relies on (changing the value or state of) non-thread-local variables. You can get around this problem by either:

a) Making the function reentrant. This means removing use of non-thread-local variables, i.e.

Code: Select all

int myfunc(int param)
{
  return param++;
}
b) Locking, i.e.

Code: Select all

int myfunc(int param)
{
  static spinlock myLock;
  myLock.acquire();
  myGlobal = param;
  myGlobal++;
  
  int buffer = myGlobal; // As soon as we call release(), the thread-safety is lost and myGlobal could change value, so buffer its current value here.
  myLock.release();
  return buffer;
}
Both accomplish the same thing. Video memory is not a thread local resouce, therefore one cannot make a function that uses it reentrant. Only locking can be used in this case.

Cheers.
James