romange / gaia

C++ framework for rapid server development
https://romange.github.io/gaia/
BSD 2-Clause "Simplified" License
76 stars 14 forks source link

Stupid question #65

Closed akseg73 closed 2 years ago

akseg73 commented 2 years ago

I have a dumb question, if you don't mind. What API to utilize to check if we are executing inside a fiber or not? the below code does not work. It returns a valid fiber id even though it should be saying not-valid.

int main() { boost::fibers::fiber::id id = boost::this_fiber::get_id(); cout << "fiber id " << id << endl; }

romange commented 2 years ago

why should it be saying not-valid? Boost.Fibers adopts a non-intrusive design where fibers scheduler is initialized when the fibers code is first called.

boost::this_fiber::get_id() calls internally boost::fibers::context::active() which does such one-time initialization when it is called in a new thread. the main thread is not different in this sense.

In short, you can use fibers from your main function and your main function becomes one of the fibers just because the scheduler must return to it when other fibers yield or are blocked on something.

if you read my post about fibers https://www.romange.com/2018/12/15/introduction-to-fibers-in-c-/
you could test it by copying the example below from the blog into your main function. fb1.join(); is a blocking condition for a main fiber where fiber scheduler switches the control to other fibers and then eventually switches back. The same true with fb2.

int keep_going = true;
int iteration = 1;
fibers::mutex mu;
fibers::conditional_variable cv;

auto cb = [&] {
  while (keep_going) {
    do_something_fiber_blocking();
    ++iteration;
    cv.notify_on();
  }
};

fiber fb1(cb);
fiber fb2([&] {
  {
    std::unique_lock<fibers::mutex> lock(mu);
    cv.wait(lock, [&] { return iteration > 5;});
  }
  keep_going = false;
});

fb1.join();
fb2.join();
akseg73 commented 2 years ago

Thanks so much for the response. The reason we are looking at this possibility is this. In our code case there are two different kinds of usages: a) with fibers that can not do a regular blocking sleep() b) without fibers which yield the processor with sleep().

If we can not determine whether we are in a fiber or not we don;t know whether to do a blocking sleep or to do a boost::fiber::sleep_for()

that is the use case we are stuck on.

thanks.

On Wednesday, January 26, 2022, 05:41:53 PM PST, Roman Gershman @.***> wrote:

why should it be saying not-valid? Boost.Fibers adopts a non-intrusive design where fibers scheduler is first initialized when fibers code is called.

boost::this_fiber::get_id() calls internally boost::fibers::context::active() which does such one-time initialization when it is called in a new thread. the main thread is not different in this sense.

In short, you can use fibers from your main function and your main function becomes one of the fibers just because the scheduler must return to it when other fibers yield or are blocked on something.

if you read my post about fibers https://www.romange.com/2018/12/15/introduction-to-fibers-in-c-/ you could test it by copying the example below from the blog into your main function. fb1.join(); is a blocking condition for a main fiber where fiber scheduler switches the control to other fibers and then eventually switches back. The same true with fb2. int keep_going = true; int iteration = 1; fibers::mutex mu; fibers::conditional_variable cv;

auto cb = [&] {   while (keep_going) {     do_something_fiber_blocking();     ++iteration;     cv.notify_on();   } };

fiber fb1(cb); fiber fb2([&] {   {     std::unique_lock lock(mu);     cv.wait(lock, [&] { return iteration > 5;});   }   keep_going = false; });

fb1.join(); fb2.join();

— Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android. You are receiving this because you authored the thread.Message ID: @.***>

akseg73 commented 2 years ago

I think i understand your point now. fibers are initialized the first time you utilize them. So if you don't utilize the fiber functionality then that code is not running fibers. Got it. I think then i know what to do.

Thanks a lot for the help.

akseg73 commented 2 years ago

I had a question about fibers, if you don't mind:

It looks like gperftools does not recognize the functions executing as fibers. Have you tried to utilize any performance measurement tools with fibers?

any help is greatly appreciated ...

regards

On Wednesday, January 26, 2022, 06:10:40 PM PST, amit sehas @.***> wrote:

Thanks so much for the response. The reason we are looking at this possibility is this. In our code case there are two different kinds of usages: a) with fibers that can not do a regular blocking sleep() b) without fibers which yield the processor with sleep().

If we can not determine whether we are in a fiber or not we don;t know whether to do a blocking sleep or to do a boost::fiber::sleep_for()

that is the use case we are stuck on.

thanks.

On Wednesday, January 26, 2022, 05:41:53 PM PST, Roman Gershman @.***> wrote:

why should it be saying not-valid? Boost.Fibers adopts a non-intrusive design where fibers scheduler is first initialized when fibers code is called.

boost::this_fiber::get_id() calls internally boost::fibers::context::active() which does such one-time initialization when it is called in a new thread. the main thread is not different in this sense.

In short, you can use fibers from your main function and your main function becomes one of the fibers just because the scheduler must return to it when other fibers yield or are blocked on something.

if you read my post about fibers https://www.romange.com/2018/12/15/introduction-to-fibers-in-c-/ you could test it by copying the example below from the blog into your main function. fb1.join(); is a blocking condition for a main fiber where fiber scheduler switches the control to other fibers and then eventually switches back. The same true with fb2. int keep_going = true; int iteration = 1; fibers::mutex mu; fibers::conditional_variable cv;

auto cb = [&] {   while (keep_going) {     do_something_fiber_blocking();     ++iteration;     cv.notify_on();   } };

fiber fb1(cb); fiber fb2([&] {   {     std::unique_lock lock(mu);     cv.wait(lock, [&] { return iteration > 5;});   }   keep_going = false; });

fb1.join(); fb2.join();

— Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android. You are receiving this because you authored the thread.Message ID: @.***>

romange commented 2 years ago

I did not have any problem with fibers in that sense. I can see my functions inside fibers when doing profiling with gperftools @akseg73