<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://community.arm.com/utility/feedstylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>re-entrant code</title><link>https://community.arm.com/developer/tools-software/tools/f/keil-forum/37512/re-entrant-code</link><description> 
what is a re-entrant code? 
again what is re-entrant kernel? 

 
thank you 
ece tech 
 </description><dc:language>en-US</dc:language><generator>Telligent Community 10</generator><item><title>RE: re-entrant code</title><link>https://community.arm.com/thread/144309?ContentTypeID=1</link><pubDate>Sun, 11 Nov 2007 11:29:12 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:07002f7e-b03c-40e2-a296-eb704c666396</guid><dc:creator>erik  malund</dc:creator><description>&lt;p&gt;&lt;p&gt;
&lt;i&gt;Now: let&amp;#39;s say I need to use reentrancy. There are several
flavors of it: ISR-safe, thread-safe, recursion-safe, let&amp;#39;s say I
need something that is thread-safe. Say I&amp;#39;m using RTX51.&lt;/i&gt;&lt;br /&gt;
While the &amp;#39;51, since it is programmable, &lt;i&gt;is&lt;/i&gt; capable of
operating with a RTOS the jumping through hoops the &amp;#39;51 architecture
requires makes the &amp;#39;51 (with the exception of some PIGs, I guess) the
worst possible choice for an application that requires a RTOS. When
you then add reentrancy which, again, does not fit the &amp;#39;51
architecture you get problms piled on top of problems.&lt;/p&gt;

&lt;p&gt;
&lt;i&gt;This begs the question: is there a finite checklist that I can
check my code against, to ensure it is reentrant
(thread-safe)?&lt;/i&gt;&lt;br /&gt;
yes, 1) check that no RTOS is involved and 2) do not call functions
from ISRs.&lt;/p&gt;

&lt;p&gt;
you &lt;i&gt;can&lt;/i&gt;, since the &amp;#39;51 is programmable, of course use both
a RTOS and reentrant functions, but with all the concern you seems to
have about &amp;quot;ensuring&amp;quot; I would strongly advise aganst it.&lt;/p&gt;

&lt;p&gt;
Erik&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: re-entrant code</title><link>https://community.arm.com/thread/141891?ContentTypeID=1</link><pubDate>Sun, 11 Nov 2007 10:37:31 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:35112863-9134-4222-be76-0b6dea84f012</guid><dc:creator>Georget Stephane</dc:creator><description>&lt;p&gt;&lt;p&gt;
Hello Per,&lt;/p&gt;

&lt;p&gt;
Sometimes, reentrancy is needed. Sometimes, it is not. Sometimes,
as in the case of the C51 MCU, it makes sense, from an architectural
point of view, to ban anything that uses reentrancy, I agree with all
that.&lt;/p&gt;

&lt;p&gt;
Now: let&amp;#39;s say I need to use reentrancy. There are several flavors
of it: ISR-safe, thread-safe, recursion-safe, let&amp;#39;s say I need
something that is thread-safe. Say I&amp;#39;m using RTX51.&lt;/p&gt;

&lt;p&gt;
Reentrancy cannot be tested. Wicca does not work either. So I will
have to be careful about what I write.&lt;/p&gt;

&lt;p&gt;
This begs the question: is there a finite checklist that I can
check my code against, to ensure it is reentrant (thread-safe)?&lt;/p&gt;

&lt;p&gt;
Steph-&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: re-entrant code</title><link>https://community.arm.com/thread/138603?ContentTypeID=1</link><pubDate>Sun, 11 Nov 2007 10:13:12 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:67288439-d405-41bb-8259-458d3de02623</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
But the question here is: why do you need reentrancy?&lt;/p&gt;

&lt;p&gt;
If you write a thread-safe c library, where the functions should
be called from multiple threads, then you need it. And you also need
it if you want to call the same function from both an interrupt
service routine and a main application.&lt;/p&gt;

&lt;p&gt;
You need a little bit simpler form of reentrant-safe if the
function is part of a recursive chain - in that case you don&amp;#39;t have
to worry about atomicity of instructions.&lt;/p&gt;

&lt;p&gt;
The C51 architecture isn&amp;#39;t the worlds most powerful, so a lot of
applications are implemented without an RTOS. Just a super-loop and a
number of ISR. An ISR should be as fast as possible, so normally
don&amp;#39;t call any functions.&lt;/p&gt;

&lt;p&gt;
In the end, there isn&amp;#39;t too much need for reentrant functions on
the C51 architecture.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: re-entrant code</title><link>https://community.arm.com/thread/135210?ContentTypeID=1</link><pubDate>Sun, 11 Nov 2007 09:52:26 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:401d7bb9-bfc3-48e6-9ce0-d5a695e15468</guid><dc:creator>Georget Stephane</dc:creator><description>&lt;p&gt;&lt;p&gt;
Hello,&lt;/p&gt;

&lt;p&gt;
&lt;i&gt;You are making it too hard! Reentrant functions are not black
magic :)&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;
All I&amp;#39;m trying to say is that the design of a reentrant function
requires extra attention, i.e. extra time and money, because
reentrancy problems are usually very hard to troubleshoot, so it&amp;#39;s
best to get it right the first time. Hence my feeble attempt to draw
a checklist to test for reentrancy (using elbow grease, since there
is no software to do that for me).&lt;/p&gt;

&lt;p&gt;
Agreed that there is no black magic wizardry involved there. I
couldn&amp;#39;t find any entry on reentrancy in my book of shadows. That
said, it&amp;#39;s a rather old edition...&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: re-entrant code</title><link>https://community.arm.com/thread/138606?ContentTypeID=1</link><pubDate>Sun, 11 Nov 2007 08:11:00 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:4f5351c0-f5fd-4e77-bc0b-43b9aef5801e</guid><dc:creator>erik  malund</dc:creator><description>&lt;p&gt;&lt;p&gt;
To make Per happy:&lt;br /&gt;
This relates to the &amp;#39;51&lt;br /&gt;
Since the OP started the thread with C51 I have changed MCU back to
the C51 to stay with the OPs intent.&lt;/p&gt;

&lt;p&gt;
I have never used reentrant code. Yes, I have had cases where it
might have been desirable (e.g. a function shared by an ISR and main)
but the potential debugging nightmare has kept me from using
reentrant code.&lt;/p&gt;

&lt;p&gt;
I think the OPs worry that he &amp;#39;might&amp;#39; have reentranr code is
greatly overblown. Just make sure that all functions called from ISRs
(if you &lt;i&gt;absolutely&lt;/i&gt; have to have them) have names that are e.g.
ISR..... and no ISR.... function is called from main.&lt;/p&gt;

&lt;p&gt;
Erik&lt;/p&gt;

&lt;p&gt;
PS the one &amp;#39;51 case I can see for reentrant code would be to &amp;#39;core
use squeeze&amp;#39; a unit that was to be made in millions.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: re-entrant code</title><link>https://community.arm.com/thread/135202?ContentTypeID=1</link><pubDate>Sun, 11 Nov 2007 01:16:59 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:6d55db5f-d3f9-4356-a2be-6d2545c7d802</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
You have to realize that when talking about global variables, the
problem is more about architecture than the used code-generating
tool.&lt;/p&gt;

&lt;p&gt;
Most architectures can read an 8-bit variable atomically. But can
they read a 16-bit, 32-bit or 64-bit variable atomically?&lt;/p&gt;

&lt;p&gt;
Some architectures can increment a memory variable atomically,
while other architectures may need a load + increment + store. If the
variable is too large to increment directly, then the code-generating
tool (any tool - or yourself, using assembler) will have to care
about overflow rippling to the upper parts of the variable - for
example by adding extra add-with-carry steps.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: re-entrant code</title><link>https://community.arm.com/thread/124222?ContentTypeID=1</link><pubDate>Sat, 10 Nov 2007 17:26:58 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:c4894df0-5840-4338-9a1f-5b904cccf490</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
You are making it too hard! Reentrant functions are not black
magic :)&lt;/p&gt;

&lt;p&gt;
You can write reentrant code in C. On some architectures, the
compiler will directly generate code that is reentrant (this still
requires that the developer takes care of accesses to global/static
resources). On some architectures, you have to specifically tell the
compiler to generate reentrant code. A C51 compiler normally produces
non-reentrant code, specifically because of limitations of the C51
architecture.&lt;/p&gt;

&lt;p&gt;
You can have a reentrant function read and write to global
resources. It is just a question of making sure that the function
always gives predictable results even if having two concurrent calls
active. For axample: A pseudo-random number generator must have code
to atomically read its old seed and update it with a new value, to
make sure that two concurrent calls doesn&amp;#39;t result in the same random
number. malloc()/free() or new/delete must protect internal lists of
used/released memory.&lt;/p&gt;

&lt;p&gt;
The compiler vendor documentation will tell if floating-point
code, and memory allocation functions etc are reentrant or not.&lt;/p&gt;

&lt;p&gt;
But as already noted: C51 is not an architecture that likes
reentrant functions! You really want the compiler to convert
parameters and local variables to reusable global variables because
of size and efficiency!&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: re-entrant code</title><link>https://community.arm.com/thread/113384?ContentTypeID=1</link><pubDate>Sat, 10 Nov 2007 16:41:58 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:0fd43f3a-030b-49e9-9d19-485bafc33748</guid><dc:creator>Georget Stephane</dc:creator><description>&lt;p&gt;&lt;p&gt;
Per wrote:&lt;/p&gt;

&lt;p&gt;
&lt;i&gt;You don&amp;#39;t test for reentrancy. You specifically develop with
that in mind. Reentrancy is a factor of what resources the function
makes use of, and how it uses them.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;
That&amp;#39;s unfortunately what I&amp;#39;m thinking too; and that&amp;#39;s a scary
fact. I have the feeling that automatic test code that would test for
reentrancy would be more difficult to write than the tested code
itself.&lt;/p&gt;

&lt;p&gt;
Therefore, is it safe to say that, a few high-level ways to prove
that code is reentrant are:&lt;/p&gt;

&lt;p&gt;
- by doing a code review&lt;/p&gt;

&lt;p&gt;
- by having the code generated automatically by a tool that is
proven to produce reentrant code&lt;/p&gt;

&lt;p&gt;
- ... anything else?&lt;/p&gt;

&lt;p&gt;
And then, we could say that the code review would check, amongst
other things:&lt;/p&gt;

&lt;p&gt;
- code does not call non-reentrant code&lt;/p&gt;

&lt;p&gt;
- inspected code must be assembly. When inspecting C, one must
mentally process every line and imagine what the assembly code would
be in the end.&lt;/p&gt;

&lt;p&gt;
- keeping in mind that in C, some casts, floating point
calculations, etc. will in turn call a function in a library, which
itself must have been designed for reentrancy. In C++, add to this
the army of operators like new delete etc.&lt;/p&gt;

&lt;p&gt;
- none of the variables that are changed by the reentrant code,
can have a fixed address in RAM. That means no &amp;quot;static&amp;quot; variables in
C&lt;/p&gt;

&lt;p&gt;
- there will inevitably be a few lines of code that simply cannot
be made reentrant, in which case additional protection mechanism must
be used to make sure that it will not be re-entered. Like disabling
interrupts, to the cost of increasing interrupt latency.&lt;/p&gt;

&lt;p&gt;
- self modifying code is not reentrant&lt;/p&gt;

&lt;p&gt;
- ... ok: what else?&lt;/p&gt;

&lt;p&gt;
Steph-&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: re-entrant code</title><link>https://community.arm.com/thread/138602?ContentTypeID=1</link><pubDate>Sat, 10 Nov 2007 07:00:55 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:64beb673-5d3b-4757-a6dc-cd6e35bfea02</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
It doesn&amp;#39;t matter if a thread is about a specific architecture. If
the answer sounds general, the OP may assume that the answer really
is valid for other architectures too.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: re-entrant code</title><link>https://community.arm.com/thread/135200?ContentTypeID=1</link><pubDate>Sat, 10 Nov 2007 06:42:26 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:566581e4-85c8-4fa7-8279-0bdc5a917dfb</guid><dc:creator>erik  malund</dc:creator><description>&lt;p&gt;&lt;p&gt;
&lt;i&gt;when specifically talking about a C51 processor&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;
I am posting based on that. I see no reason to mention that this
is specifically about the C51 when the architecture window states
C51.&lt;/p&gt;

&lt;p&gt;
Erik&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: re-entrant code</title><link>https://community.arm.com/thread/124220?ContentTypeID=1</link><pubDate>Fri, 09 Nov 2007 14:17:23 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:a52ae48e-76b0-468f-8995-b7b030f108f0</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
Erik is a bit rough, but when specifically talking about a C51
processor (it doesn&amp;#39;t have a real generic stack), reentrancy costs a
lot.&lt;/p&gt;

&lt;p&gt;
For a C51, most parameters and function-local variables are
converted to global variables by the compiler and linker. A reentrant
function can not have it&amp;#39;s parameters or local variables converted to
global variables since each active instance of the function must have
a separate set of variables. That&amp;#39;s the rule I mentioned in my
earlier post about reentrant functions often needing syncronized read
and/or write access to global resources.&lt;/p&gt;

&lt;p&gt;
In short, making a function reentrant on a C51 processor costs
memory, code size and speed. Few functions really need to be
reentrant. It is better to create several copies of the same
function. One copy to call from the main loop, and one copy to call
from an interrupt handler. Especially if the interrupt handler are
already using a different register bank.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: re-entrant code</title><link>https://community.arm.com/thread/124219?ContentTypeID=1</link><pubDate>Fri, 09 Nov 2007 14:06:56 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:2d903192-46da-4703-b823-d2e4a166aa5a</guid><dc:creator>Christoph Franck</dc:creator><description>&lt;p&gt;&lt;p&gt;
&lt;i&gt;stay away from reentrancy.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;
To be more precise - on a &amp;#39;51, stay away from situations where you
may need reentrant functions (e.g. recursive functions,
multithreading, calling the same function in ISRs and the regular
program, etc)&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: re-entrant code</title><link>https://community.arm.com/thread/113382?ContentTypeID=1</link><pubDate>Fri, 09 Nov 2007 13:54:57 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:5ee53aca-4e2c-4517-a632-9810e4c64c35</guid><dc:creator>erik  malund</dc:creator><description>&lt;p&gt;&lt;p&gt;
&lt;i&gt;Another example is that a function that reads a global resource
may have to protect ........&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;
Pers post abbreviated: stay away from reentrancy.&lt;/p&gt;

&lt;p&gt;
Erik&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: re-entrant code</title><link>https://community.arm.com/thread/113381?ContentTypeID=1</link><pubDate>Fri, 09 Nov 2007 13:28:16 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:76325560-33a2-4b66-90a6-5aae1cb1a8d5</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
Note that a reentrant function may only call other reentrant
functions.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: re-entrant code</title><link>https://community.arm.com/thread/99909?ContentTypeID=1</link><pubDate>Fri, 09 Nov 2007 13:20:42 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:7d2720dd-9611-4772-a6fc-d6558f6089b6</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
You don&amp;#39;t test for reentrancy. You specifically develop with that
in mind. Reentrancy is a factor of what resources the function makes
use of, and how it uses them.&lt;/p&gt;

&lt;p&gt;
An example is that if a function needs to change two global
variables (and these variables must always be in sync, then the
change must be atomic. An example is allocating/releasing memory.&lt;/p&gt;

&lt;p&gt;
Another example is that a function that reads a global resource
may have to protect the read access, to make sure that two instances
of the same function reads the same value and then does an updated
based on the same value. For example a function that reads a counter,
performs some work based on the counter and then increment the
counter. If two instances of the same function checks that there are
data available in a read queue, they may both process the same
character and insert two results based on the same input.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: re-entrant code</title><link>https://community.arm.com/thread/75697?ContentTypeID=1</link><pubDate>Fri, 09 Nov 2007 10:54:13 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:25f74d72-d43b-443f-8483-e0e93d273014</guid><dc:creator>Georget Stephane</dc:creator><description>&lt;p&gt;&lt;p&gt;
Now here is another question: how do you test for reentrancy of
such code?&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: re-entrant code</title><link>https://community.arm.com/thread/51270?ContentTypeID=1</link><pubDate>Thu, 08 Nov 2007 23:46:24 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:030e5cce-21c7-4374-a98c-8f7e6d3afb54</guid><dc:creator>Christoph Franck</dc:creator><description>&lt;p&gt;&lt;p&gt;
&lt;i&gt;what is a re-entrant code?&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;
Code (for example a function) that can be called safely while the
same function is already being run by another
task/program/function.&lt;/p&gt;

&lt;p&gt;
Reentrancy is needed, for example, for recursive function calls,
or for functions that are called from multiple tasks without any kind
of mutex mechanism.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>