re-entrant function????????

T

thesushant

hi,

can anyone of C masters siting out there suggest any 1 example of
re-entrnt function just to show what is the significance of that
property and how we can exploit it ....

sushant
 
Y

Yan

hi,

can anyone of C masters siting out there suggest any 1 example of
re-entrnt function just to show what is the significance of that
property and how we can exploit it ....

sushant

that becomes an issue when using/writing multi-threading code. If a
function relies on static data, and is called while another thread has
already called it and is executing, that static data may be changed by
different threads and produce unexpected results
 
C

CBFalconer

can anyone of C masters siting out there suggest any 1 example of
re-entrnt function just to show what is the significance of that
property and how we can exploit it ....

#include <stdio.h>

int putword(unsigned long w, FILE *f)
{
if (w > 9)
if (0 > putword(w / 10, f)) return EOF;
return putc((w % 10) + '0', f);
} /* putword */

/* --------------- */

#ifdef TESTING

#include <stdlib.h>

int main(void)
{
int i;

for (i = 0; i < 10; i++) {
putword(i, stdout);
putc(' ', stdout);
putword(rand(), stdout);
putc('\n', stdout);
}
return 0;
} /* main */
#endif
 
T

Trent Buck

Up spake (e-mail address removed):
can anyone of C masters siting out there suggest any 1 example of
re-entrnt function just to show what is the significance of that
property and how we can exploit it ....

This is re-entrant

int
f (int x)
{
int y;

y = x * x;
return y;
}

This is not

int y;

int
f (int x)
{
y = x * x;
return y;
}

Another example of re-entrant vs. non-reentrant functions is strtok_r
vs. strtok.

As the OP said, it becomes an issue when you have multiple threads
(lightweight processes) in a single process, because (some) state is
shared between multiple threads of execution.

The canonical example is

int x;
void f (void) { x++; }

with two threads executing f(). The ++ operation (typically) resolves
into three assembly instructions: copy-memory-to-register,
increment-register, and copy-register-to-memory.

Consider, for example, the situation where first thread executes the
first two instructions, then the second thread executes all three, then
the first thread executes the last instruction. The second thread's
change will be lost, and the contents of memory at that address will be
incorrect.

This class of bugs are a PITA to locate, because symptoms are
intermittent and therefore difficult to reproduce.
 
P

pete

CBFalconer said:
#include <stdio.h>

int putword(unsigned long w, FILE *f)
{
if (w > 9)
if (0 > putword(w / 10, f)) return EOF;
return putc((w % 10) + '0', f);
} /* putword */

Standard library functions aren't guaranteed to be reentrant, so,
a function which calls putc can't be guaranteed to be reentrant.
 
T

Thomas Stegen

pete said:
Standard library functions aren't guaranteed to be reentrant, so,
a function which calls putc can't be guaranteed to be reentrant.

More importantly imo is that putc has a side effect on the file and so
the function is not reentrant even on an implementation where putc is
reentrant.
 
D

dandelion

As the OP said, it becomes an issue when you have multiple threads
(lightweight processes) in a single process, because (some) state is
shared between multiple threads of execution.
<snip>

Minor nitpick:

Reentrancy is not just a multi-threading (lightweight processes) issue, but
arises whenever two threads of execution have access to some common
function. Apart from the example given, this may also happen in Interrupt
Service Routines (ISR's) or multitasking environments wich allow concurrent
access to a shared resource.
 
E

Eltee

dandelion said:
<snip>

Minor nitpick:

Reentrancy is not just a multi-threading (lightweight processes) issue, but
arises whenever two threads of execution have access to some common
function. Apart from the example given, this may also happen in Interrupt
Service Routines (ISR's) or multitasking environments wich allow concurrent
access to a shared resource.

Pardon me but ... are reentrancy, multi-threading, ISR's and multitasking really
a part of ISO C specification?
 
D

dandelion

Eltee said:
Pardon me but ... are reentrancy, multi-threading, ISR's and multitasking really
a part of ISO C specification?

Reentrancy is, for the simple reason that the standard lib is not guaranteed
to be reentrant (and that is, IIRC, part of the standard). A further
discussion of "reentrancy" brings on the other subjects.

So while not being part of the standard, they (multithreading, ISR's and
shared resources) are topical in this limited treatment.
 
E

Eltee

dandelion said:
Reentrancy is,

Would you point some fingers, please? Where can I find the ISO C specification
and, specificaly, where does it say anything about reentrancy?
 
D

dandelion

Eltee said:
Would you point some fingers, please? Where can I find the ISO C specification
and, specificaly, where does it say anything about reentrancy?

http://www.iso.org, the costs are 340 swiss franks.

<quote 5.2.3>
[#1] Functions shall be implemented such that they may be
interrupted at any time by a signal, or may be called by a
signal handler, or both, with no alteration to earlier, but
still active, invocations' control flow (after the
interruption), function return values, or objects with
automatic storage duration. All such objects shall be
maintained outside the function image (the instructions that
compose the executable representation of a function) on a
per-invocation basis.
</quote>

<quote 7.1.4>
[#4] The functions in the standard library are not
guaranteed to be reentrant and may modify objects with
static storage duration.146)
</quote>
 
X

Xenos

dandelion said:
Minor nitpick:

Reentrancy is not just a multi-threading (lightweight processes) issue, but
arises whenever two threads of execution have access to some common
function. Apart from the example given, this may also happen in Interrupt
Service Routines (ISR's) or multitasking environments wich allow concurrent
access to a shared resource.
You are getting too caught up in terminology. An interrupt *is* a thread of
execution.

DrX
 
R

Richard Tobin

Xenos said:
You are getting too caught up in terminology. An interrupt *is* a thread of
execution.

Maybe. Or maybe it's just an involuntary function call. It depends
on your interrupts.

-- Richard
 
C

CBFalconer

pete said:
Standard library functions aren't guaranteed to be reentrant, so,
a function which calls putc can't be guaranteed to be reentrant.

True. Which points out that we need a putc call guaranteed to be
atomic, i.e. non-interuptable. All of which is OT here.
 
C

CBFalconer

Thomas said:
More importantly imo is that putc has a side effect on the file
and so the function is not reentrant even on an implementation
where putc is reentrant.

That side effect is under control, since f is a parameter.
putword, and even for that matter putc, can be interrupted and
called again, provided only that the parameters are different.
However if the function used putchar the criticism is valid.
 
D

dandelion

You are getting too caught up in terminology. An interrupt *is* a thread of
execution.

That was the point. I was responding to a post which seemed to suggest only
lightweight processes have reentrancy issues.
 
X

Xenos

Richard Tobin said:
Maybe. Or maybe it's just an involuntary function call. It depends
on your interrupts.
Again, it doesn't matter. It's still a particular order of executing
instructions. What you choose to call it or how it is implemented is
relevant. It is still a thread of execution. A thread of execution is not
exclusive to a so called multi-threaded environment, or the use of "thread"
for a light-weight process. A process, interrupt, or even the execution of
a C signal or C++ exception, are all threads of execution, that may or may
not execute within the context of a given process, process thread, process
fiber, or whatever.
 
E

Eltee

dandelion said:
multitasking


Would you point some fingers, please? Where can I find the ISO C
specification

and, specificaly, where does it say anything about reentrancy?


http://www.iso.org, the costs are 340 swiss franks.

<quote 5.2.3>
[#1] Functions shall be implemented such that they may be
interrupted at any time by a signal, or may be called by a
signal handler, or both, with no alteration to earlier, but
still active, invocations' control flow (after the
interruption), function return values, or objects with
automatic storage duration. All such objects shall be
maintained outside the function image (the instructions that
compose the executable representation of a function) on a
per-invocation basis.
</quote>

<quote 7.1.4>
[#4] The functions in the standard library are not
guaranteed to be reentrant and may modify objects with
static storage duration.146)
</quote>

Thanks.

Now, as we established that reentrancy is not entirely off topic, may I inquire
as to which implementations of a standard library are, in fact, reentrant
inspite of the above ISO "not guaranteed" guideline? GNU? Intel? M$? Borland? etc?
 
D

dandelion


My pleasure.
Now, as we established that reentrancy is not entirely off topic, may I inquire
as to which implementations of a standard library are, in fact, reentrant
inspite of the above ISO "not guaranteed" guideline? GNU? Intel? M$?
Borland? etc?

Dunno. Frankly I would not count on any of them being reentrant. If you _do_
find a reentrant version and count on that, someone, somewhere, sometime is
going to compile your program with some other (non-reentrant) library.

And that's when the big, ugly brutes of bugs crawl out of the woodwork. So
(privately) I'll treat them *all* as being 'non-reentrant', which has not
been a major problem.
 
E

Eltee

dandelion said:
My pleasure.



Borland? etc?

Dunno. Frankly I would not count on any of them being reentrant. If you _do_
find a reentrant version and count on that, someone, somewhere, sometime is
going to compile your program with some other (non-reentrant) library.

And that's when the big, ugly brutes of bugs crawl out of the woodwork. So
(privately) I'll treat them *all* as being 'non-reentrant', which has not
been a major problem.

So you guys always use synchronized wrappers around stdlib functions? I mean,
common "operations" such as malloc, sprintf? That's news to me, cause I haven't
written a synchronized wrapper around a malloc, yet. Consequently, my entire "c
opus" ;-) is useless as far as multi-threadedness is concerned? Bummer!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top