How to determine that multiple threads call function simultaneously in C? - c

I want to determine whether certain function in C can be called from multiple threads at the same time, in order to understand if I need to protect it with mutexes. The file where the function is implemented and defined does not have any mutex mechanism, so there is a chance that only one thread ever accesses the function but there is a chance that multiple threads do.
I thought to add a thread local storage variable which I increment upon starting the function and decrement upon exiting the function. If, after decrementing, the value of the variable is greater than 0, then multiple threads access the function.
This is my code:
#include <stdio.h>
static __thread int threadCounter = 0;
void f(void)
{
threadCounter++;
// do something
threadCounter--;
printf("threadCounter: %d\n", threadCounter);
}
a'm wondering if this solution is sufficient to determine whether multiple threads access a function and whether there are better ways to accomplish this.

From the GCC documentation :
"Thread-local storage (TLS) is a mechanism by which variables are allocated such that there is one instance of the variable per extant thread."
Thus, your solution will always indicate that only one thread access your function at the time even if it's not the case. You should use a variable that is shared between thread. But using a volatile one is still not a good solution because if there are multiple thread accessing it at the time, the value might not be the good one.
In conclusion, I think the better way of doing this would be to setup a mutex and using the pthread_mutex_trylock function to detect if there are multiple threads trying to call your function.

A thread local variable is by definition only visible for the current thread, your solution won't work. But your approach is good. Instead of using a thread local variable you should use a variable protected by a mutex.

This test either is using a local variable, or it isn't thread-safe in itself. In either case, it won't be useful as proof. If you want to use a counter, you have to protect it with something like a mutex or critical section. There's pretty much no way around this.
But there's a another way to do this better though, giving you exact information of who called the function, while at the same time not having to modify the actual function. You can create a "mock" function:
#define f() ( print(__func__), f() )
This prints the name of the thread callback function, then calls the actual function f(). This works because the pre-processor token f() is evaluated before any function call.
I wrote the function as a custom one print, since you'll still have the problem with multiple thread trying to access stdout at once if you use printf etc. So the custom print function must contain the means of thread-safety.

Related

Is there any thread safe variable for Pthreads, i need to pass data from one thread to other

Im new to implementation of pthreads
Im using pthreads for two separate actions but in some cases i will have to use data updated from first thread to be used by the other, so just a global variable, with mutex will work or is there any particular variable to be used?
Another thing is that how can i make a pthreads wait until a particular condition is achieved, now i use a "if" condition, but here, thread will be running continuously(Utilizing system recourses) and if condition is satisficed that piece of code works
I was looking for something like an interrupt is it possible?
similarly stopping a pthread, should i use pthreadexit?
Mutex + variable is sufficient. For second part of your question, please read about conditionals and how to use it with pthread (good start point can be https://linux.die.net/man/3/pthread_cond_signal)

Clarifying how GNU C Library defines nonreentrant functions

Taken from: https://www.gnu.org/software/libc/manual/html_node/Nonreentrancy.html
For example, suppose that the signal handler uses gethostbyname. This function returns its value in a static object, reusing the same object each time. If the signal happens to arrive during a call to gethostbyname, or even after one (while the program is still using the value), it will clobber the value that the program asked for.
I fail to see how the above scenario is non-reentrant. It seems to me that gethostbyname is a (read-only) getter function that merely reads from memory (as opposed to modifying memory). Why is gethostbyname non-reentrant?
As the word says, reentrancy is the capability of a function to be able to be called again while it is being called in anothe thread. The scenario you propose is the exact place in which reentrancy is exercised. asume the function has some static or global variable (as the gethostbyname(3) function does) As the return buffer for the structure is being written by one, the other call can be overwriting it to completely destroy the first writing. When the in execution instance of the function (the interrupted one, not the interrumpting one) gets control again, all it's data has been overwritten by the interrupting one, and destroyed it.
A common solution to solve this problem with interruptions is to disable interrupts while the function is executing. This way it doesn't get interrupted by a new call to itself.
If two threads call the same piece of code, and all the parameters and local variables are stored in the stack, each thread has a copy of its own data, so there's no problem in calling both at the same time, as the data they touch is in different stacks. This will not happen with static variables, being those local scope, compilation unit scope or global scope (think that the problem comes when calling the same piece of code, so everywhere one call has access to, the other has also)
Static data, like buffers (look at stdio buffered packages) etc. means in general, the routines will not be reentrant.

pthread Linux data runtime

I have threads in my application that wait on condition variable. When the codition is good thread starts to work and reads some data. My data is global variable. Is it possible pass data on runtime without using global data? I read something about specific data but i don't know if it is useful in this case. Thank you!
Yes, you can pass this to your thread routine: pthread_create(thread, attr, function, *USER_ARG*). Simply create a struct for the data you need for the thread to execute.
Where *USER_ARG* is stored in memory is important, you will often want to use the free store (malloc it) for the argument, otherwise you may corrupt the stack of the thread which called pthread_create.

Does local variable in thread function have separe copy according to thread?

I have declared some local variable in one function like this:
void* thread_function (void* parameter)
{
struct parameter * thread_data = (struct parameter *)parameter;
char buffer[20];
int temp;
}
Here if I have created two threads then in one thread if buffer & temp is updated so will it effect other thread ?
i mean if there are two thread then does there will be two copy of all local variable?
EDIT : then in which case i need to used thread specific data.? i mean pthread_setspecific & all such stuff
These variables are allocated on the stack, and each thread has its own stack: these variables are private to each thread (they are not shared). (See this answer for more details.)
If you assign thread_data to a global pointer, for example, other threads will be able to access thread_data via the global pointer.
Thread specific data (e.g. pthread_setspecific) is used to create variables that are global, but still specific to each thread (not shared): They are thread-specific global variables.
You need to use thread specific variables when you want global variables, but don't want to share them between threads.
It's not that each thread has its own copy, it's that each instance of a function invocation has its own copy of all automatic (i.e. local non-static) variables, regardless of whether the instances are in the same thread or different threads. This is true if the instances come into existence due to invocation in different threads, recursive invocation, mutual/indirect recursion, or even invocation from an asynchronous signal handler. Note that while the C standard does not specify threads, the relevant section in the standard is probably 5.2.3 Signals and interrupts:
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.
This makes it explicit that each invocation must have its own storage for automatic variables.
Local variables are stored in stack memory, which is private to a thread.
Therefore they are not shared between threads: there will be an independent copy of each variable in each thread
Update
Whether you would want to share data between threads really boils down to a design question; What are your threads doing? Are their effort co-ordinated or are they simply workers processing a queue.
The main thing to consider is synchronization of shared data. Variables that are shared between threads are variables that can change value unexpectedly (within a single thread) and so need to be treated as such. I would suggest that you err on the side of not sharing, unless you have a specific reason to do so.

A function in a pthread

Can I call another function in a thread runner function, called by a pthread_create()? Are there any restrictions on such functions?
Yes, you can (and doing so is fairly frequent). The main restriction is that you need to synchronize threads when two or more access the same data (at least if there's any chance that any of them might modify that data).
You can call any function from a runner function. BUT, you should make sure that any function in a multi-threaded system is protected with mutexes correctly.
You can call any function you want from a thread, but C does not automatically synchronize values. If a function uses global variables or static variables then you may get some bad surprises when you call it in multi-threaded code.

Resources