Dereferencing struct void pointer in C - c

I have a MyLib.h which has
typedef void *MyThread;
and a MyLib.c which has:
typedef struct
{
ucontext_t *context;
int tid;
}_MyThread;
there is a test function that creates a thread and issues a join as:
void f0(void * dummy)
{
MyThread t1;
printf("f0 start\n");
t1 = MyThreadCreate(f1, NULL);
_MyThread *t = (_MyThread*)t1;
printf("passed value=%d\n",t->tid);
printf("f0 join on t1\n");
MyThreadJoin(t1);
....
}
MyThreadCreate and MyThreadJoin in MyLib.c are as follows:
MyThread MyThreadCreate(void(*start_funct)(void *), void *args)
{
_MyThread child_thread;
...
//setting the child thread's tid
child_thread.tid = ++active_threads;
... MyThread ret = (MyThread)&child_thread;
return ret;
}
int MyThreadJoin(MyThread thread)
{
_MyThread *arg_thread;
arg_thread = (_MyThread*)thread;
int id = arg_thread->tid;
....
}
My problem is, when I run the above, I get:
passed value=2
f0 join on t1
arg_thread->tid = 13
The passed value = "2" is correct, however the value "13" that comes up inside the library function is wrong. Why is the passed value dereferenced in the same way coming different from calling function and different in called function?

Can you add code to print out the memory address of arg_thread and t. I have a feeling what is going on is that your pointer is being sliced in half by a cast. Is MyThreadJoin being forward declared in MyLib.h correctly? Are you compiling your code as 64 bit?
[edit]
I just saw your comment where you were creating t. It looks like you are allocating it on the stack,(not the heap). When you go up a stack frame, it's memory hasn't been overwritten. When you push a new function on to the stack, it overwrites the memory on t. The simple solution is to malloc the struct in your construction function.

Related

Passing function pointer to arg of pthread_create function

I have a function void startScanner(...) taking two function pointer as arguments: userType *vConfig(void) and void * vCallback(void). In this function i would like to create a thread and call vCallback() function in the function thread created. So i decided to pass vCallback as args to pthreadcreate.
The code of startScanner function :
void startScanner(tUsrStatus (*vConfig)(), void* (vCallback)()){
if(pthread_create(&scannerThread, NULL, scannerThreadFunc, vCallback))
{
printf("Thread creation fails!\n");
}
}
The scannerTread function:
static void *scannerThreadFunc(void *arg()){
void *funcptr(void) = arg;
while(1)
{
funcptr();
}
pthread_exit(NULL);
}
I get the following error:
error: function ‘funcptr’ is initialized like a variable
error: nested function ‘funcptr’ declared but never defined
How can i fix this?
Syntax errors aside (*) , it's impossible in standard C to pass a function pointer in a void *. There's a fundamental difference between pointers to functions and pointers to data, they can't be converted into each other. This is because there might be platforms where function and data pointers would differ even in size, or refer to different address spaces, or whatever.
But of course, there's a simple way to achieve what you want: Put your function pointer inside a struct and pass a pointer to that.
typedef (*callback)(void);
typedef struct threadargs
{
callback cb;
} threadargs;
void mycallback(void)
{
// ...
}
void *threadfunc(void *arg)
{
threadargs *ta = arg;
// call your callback:
ta->cb();
return ta; // or: return 0, or some pthread_exit(), ...
}
int main(void)
{
pthread_t thread;
threadargs ta = { mycallback };
pthread_create(&thread, 0, threadfunc, &ta);
// make sure "ta" lives for as long as the thread executes,
// here just wait until it exits:
pthread_join(&thread, 0);
}
add error checking etc.
(*) as for the concrete error you're getting, a function pointer needs parantheses around the identifier, so instead of
void *funcptr(void) = arg;
you'd have to write
void (*funcptr)(void) = arg;
To facilitate the usage of function pointers, it's common to typedef them, as seen in my example above. Anyways, as explained above, this wouldn't solve your problem here.

How can I create a function object in C

I would like to create a wrapper for c functions, so that I can convert a function call of the form ret = function(arg1,arg2,arg3); into the form /*void*/ function_wrapper(/*void*/);. That is similar to function objects in C++ and boost bind.
Is this possible? how can I do it?
Update:
To explain in more details what I am looking for:
We start with this function:
int f(int i){
//do stuff
return somevalue;
}
Obvioulsy, it is called like this:
// do stuff
int x = 0;
ret = f(0);
// do more stuff.
I would like to do some magic that will wrap the function into void function(void)
struct function_object fo;
fo.function_pointer = &f;
fo.add_arg(x, int);
fo.set_ret_pointer(&ret);
fo.call();
Note: I saw that there was a vote for closing this question and marking it as unclear. Please do not do that. I have a legitimate need to get this question answered. If you need explanation, ask and I will be glad to elaborate.
I came up with a better code that might allow you to do what you want. First I'll explain how it works, show the code and explain why I still don't think it's a good idea to use it (though the code might open doors for improvements that addresses those issues).
Functionality:
Before you start using the "function objects", you have to call an initialization function (FUNCTIONOBJ_initialize();), which will initialize the mutexes on every data structure used in the library.
After initializing, every time you want to call one of those "function objects", without using the parameters, you will have to set it up first. This is done by creating a FUNCTIONOBJ_handler_t pointer and calling get_function_handler(). This will search for a free FUNCTIONOBJ_handler data structure that can be used at the moment.
If none is found (all FUNCTIONOBJ_handler data structures are busy, being used by some function call) NULL is returned.
If get_function_handler() does find a FUNCTIONOBJ_handler data structure it will try to lock the FUNCTIONOBJ_id_holder data structure, that holds the ID of the FUNCTIONOBJ_handler of the function about to be called.
If FUNCTIONOBJ_id_holder is locked already, get_function_handler() will hang until it's unlocked by the thread using it.
Once FUNCTIONOBJ_id_holder is locked, the ID of the grabbed FUNCTIONOBJ_handler is wrote on it and the FUNCTIONOBJ_handler pointer is returned by get_function_handler.
With the pointer in hand, the user can set the pointer to the arguments and the return variable with set_args_pointer and set_return_pointer, which both take a void * as arguments.
Finally, you can call the function you want. It has to:
1 - Grab the FUNCTIONOBJ_handler ID from the FUNCTIONOBJ_id_holder data structure and use it to get a pointer to the FUNCTIONOBJ_handler itself.
2 - Use the FUNCTIONOBJ_handler to access the arguments.
3 - Return by using one of the return function (on the example we have ret_int, which will return an integer and unlock the FUNCTIONOBJ_handler)
Below is a simplified mind map describing a bit of what is going on:
Finally, the code:
funcobj.h:
#include <stdio.h>
#include <pthread.h>
#define MAX_SIMULTANEOUS_CALLS 1024
typedef struct {
//Current ID about to be called
int current_id;
//Mutex
pthread_mutex_t id_holder_mutex;
} FUNCTIONOBJ_id_holder_t;
typedef struct {
//Attributes
void *arguments;
void *return_pointer;
//Mutex
pthread_mutex_t handler_mutex;
} FUNCTIONOBJ_handler_t;
FUNCTIONOBJ_handler_t FUNCTIONOBJ_handler[MAX_SIMULTANEOUS_CALLS];
FUNCTIONOBJ_id_holder_t FUNCTIONOBJ_id_holder;
void set_return_pointer(FUNCTIONOBJ_handler_t *this, void *pointer);
void set_args_pointer(FUNCTIONOBJ_handler_t *this, void *pointer);
void ret_int(FUNCTIONOBJ_handler_t *this, int return_value);
void FUNCTIONOBJ_initialize(void);
FUNCTIONOBJ_handler_t *get_function_handler(void);
funcobj.c:
#include "funcobj.h"
void set_return_pointer(FUNCTIONOBJ_handler_t *this, void *pointer){
this->return_pointer = pointer;
}
void set_args_pointer(FUNCTIONOBJ_handler_t *this, void *pointer){
this->arguments = pointer;
}
void ret_int(FUNCTIONOBJ_handler_t *this, int return_value){
if(this->return_pointer){
*((int *) (this->return_pointer)) = return_value;
}
pthread_mutex_unlock(&(this->handler_mutex));
}
void FUNCTIONOBJ_initialize(void){
for(int i = 0; i < MAX_SIMULTANEOUS_CALLS; ++i){
pthread_mutex_init(&FUNCTIONOBJ_handler[i].handler_mutex, NULL);
}
pthread_mutex_init(&FUNCTIONOBJ_id_holder.id_holder_mutex, NULL);
}
FUNCTIONOBJ_handler_t *get_function_handler(void){
int i = 0;
while((0 != pthread_mutex_trylock(&FUNCTIONOBJ_handler[i].handler_mutex)) && (i < MAX_SIMULTANEOUS_CALLS)){
++i;
}
if(i >= MAX_SIMULTANEOUS_CALLS){
return NULL;
}
//Sets the ID holder to hold this ID until the function is called
pthread_mutex_lock(&FUNCTIONOBJ_id_holder.id_holder_mutex);
FUNCTIONOBJ_id_holder.current_id = i;
return &FUNCTIONOBJ_handler[i];
}
main.c:
#include "funcobj.h"
#include <string.h>
//Function:
void print(void){
//First the function must grab the handler that contains all its attributes:
//The FUNCTIONOBJ_id_holder is mutex locked, so we can just access its value and
//then free the lock:
FUNCTIONOBJ_handler_t *this = &FUNCTIONOBJ_handler[FUNCTIONOBJ_id_holder.current_id];
//We dont need the id_holder anymore, free it!
pthread_mutex_unlock(&FUNCTIONOBJ_id_holder.id_holder_mutex);
//Do whatever the function has to do
printf("%s\n", (char *) this->arguments);
//Return the value to the pointed variable using the function that returns an int
ret_int(this, 0);
}
void *thread_entry_point(void *data){
int id = (int) data;
char string[100];
snprintf(string, 100, "Thread %u", id);
int return_val;
FUNCTIONOBJ_handler_t *this;
for(int i = 0; i < 200; ++i){
do {
this = get_function_handler();
} while(NULL == this);
set_args_pointer(this, string);
set_return_pointer(this, &return_val);
print();
}
return NULL;
}
int main(int argc, char **argv){
//Initialize global data strucutres (set up mutexes)
FUNCTIONOBJ_initialize();
//testing with 20 threads
pthread_t thread_id[20];
for(int i = 0; i < 20; ++i){
pthread_create(&thread_id[i], NULL, &thread_entry_point, (void *) i);
}
for(int i = 0; i < 20; ++i){
pthread_join(thread_id[i], NULL);
}
return 0;
}
To compile: gcc -o program main.c funcobj.c -lpthread
Reasons to avoid it:
By using this, you are limiting the number of "function objects" that can be running simultaneously. That's because we need to use global data structures to hold the information required by the functions (arguments and return pointer).
You will be seriously slowing down the program when using multiple threads if those use "function objects" frequently: Even though many functions can run at the same time, only a single function object can be set up at a time. So at least for that fraction of time it takes for the program to set up the function and actually call it, all other threads trying to run a function will be hanging waiting the the data structure to be unlocked.
You still have to write some non-intuitive code at the beginning and end of each function you want to work without arguments (grabbing the FUNCTIONOBJ_handler structure, unlocking the FUNCTIONOBJ_id_holder structure, accessing arguments through the pointer you grabbed and returning values with non-built-in functions). This increases the chances of bugs drastically if care is not taken, specially some nasty ones:
Increases the chances of deadlocks. If you forget to unlock one of the data structures in any point of your code, you might end up with a program that works fine at some moments, but randomly freeze completely at others (because all function calls without arguments will be hanging waiting for the lock to be freed). That is a risk that happens on multithreaded programs anyways, but by using this you are increasing the amount of code that requires locks unnecessarily (for style purposes).
Complicates the use of recursive functions: Every time you call the function object you'll have to go through the set up phrase (even when inside another function object). Also, if you call the recursive function enough times to fill all FUNCTIONOBJ_handler structures the program will deadlock.
Amongst other reasons I might not notice at the moment :p

How to pass a local struct as parameter to pthread_create?

The following function doesn't work. pin_thread_function sometimes receive garbage instead of the struct data. What is wrong? I know that is some basic scope related problem, but I can't explain.
typedef void (*state_callback_t)(int state);
struct pin_thread_params
{
char pin[3 + 1];
state_callback_t callback_onchange;
};
extern int pin_monitor_create(const char * pin,
state_callback_t callback_onchange)
{
int ret;
unsigned long int thread;
struct pin_thread_params params;
//Setup struct
strcpy(params.pin, "123");
params.callback_onchange = callback_onchange;
//Create thread with struc as parameter
ret = pthread_create(&thread, NULL, pin_thread_function, &params);
if (!ret)
{
ret = pthread_detach(thread);
}
return ret;
}
static void * pin_thread_function(void * context)
{
struct pin_thread_params params;
memcpy(&params, context, sizeof(params));
//Sometimes the correct string, most time garbage
printf("Started monitoring %s", params.pin);
}
When params is malloc'ed before pthread_create, everything works fine, like this:
...
struct pin_thread_params * params;
//Setup struct with malloc
params = malloc(sizeof(struct pin_thread_params));
strcpy(params->pin, "123");
params->callback_onchange = callback_onchange;
...
struct pin_thread_params params is statically allocated and the address of it is not safe to use once the scope of it is over (i.e. after pin_monitor_create has returned). It may happen that sometimes the thread execution starts before the pin_monitor_create has exited and you see the valid data in params. However, the dynamically allocated memory is from heap and will be usable until you free it, so you always get valid data in params within pin_thread_function .
I'm not particularly knowledgeable about pthreads (can't just comment quite yet), but you are passing a pointer to stack allocated memory to the thread which will eventually be clobbered by proceeding function calls.

ucontext.h and uc_link not returning from main thread

Here is what I want to do as part of a larger thread scheduling api.
I want to create a thread and when the main thread (the one creating the thread) exits, the thread I just created should execute. I am trying to do this with ucontext and the uc_link, but it is not working. It appears that my uc_link does not work when I try to set it for the current thread.
Here is a slightly modified example from this link which is what I tired to make this work.
http://pubs.opengroup.org/onlinepubs/009695399/functions/makecontext.html
#include <stdio.h>
#include <ucontext.h>
static ucontext_t ctx[3];
static void
f1 (void)
{
puts("start f1");
swapcontext(&ctx[1], &ctx[2]);
puts("finish f1");
}
static void
f2 (void)
{
puts("start f2");
swapcontext(&ctx[2], &ctx[1]);
puts("finish f2");
}
int
main (void)
{
char st1[8192];
char st2[8192];
getcontext(&ctx[1]);
ctx[1].uc_stack.ss_sp = st1;
ctx[1].uc_stack.ss_size = sizeof st1;
ctx[1].uc_link = 0;
makecontext(&ctx[1], f1, 0);
getcontext(&ctx[2]);
ctx[2].uc_stack.ss_sp = st2;
ctx[2].uc_stack.ss_size = sizeof st2;
ctx[2].uc_link = &ctx[1];
makecontext(&ctx[2], f2, 0);
getcontext(&ctx[0]);
ctx[0].uc_link = &ctx[2];
return 0;
}
Expected output :
finished main
start f2
start f1
finish f2
finish f1
Given output :
finished main
How do I go about setting the uc_link for the current thread/process in a meaningful manner ?
Replacing main in the above code with the following produces the expected output.
int
main (void)
{
char st1[8192];
char st2[8192];
getcontext(&ctx[1]);
ctx[1].uc_stack.ss_sp = st1;
ctx[1].uc_stack.ss_size = sizeof st1;
ctx[1].uc_link = &ctx[0];
makecontext(&ctx[1], f1, 0);
getcontext(&ctx[2]);
ctx[2].uc_stack.ss_sp = st2;
ctx[2].uc_stack.ss_size = sizeof st2;
ctx[2].uc_link = &ctx[1];
makecontext(&ctx[2], f2, 0);
getcontext(&ctx[0]);
ctx[0].uc_mcontext.gregs[16] += 0x26;
puts("finish main");
setcontext(&ctx[2]);
return 0;
}
BUT this doesn't do what you say you want.
The context functions are a way to put a specific return address on the stack.
getcontext captures the address of the next instruction into a struct
makecontext changes the address in the struct to that of its function argument
setcontext/swapcontext puts the address in the struct on the stack and returns to it
This program above has only one thread of control. I think you really want multiple threads, in which case you wouldn't use these context functions.
For more information about the stack and the C calling convention, Eli Bendersky has two nice articles with diagrams:
Where the top of the stack is on x86
Stack frame layout on x86-64
FWIW, to get the 0x26 constant in the above code, I had to disassemble main to find the first address after the setcontext call.
At the link you provided they say
The uc_link member is used to determine the context that shall be
resumed when the context being modified by makecontext() returns.
Since your program doesn't resume (execute) any context modified by makecontext(), the above does not apply and the program ends without resuming any context.
To achieve what you want, you have to define some function like
void main_context()
{
// do everything you yet wanted to do in main()
puts("finished main");
}
and replace the
return 0;
with
char st0[8192];
ctx[0].uc_stack.ss_sp = st0;
ctx[0].uc_stack.ss_size = sizeof st0;
makecontext(&ctx[0], main_context, 0);
return -setcontext(&ctx[0]);

Passing queue as parameter in c

I am passing queues like these between source files a.c and b.c
File : a.c
sq[a]=new_queue();
pthread_create(&st[a],NULL,sendPacket,sq[a]);
File : b.c
void *sendPacket(void *queue){
/* here i need to know which queue has come ,determine
the index of queue how can I do it? */
}
Create a more high-level representation of your queue. It seems the queue can be a void * (you're not showing its actual type, i.e. what does the new_queue() call return?), so embed that in a structure while adding the additional parameters:
struct queue_state {
void *queue;
int index;
};
Then instantiate a structure, and pass a pointer to it to the thread function:
struct queue_state qsa = malloc(sizeof *qsa);
if(qsa != NULL)
{
qsa->queue = new_queue();
qsa->index = 4711; /* or whatever */
pthread_create(&st[a], NULL, sendPacket, qsa);
}
Then the thread function can use the struct declaration to access all the fields. Of course, the declaration needs to be in a shared header (say queue.h) which is included from both C files.
Your question description is very rough. But at least from what I understand, you actually need to pass 2 parameters to your function: the (pointer to) queue (which seems an array for me), and the index within this queue.
You may not pack both your parameters in a single variable of type void*. What you may do is declare a struct with all the needed parameters, fill it, and pass a pointer to it to your thread.
Like this (error handling omitted):
struct Params
{
queue* m_Queue;
size_t m_Idx;
};
// ...
Params* pParams = new Params;
pParams->m_Queue = sq;
pParams->m_Idx = a;
pthread_create(&st[a],NULL,sendPacket, pParams);
void *sendPacket(void *pPtr)
{
Params* pParams = (Params*) pPtr;
// ...
delete pParams;
}
Probably it is easier if you just pass the index to the function:
void *sendPacket(int queue_idx) {
queue_t *queue = &sq[queue_idx];
}
If in b.c you have access to sq, you can just pass the index to the queue. Otherwise you can pass a struct containing the actual queue and the index

Resources