-
- Downloads
core: introduce deferred work framework
The design behind timer_task timer_task was design for making cancel() and reschedule() scale well with the number of threads and CPUs in the system. These methods may be called frequently and from different CPUs. A task scheduled on one CPU may be rescheduled later from another CPU. To avoid expensive coordination between CPUs a lockfree per-CPU worker was implemented. Every CPU has a worker (async_worker) which has task registry and a thread to execute them. Most of the worker's state may only be changed from the CPU on which it runs. When timer_task is rescheduled it registers its percpu part in current CPU's worker. When it is then rescheduled from another CPU, the previous registration is marked as not valid and new percpu part is registered. When percpu task fires it checks if it is the last registration - only then it can fire. Because timer_task's state is scattered across CPUs some extra housekeeping needs to be done before it can be destroyed. We need to make sure that no percpu task will try to access timer_task object after it is destroyed. To ensure that we walk the list of registrations of given timer_task and atomically flip their state from ACTIVE to RELEASED. If that succeeds it means the task is now revoked and worker will not try to execute it. If that fails it means the task is in the middle of firing and we need to wait for it to finish. When the per-CPU task is moved to RELEASED state it is appended to worker's queue of released percpu tasks using lockfree mpsc queue. These objects may be later reused for registrations.
Loading
Please register or sign in to comment