Besides being a great product the Easy Profiler is hard to use optimally when fibers are used in the project (we have a MS CreateFiber as well as set_contex variant).
The problem occurs when a Fiber decides to go into the waiting state and release the thread to other work. In such case all started but not finished profiling blocks on that thread are left hanging and there's no way to signal them that the current fibers is yielding the thread and the time collection for those blocks should be stopped.
Similarly, when the fiber returns to execution there's no way to "restart" profiling blocks that were started when fiber yielded. It should be noted that fiber job can be continue on different thread than it was started on.
Adding following features would allow cheap integration with fiber system:
EASY_CAPTURE_STATE() - captures state of the currently started blocks on the current thread into an internal temporary storage, all blocks can be marked as "yielded" and the time collection for them stops. This function returns the ID of the stored state that is opaque to the application.
EASY_RESTORE_STATE(id) - restores previously captured state of the blocks, resumes the time collection for them.
This way, the typical integration with fiber system would be much simplified:
void Fiber::Yield()
{
m_state = Yielded;
m_opaqueProfilingData = EASY_CAPTURE_STATE();
m_fiberScheduler->GetNextFiber(...); // etc - switches to another fiber
}
void Fiber::Resume() // called from scheduler when this fiber is selected for execution
{
EASY_RESTORE_STATE(m_opaqueProfilingData);
m_state = Running;
SwitchToFiber(m_hFiber);
}
Currently I have this implemented on top of the easy_profiler but it adds A LOT of overhead and could be done much simpler internally.
Besides being a great product the Easy Profiler is hard to use optimally when fibers are used in the project (we have a MS CreateFiber as well as set_contex variant).
The problem occurs when a Fiber decides to go into the waiting state and release the thread to other work. In such case all started but not finished profiling blocks on that thread are left hanging and there's no way to signal them that the current fibers is yielding the thread and the time collection for those blocks should be stopped.
Similarly, when the fiber returns to execution there's no way to "restart" profiling blocks that were started when fiber yielded. It should be noted that fiber job can be continue on different thread than it was started on.
Adding following features would allow cheap integration with fiber system:
EASY_CAPTURE_STATE() - captures state of the currently started blocks on the current thread into an internal temporary storage, all blocks can be marked as "yielded" and the time collection for them stops. This function returns the ID of the stored state that is opaque to the application.
EASY_RESTORE_STATE(id) - restores previously captured state of the blocks, resumes the time collection for them.
This way, the typical integration with fiber system would be much simplified:
Currently I have this implemented on top of the easy_profiler but it adds A LOT of overhead and could be done much simpler internally.