Skip to content

fibers: Add lifeycle hook to fiber#610

Draft
abhijat wants to merge 3 commits into
romange:masterfrom
abhijat:abhijat/feat/add-fiber-hooks
Draft

fibers: Add lifeycle hook to fiber#610
abhijat wants to merge 3 commits into
romange:masterfrom
abhijat:abhijat/feat/add-fiber-hooks

Conversation

@abhijat

@abhijat abhijat commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

An option hook is added. It is a function pointer and an opaque context pointer. If it is set, then it is called on fiber suspend and resume, with user supplied context pointer.

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3a246db0-6399-46d2-b1f2-e0d74a695e2d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

An option hook is added. It is a function pointer and an opaque context
pointer. If it is set, then it is called on fiber suspend and resume,
with user supplied context pointer.

Signed-off-by: Abhijat Malviya <abhijat@dragonflydb.io>
@abhijat
abhijat force-pushed the abhijat/feat/add-fiber-hooks branch from ceacba7 to 5c12ac1 Compare July 10, 2026 11:29
@kostasrim

Copy link
Copy Markdown
Collaborator

just a heads up and something that popped my mind, we can also dispatch plain functions outside of a fiber context. Not sure if we need a hook for those cases as well (see proactor main loop on how we execute those)

@romange

romange commented Jul 10, 2026

Copy link
Copy Markdown
Owner

I do not think we need. I'm any case I asked abhijiat to write down how this will help with memory accounting. I do not wish to add this if it does not solve anything as it slows down all context switches

@abhijat

abhijat commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

just consider this an experiment for now, Im using it in dragonflydb/dragonfly#7794 but its a swappable part

Comment thread util/fibers/detail/fiber_interface.h Outdated
// the fiber context. Returns the active fiber before the context switch.
FiberInterface* SwitchSetup();

void CallSwitchHook(FiberSwitchHookEvent event) noexcept {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You do not need these duplicated functions.
Both can be removed if you introduce FiberSwitchHook::Run(FiberSwitchHookEvent)
and just call it on the appropriate objects.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

HIGH = 2, // High priority, activated earlier than other fibers.
};

enum class FiberSwitchHookEvent : uint8_t {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need both events? I would like to see memory accounting design before we submit this

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need both events, now I can answer this because the accounting design has progressed. the use case is like this:

in dragonfly we have the struct with the following fields:

  • baseline: memory usage in bytes when the scope began
  • delta: increase/decrease in memory usage which will contribute to metric, starts at 0

on suspend we need to do:

  • compute delta to latest value before suspension (delta = current_mem_usage - baseline)

on resume we need to do:

  • restore baseline to current_mem_usage so that later on delta calculations (at destructor or next suspend) are against current baseline

So we need the callback method to be able to differentiate between the two events.

Signed-off-by: Abhijat Malviya <abhijat@dragonflydb.io>
@abhijat
abhijat force-pushed the abhijat/feat/add-fiber-hooks branch from c377a62 to bb061d6 Compare July 24, 2026 07:45
Signed-off-by: Abhijat Malviya <abhijat@dragonflydb.io>
@abhijat

abhijat commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

I added a benchmark in a temp. commit, which will be dropped after review, it shows the following numbers

 ----------------------------------------------------------------
  Benchmark                      Time             CPU   Iterations
  ----------------------------------------------------------------
  BM_FiberYieldNoHook         87.9 ns         87.8 ns     79043290
  BM_FiberYieldWithHook       88.1 ns         88.0 ns     79126698

the no hook benchmark does not install a hook and keeps yielding between the test and subject fiber.
the other benchmark installs a hook to count the events and keeps yielding.

However even here the BM_FiberYieldNoHook still pays the cost of the checks (if hook is set etc) so this does not mean much.

I commented out the lines which actually run the hooks for better comparison and reran the benchmark:

  ----------------------------------------------------------------
  Benchmark                      Time             CPU   Iterations
  ----------------------------------------------------------------
  BM_FiberYieldNoHook         88.7 ns         88.6 ns     79266923
  BM_FiberYieldWithHook       89.0 ns         88.9 ns     79921919

the numbers are still somewhat similar to the first run. perhaps it is best to compare with the base branch (only the no hook version ofc)

@abhijat

abhijat commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

same benchmark on the base branch is moderately faster:

--------------------------------------------------------------
Benchmark                    Time             CPU   Iterations
--------------------------------------------------------------
BM_FiberYieldNoHook       85.9 ns         85.8 ns     82297109

the numbers on this branch for comparison:

----------------------------------------------------------------
Benchmark                      Time             CPU   Iterations
----------------------------------------------------------------
BM_FiberYieldNoHook         87.9 ns         87.8 ns     79043290
BM_FiberYieldWithHook       88.1 ns         88.0 ns     79126698

After several runs, the base branch yield test is between 85 to 86 ns on each run.
The pr branch no hook and with hook yield tests are very close, and they are between 87 to 88 ns on each run.

So there is around a 2ns/test cost on my machine for the hook setup and calling etc on suspend/resume.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants