2

I am developing a thread pool in c language and i wanted to allow a task to have an arbitrary number of arguments. Even-thought i could use a function like

int (*task) ();

This function would be able to be called with any type of arguments, like for example i could do

int fib(int n) { return n < 2 ? n : fib(n-1) + fib(n-2); }
...
task = fib;
printf("fib(10)=%d\n",task(10));

However what I want is to be able to save the arguments to run it later, without having to use a call to malloc, because otherwise i would prefer to just use a task like

void * (*task) (void *);

in which i would only have to save the void * argument on a struct. However i wanted to do that for arbitrary arguments, is it possible to make it automatically for any kind of functions i want, without even using any va_list.

Is it possible?

tx in advance

guilhermemtr
  • 528
  • 1
  • 4
  • 15

2 Answers2

1

I'm afraid what you want is not possible - given I correctly understand your question.

The way I'd implement it is using an anonymous pointer to a struct, which implementation is known by the callback and by the caller, but not the thread pool, which will only carry around a single pointer.

But, sadly that solution implies using a malloc(), or nasty memory copy on preallocated space which could be on the stack or globally.

zmo
  • 24,463
  • 4
  • 54
  • 90
  • Yes, on my current implementation, i make use of structs and keep only a void * pointer to that struct. Actually in some cases i can save the struct in the stack, by just declaring it. My problem is that the threadpool needs to be fast (really really fast). and so, even when declaring on the heap, i need to initialize the struct, and so, i loose time, since i could (maybe on another language) simply call it with the right arguments. But thank you (i won't mark it as correct for now, just in order to have some more answers, please don't take me wrong, it's just that this is too much important). – guilhermemtr Feb 25 '14 at 21:24
  • 1
    @guilhermemtr You just can't avoid copying arguments to additional memory, if you want to use them later. – this Feb 25 '14 at 21:27
  • my problem is that in cilk (multithreaded language made by mit, and now continued by intel) they have a compiler, and so they can do it easily. And i wanted to make it so every application would be easy to be ported to my thread pool. (when i tell about initializing it, i'm trying to say that they only have to copy the values to then be loaded in the function). – guilhermemtr Feb 25 '14 at 21:32
  • @self, (to your first comment) that's actually the point I'm making... and to the OP, well, the other choice you've got is the nasty solution I'm telling, which is to preallocate some memory in the stack and fill it in with your structs. You could do it with an union of the different struct you're allowing to use in your callback. Only thing, make sure your allocations **never** gets out of the allocated space. – zmo Feb 25 '14 at 21:33
  • well, I guess that's one of the reasons they designed such a language, "The philosophy behind Cilk is that a programmer should concentrate on structuring the program to expose parallelism and exploit locality..."... So, it'd be in the lines of that philosophy that they also made an easier design for variadic function parameters. – zmo Feb 25 '14 at 21:38
  • and @self. you are right, since i just need to copy a pointer, and initialized the struct (and that would happen automatically when i called a function with certain parameters). So i only make two ops, which is acceptable. – guilhermemtr Feb 25 '14 at 21:42
  • I am sorry but only now i know enough to know it is not possible, and so i have accepted your answer. Thank you :) – guilhermemtr Jun 15 '15 at 20:42
1

If it was only the argument, then I'd use:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-prototypes"
typedef void *(*task_t)();
#pragma GCC diagnostic pop

But that won't work for return types.

The 1st #pragma makes GCC remember which -W flags were provided on the command line. The current warning flags get pushed on a stack.

The 2nd #pragma makes GCC not whine about the absence of the arguments.

The 3rd #pragma restores the old warnings.

The ‘#pragma’ directive is the method specified by the C standard for providing additional information to the compiler, beyond what is conveyed in the language itself.

  — https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html

Community
  • 1
  • 1
Kijewski
  • 25,517
  • 12
  • 101
  • 143