Reentrancy of newlib funktions

OP #1173941
Hello,

I have a little problem with my system (TMS470 & WinArm-GCC Version
20070505
  & Eclipse). I have a program with min. 9 threads and when it runs in a
debug session it works fine. But when it runs in release version it get
an reset. I have set a breakpoint at my boot up and so I could read the
lr register. When I stop in error I see that impure_data calls my
thread. In the newlib documentation is a descriptionon of reentrancy,
but I don´t understand what I have to do. Needs every thread an own
struct _reent ? How do I call the funktion? Which funktion I have to
call _iprintf_r or iprintf? I couldn't find an example anywhere.
I hope somebody can help me.
Thanks Andrea
The reentrancy support in syscalls is primarily to provide a
thread-local copy of errno (otherwise a failing function in one thread
could set a global errno being checked in another thread). If you never
use errno, I don't think you need worry. It is possible to add your own
thread-local data to _reent, but it is not necessary. In my system I
simply do not rely on errno being valid - i.e. I ignore it. And I have
in excess of 40 tasks.

Some standard library functions are inherently non-reentrant because
they use static data, such as strtok(). That is the putpose of
strtok_r() for example.

What makes you suspect that reentrancy is a problem? If the problem
manifests itself when optimization is enabled, it is far more likely
that you have failed to declare some shared data volatile.

You also need to ensure that access to non-atomic shared data is
protected by a mutual exclusion mechanism or is thread-locked.

Clifford
OP
I thought, I have a problem with reentrancy, because in debugmode
(optimization is enabled) I saw that my thread was called from
impure_data(). Yesterday I insert for eacht task an own reent struct but
my system still gets a reset :-(
Regrettably I am at a loss.
Andrea Runge wrote:
> I thought, I have a problem with reentrancy, because in debugmode
> (optimization is enabled) I saw that my thread was called from
> impure_data(). Yesterday I insert for eacht task an own reent struct but
> my system still gets a reset :-(
> Regrettably I am at a loss.

And about shared data? Is it declared volatile?

You did not say what you were using to implement threads (RTOS or
scheduler oe whatever).
A further thoughts, a common cause of crashing in a multi-threaded
application is stack overflow.

How much stack have you allocated to each thread?

Bear in mind that formatted I/O functions such as printf() - and
probably iprintf() too - usually require a relatively large stack (in
excess of 4 Kbytes in my experience). That's a significant amount of
memory on a typical micro controller with on-chip RAM.

The fact that this occurs only when you use optimisation is irrelevant,
since the effect of a stack overflow is entirely non-deterministic, it
depends what gets corrupted and when, and the different memory
organisation and usage patterns in an optimised build will result in
different non-deterministic behaviour. It was just as likely to be the
other way around.

The fact that your thread appears to be called from an unlikely source
is a fair indicator of stack corruption.

Clifford
OP
At next I'll prove my shared data again. Maybe I have forgot anyone.
I use FreeRtos to implement threads. My tasks have different stack size
depending on functionality. I use the funktion vTaskList to display the
remain stacksize. A problem is that the TMS470 has only 64k RAM and so
I use an extra extern RAM with 512k RAM. For testing I 'll comment out
all iprintf's.
I hope, I would find the bug soon. In the meantime I feel blue :-(
Andrea Runge wrote:
> I'm so happy!!! I've comment out all iprintf's and it works :-) One
> thread gets a stack overflow.
> Many, many thanks!!!!!

As I said formatted I/O is expensive (and that includes sprintf and the
'v' variants such as vprintf). Some solutions you might consider:

1) Use a 'lean' alternative, of which there are several.

2) Use plain unformatted string output - puts() or a lower level
function, with a few data type specific functions  convert data t
strings.

3) Create a server thread that receives print requests via a message
queue, so that formatted I/O is restricted one thread with a larger
stack, rather than allocating the stack to all threads.

The last suggestion has the benefit of serializing the output so
multiple threads cannot 'interleave' their output. It also has the
advantage - by using fprintf() - of being able to easily redirect the
output to other devices, such as a file system. However the variable
argument list may have to go to simplify installation. The interface
would look rather like VxWorks' logLib:
http://www-kryo.desy.de/documents/vxWorks/V5.4/vxworks/ref/logLib.html

Clifford

Reply

A question of your own? This thread is over 18 years old. Ask it in a thread of its own – more people read along there, and it gets answered more often and sooner.

Start a new thread

A fix, an addition or feedback on this thread? Then reply here.

Formatting
  • [c]C-Code[/c]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]
  • [[Title]] – link to an article
  • Link to another post: right-click its post ID (#8078628), copy the address, paste it into the text

More about formatting

Post long source code as an attachment, not in the text.

Already registered? Log in

Not shown to anyone. We send you a link; your post appears once you confirm it there.

By submitting you create a free account and accept the terms of use.