alibaba / PhotonLibOS

Probably the fastest coroutine lib in the world!

Home Page:https://PhotonLibOS.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Is there a way to call `photon::thread_create11()` from C by using a void* function pointer?

medvednikov opened this issue · comments

Hi,

Thanks for the great lib!

I'm writing a C wrapper to use it from C, and I'm getting a compilation error due to passing a void* instead of a C++ function:

photonwrapper.cpp:12:2: error: no matching function for call to 'thread_create11'
        photon::thread_create11(f);
        ^~~~~~~~~~~~~~~~~~~~~~~
/Users/alex/code/3rd/PhotonLibOS/include/photon/thread/thread11.h:69:5: note: candidate template ignored: requirement 'is_function_pointer<void *>::value' was not satisfied [with F = void *, ARGUMENTS = <>]
    thread_create11(F f, ARGUMENTS&&...args) {
    ^
/Users/alex/code/3rd/PhotonLibOS/include/photon/thread/thread11.h:114:5: note: candidate template ignored: requirement 'is_functor<void *&>::value' was not satisfied [with FUNCTOR = void *&, ARGUMENTS = <>]
    thread_create11(FUNCTOR&& f, ARGUMENTS&&...args) {
void photon_thread_create11(void* f) {
	photon::thread_create11(f);
}

According to this, converting a void* to a function pointer directly is not allowed in C++:
https://stackoverflow.com/questions/57435515/how-to-cast-void-pointers-to-function-pointers

So how can we call it from C? I guess a new overloaded function photon::thread_create11() that accepts a void* instead of F can be added?

Thanks.

photon::thread_create11() is the C++11 implementation in thread/thread11.h.

We also have a photon::thread* photon::thread_create(thread_entry start, void* arg) in thread/thread.h

BTW, what kind of project do you plan to use this c wrapper in?

So how can we call it from C?

photon::thread_create is a c-style function that creates a photon thread. This may fits better for your needs.

accepts a void* instead of F can be added?

I suppose this void* is actually a function pointer? You can pass the function pointer (of proper type) directly to photon::thread_create.

what kind of project

Probably langv (https://github.com/vlang/v).

I've never heard of it before, but it looks like a great language (according to the feature-list).

Thanks @beef9999 !

Yes, I want to use it internally for V's coroutines/scheduler.

OK, please feel free to ask if you have any questions.

We also have a Slack chatroom for people who want instant replies and talks, you can send me emails to book time and see if any of our team members are online to serve at that time

Thanks, that's great.

What's the Slack link?

I managed to set it up using thread_create(). In the C++11 version it's easy to just list all arguments that need to be passed. In thread_create() there's only one argument. Do I need to use temporary structs to pass multiple arguments, or is there a way to do so like with thread_create11()?

https://join.slack.com/t/photonlibos/shared_invite/zt-1wcmopjw0-wsNZxNtv6teJQxBzm_jKag

Yes you will need a temporary struct, the current create11 implementation basically does a placement-new operation ,

new (p) Pair{std::forward<F>(f), SavedArgs{std::forward<ARGUMENTS>(args)...}};

Thread create has some cost, to minimize it, you can use ThreadPool

By the way, context switch will not happen inside the thread create function call , that means the sub thread (callee) only got its stack allocated. After the caller went to sleep(yield), the sub thread callee will have a chance to run

is there a way to do so like with thread_create11()?

thread_create11 uses template meta-programming to realize a generic temp struct in order to pass arbitrary number (and types) of arguments. But it is not accessible from C. You have to do it manually in C.

When invoking thread_create(), you have an option to reserved some space in the new stack for the temp struct, so as to avoid an extra allocation for it. The placement new operation mentioned by @beef9999 uses this trick.