What is really re-entrant function? - reentrancy

I have read may threads on re-entrant subjects on SO as as well as on http://en.wikipedia.org/wiki/Reentrancy_(computing).
I might get the ideas of re-entrant functions. But when I read the example on the wiki site, I really confused.
The first example:
int t;
void swap(int *x, int *y)
{
t = *x;
*x = *y;
// hardware interrupt might invoke isr() here!
*y = t;
}
void isr()
{
int x = 1, y = 2;
swap(&x, &y);
}
As the site explained: " It still fails to be reentrant, and this will continue to cause problems if isr() is called in the same context as a thread already executing swap()." => What kinds of prolems that might happen here? the swapping result is not correct? Or value of t variable is modified?
And the second example, which improved the first one:
int t;
void swap(int *x, int *y)
{
int s;
s = t; // save global variable
t = *x;
*x = *y;
// hardware interrupt might invoke isr() here!
*y = t;
t = s; // restore global variable
}
void isr()
{
int x = 1, y = 2;
swap(&x, &y);
}
How this improves the first one? Does that mean that the variable t is kept unchanged inside the swap() function?

Re-entrant means that the function can be interrupted at any point, and be able to correctly finish executing after the interruption, even in cases when the same function is called one or more times in the interrupted state.
The crucial part here is that the invocation of the function called in the interrupted state must finish before the original call state is restored. This is the main difference between re-entrancy and thread safety: in order to be thread-safe, a function must be able to proceed even if the interrupting invocation is unfinished before the control gets back to the original call.
That's why the second version of the swap is re-entrant: it always leaves t in an unchanged state upon exiting, so entering and exiting swap in the middle of an interrupted call will not alter the global state seen by the interrupted invocation.

Related

What is a good way of synchronization for initializing constant global values accessed by multiple threads?

I have a set of global values that are initialized at program start and never change during the run. Those values are read from multiple threads, and I want to make sure the initialization is done correctly for all threads.
In this example,
int A, B;
void init() {
A = 1;
B = 2;
}
void read(int *a, int *b) {
*a = A;
*b = B;
}
void f() {
/* ... */
read(&a, &b);
/* ... */
}
int main() {
init();
startThread(f);
/* ... */
}
My understanding is that the compiler isn't allowed to put init after startThread because the side effects of the functions should be sequenced as written, so the machine instructions to store values in A and B will come before the thread start. However, this doesn't guarantee that the load in read from a different thread will happen after the stores are complete because the stores might for some reason be deferred after the loads.
Here's an obvious fix.
void init() {
A = 1;
B = 2;
atomic_thread_fence(memory_order_release);
}
void read(int *a, int *b) {
atomic_thread_fence(memory_order_acquire);
*a = A;
*b = B;
}
It should work if I've read the specs correctly, but the problem is that now, all functions that read those global values need a fence at function entry, and I'd like to avoid this. Unfortunately, all defined memory orders including memory_order_seq_cst are defined for cases where the reader is an atomic operation or has a fence.
Under the strong memory model of x86, the example code will work without any fix. I'm looking for a portable solution, but I'm also wondering whether it really could break on a different platform without synchronization.
If synchronization is necessary, what is a good way in this case? Is it possible without being intrusive to all the reader functions?

how to return a pointer value from function to array of strings in c? [duplicate]

Is the following code (func1()) correct if it has to return i? I remember reading somewhere that there is a problem when returning a reference to a local variable. How is it different from func2()?
int& func1()
{
int i;
i = 1;
return i;
}
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
This code snippet:
int& func1()
{
int i;
i = 1;
return i;
}
will not work because you're returning an alias (a reference) to an object with a lifetime limited to the scope of the function call. That means once func1() returns, int i dies, making the reference returned from the function worthless because it now refers to an object that doesn't exist.
int main()
{
int& p = func1();
/* p is garbage */
}
The second version does work because the variable is allocated on the free store, which is not bound to the lifetime of the function call. However, you are responsible for deleteing the allocated int.
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
int main()
{
int* p = func2();
/* pointee still exists */
delete p; // get rid of it
}
Typically you would wrap the pointer in some RAII class and/or a factory function so you don't have to delete it yourself.
In either case, you can just return the value itself (although I realize the example you provided was probably contrived):
int func3()
{
return 1;
}
int main()
{
int v = func3();
// do whatever you want with the returned value
}
Note that it's perfectly fine to return big objects the same way func3() returns primitive values because just about every compiler nowadays implements some form of return value optimization:
class big_object
{
public:
big_object(/* constructor arguments */);
~big_object();
big_object(const big_object& rhs);
big_object& operator=(const big_object& rhs);
/* public methods */
private:
/* data members */
};
big_object func4()
{
return big_object(/* constructor arguments */);
}
int main()
{
// no copy is actually made, if your compiler supports RVO
big_object o = func4();
}
Interestingly, binding a temporary to a const reference is perfectly legal C++.
int main()
{
// This works! The returned temporary will last as long as the reference exists
const big_object& o = func4();
// This does *not* work! It's not legal C++ because reference is not const.
// big_object& o = func4();
}
A local variable is memory on the stack, and that memory is not automatically invalidated when you go out of scope. From a function deeper nested (higher on the stack in memory), it’s perfectly safe to access this memory.
Once the function returns and ends though, things get dangerous.
Usually the memory is not deleted or overwritten when you return, meaning the memory at that address is still containing your data - the pointer seems valid.
Until another function builds up the stack and overwrites it.
This is why this can work for a while - and then suddenly cease to function after one particularly deeply nested set of functions, or a function with really huge sized or many local objects, reaches that stack-memory again.
It even can happen that you reach the same program part again, and overwrite your old local function variable with the new function variable. All this is very dangerous and should be heavily discouraged.
Do not use pointers to local objects!
A good thing to remember are these simple rules, and they apply to both parameters and return types...
Value - makes a copy of the item in question.
Pointer - refers to the address of the item in question.
Reference - is literally the item in question.
There is a time and place for each, so make sure you get to know them. Local variables, as you've shown here, are just that, limited to the time they are locally alive in the function scope. In your example having a return type of int* and returning &i would have been equally incorrect. You would be better off in that case doing this...
void func1(int& oValue)
{
oValue = 1;
}
Doing so would directly change the value of your passed in parameter. Whereas this code...
void func1(int oValue)
{
oValue = 1;
}
would not. It would just change the value of oValue local to the function call. The reason for this is because you'd actually be changing just a "local" copy of oValue, and not oValue itself.

memory access violations and windows

So I am working on the exercise below, and I understand the problems related to dereferencing null pointer as in the code below.
Swap.c
int main () {
int a = 1, b = 2;
swap(&a, &b);
}
void swap (int *px, int *py) {
int *temp;
*temp = *px; //Crashes here
*px = *py;
*py = *temp;
}
Now my issues is on my pc I always get sigsegv if proc exists or not. I assume this is windows not allowing memory access violations.This makes it impossible to really do the exercise below. Does this behave differently on a native Linux machine? Suggestions?
(Exercise) Create swap.c
Supply the definition of a C procedure proc to be called in the main
program immediately prior to the call to the buggy swap (swap2.s) that
will guarantee that swap will crash when the uninitialized temp pointer is
dereferenced (it should cause a crash on *temp). Also explain why your
call guarantees this crash. Hint: your proc procedure will leave
something on the stack.
int main () {
int a = 1, b = 2;
proc(/* Some args might go here */);
swap(&a, &b);
}
Q2. Explain how you guarantee it crashing with what is in proc.
But this is tricky when it always crashes at the deref.?

Changing value of a variable in C

Why should one change the value of the main variable and NOT the COPY of the variable.
I have a method
int plusInt(int x){
return ++x;
}
When this function is called, a new stack frame is created, with the copy of x and not the original variable. So this changes this copy's value?
Q: If I want to change the value of the original variable I use a pointer to it and then increase a value right? Eg:
int plusIntPointer(int *x){
return ++*x;
}
But what is the use/why would someone want to change the value of the original variable and not the copy?
So this changes this copy's value?
Exactly, as the function has only the copy, and not the original variable, as a local variable.
If I want to change the value of the original variable I use a pointer to it and then increase a value right?
Right again. The reason you use a pointer is to pass the address of the variable to the function.
But what is the use/why would someone want to change the value of the original variable and not the copy?
The reason is that any changes to the copy will be lost after your function ends and you return to the calling function.
For example, let's assume that you want to use a function in order to swap the values of two variables. Then, you have to change the original values. Your function should be like this :
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = *temp;
}
and you should call it like this :
swap(&a, &b);
This way, the changes will remain even when you return to the calling function.
If you just change the copies, the variables will not have swapped values when you return to the calling function!!!
Let's say you want to make a function that swaps two variables. Then you need to do this:
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = *temp;
}
...
void swapwrong(int a, int b) // wont work as intended
{
int temp = a;
a = b;
b = temp;
}
...
int a = 1, b = 2 ;
swap(&a, &b);
printf ("after swap : a=%d b=%d\n", a,b);
swapwrong(&a, &b);
printf ("after swapwrong : a=%d b=%d\n", a,b);
This will print
after swap : a=2 b=1
after swapwrong : a=2 b=1
So this changes this copy's value?
Yes. Only the copy that is local to plusInt
If I want to change the value of the original variable I use a pointer to it and then increase a value right?
Yes. To change a variable in another scope we must preform an indirection. That is achieved by passing the variables address.
But what is the use/why would someone want to change the value of the original variable and not the copy?
The simplest use case one comes across early while learning to program, is when trying to insert a node into the head of a linked list. Your addition function must modify the structure in a calling context.
Well, maybe this is not the simplest. Consider this function
void swap_ints(int l, int r) {
int t = l; l = r; r = t;
}
int main(void) {
int x = 1, y = 2;
swap_ints(x, y);
// Were they swapped?
}
But what is the use/why would someone want to change the value of the
original variable and not the copy?
You can change the copy variable, but this variable will not be available when you code exits the function.
Also, we don't generally call a function just for doing a simple increment. The code
int plusInt(int x){
return ++x;
}
can very well in replace as
x++
instead of calling a function. In optimized mode, compilers may decide to get rid of this function by in-lining the change the code wants to do
We use copy variables in many cases, e.g displaying the value of the variable or in the places where you don't want to reflect any accidental changes
There are many applications of the passing parameters to a function by the pointer. E.g.:
When you pass a parameters to a function, as you mentioned, a space in the stack is allocated and such parameters are copied to this space. This operation may be an expensive, so you may consider to pass such parameters by the pointer. Then the pointer to your data will be passed to your function (i.e., will be copied to the stack). In such case you may consider to put the const with such parameters to prevent an "unexpected" changing of their values (as usually done with the char*).
Sometimes you actually need to change a value of such parameter. Pay your attention to that this will be done "in-place". I.e. there will no a copying operations. In the (modified) your example we may to do something like this:
void increment(int* i)
{
if(i)
++*i;
}
In this example there is no any copying operations (as far of the input parameters, as of the result of the function). Moreover, as you can see, we can to pass the NULL as the value of the i. An algorithm of your function may to handle such the case in a different ways (e.g., to skip this parameter etc).
Using of this method of parameter's passing is suggests itself when you need to change a value of many parameters in one function.

What is wrong with this C code

I have a piece of code where I am trying to return the square of the value pointed to by *ptr.
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
main()
{
int a=8,t;
t=square(&a);
printf("%d",t);
}
Its working fine for me but author of this code said it might not work because of following reason:
Because it's possible for the value of *ptr to change unexpectedly, it is possible for a and b to be different. Consequently, this code could return a number that is not a square!. The correct way to do is
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}
I really wanted to know why he said like that?
The idea of the volatile keyword is exactly to indicate to the compiler that a variable marked as such can change in unexpected ways during the program execution.
However, that does not make it a source of "random numbers" - it just advises the compiler - what is responsible for actually changing the variable contents should be another process, thread, some hardware interrupt - anything that would write to the process memory but not inlined in the function where the volatile declaration finds itself. In "older times" (compilers with less magic) everything it did was preventing the compiler from caching the variable value in one of the CPU registers. I have no idea on the optimisations/de-optimistions strategies triggered by it by modern compilers - but it will at least do that.
In the absense of any such external factor, a "volatile" variable is just like any other. Actually - it is just like any other variable - as variables not marked as volatile can also be changed by the same external causes (but the compiled C code would not be prepared for that in this case, which might lead to incorrect values being used).
Since the question has an accepted and correct answer, I will be brief: here is a short program that you can run to see the incorrect behavior happening for yourself.
#include <pthread.h>
#include <math.h>
#include <stdio.h>
int square(volatile int *p) {
int a = *p;
int b = *p;
return a*b;
}
volatile int done;
void* call_square(void* ptr) {
int *p = (int*)ptr;
int i = 0;
while (++i != 2000000000) {
int res = square(p);
int root = sqrt(res);
if (root*root != res) {
printf("square() returned %d after %d successful calls\n", res, i);
break;
}
}
done = 1;
}
int main() {
pthread_t thread;
int num = 0, i = 0;
done = 0;
int ret = pthread_create(&thread, NULL, call_square, (void*)&num);
while (!done) {
num = i++;
i %= 100;
}
return 0;
}
The main() function spawns a thread, and modifies the data being squared in a loop concurrently with another loop calling the square with a volatile pointer. Relatively speaking, it does not fail often, but it does so very reliably in less than a second:
square() returned 1353 after 5705 successful calls <<== 1353 = 33*41
square() returned 340 after 314 successful calls <<== 340 = 17*20
square() returned 1023 after 5566 successful calls <<== 1023 = 31*33
First understand what's volatile: Why is volatile needed in C?
and then, try to find answer by yourself.
It's a game of volatile and hardware world. :-)
Read answer given by Chris Jester-Young:
volatile tells the compiler that your variable may be changed by other means, than the code that is accessing it. e.g., it may be a I/O-mapped memory location. If this is not specified in such cases, some variable accesses can be optimised, e.g., its contents can be held in a register, and the memory location not read back in again.
If there is more than one thread, the value the pointer points to might change inbetween statement "a = *ptr" and statement "b = *ptr". Also: you want the square of a value, why put it into two variables?
In the code you present then there is no way for the variable a that is defined in your main to be modified whilst square is running.
However, consider a multi-threaded program. Suppose that another thread modified the value to your your pointer refers. And suppose that this modification took place after you had assigned a, but before you had assigned b, in the function sqaure.
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
//the other thread writes to *ptr now
b = *ptr;
return a * b;
}
In this scenario, a and b would have different values.
The author is correct (if *ptr will be changed by other threads)
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
//between this two assignments *ptr can change. So it is dangerous to do so. His way is safer
b = *ptr;
return a * b;
}
Because the value of the pointer *ptr might change between the first affection and the second one.
I don't think the value of *ptr can change in this code barring an extremely unusual (and non-standards-compliant) runtime environment.
We're looking at the entirety of main() here and it's not starting up other threads. The variable a, whose address we are taking, is a local in main(), and main() doesn't inform any other function of that variable's address.
If you added the line mysterious_external_function(&a); before the t=square(&a) line, then yes, mysterious_external_function could start a thread and diddle the a variable asynchronously. But there's no such line, so as written square() always returns a square.
(Was the OP a troll post, by the way?)
I see some answers with *ptr can be changed by other threads. But this cannot happen since *ptr is not a static data variable. Its a parameter variable and local and parameter variables being hold inside stack. Each thread has its own stack section and if *ptr has been changed by another thread, it should not effect the current thread's.
One reason why the result might not give the square can be an HW interrupt might happen before assigning b = *ptr; operation as indicated below:
int square(volatile int *ptr) {
int a,b;
a = *ptr; //assuming a is being kept inside CPU registers.
//an HW interrupt might occur here and change the value inside the register which keeps the value of integer "a"
b = *ptr;
return a * b;
}

Resources