xref: /spdk/doc/event.md (revision 1e1fd9ac219da3e52bc166c9d2bb2376c62c113d)
1e8d13358SBen Walker# Event Framework {#event}
21a787169SDaniel Verkamp
3e8d13358SBen WalkerSPDK provides a framework for writing asynchronous, polled-mode,
4e8d13358SBen Walkershared-nothing server applications. The event framework is intended to be
5e8d13358SBen Walkeroptional; most other SPDK components are designed to be integrated into an
6e8d13358SBen Walkerapplication without specifically depending on the SPDK event library. The
7e8d13358SBen Walkerframework defines several concepts - reactors, events, and pollers - that are
8e8d13358SBen Walkerdescribed in the following sections. The event framework spawns one thread per
9e8d13358SBen Walkercore (reactor) and connects the threads with lockless queues. Messages
10e8d13358SBen Walker(events) can then be passed between the threads. On modern CPU architectures,
11e8d13358SBen Walkermessage passing is often much faster than traditional locking. For a
12e8d13358SBen Walkerdiscussion of the theoretical underpinnings of this framework, see @ref
13e8d13358SBen Walkerconcurrency.
141a787169SDaniel Verkamp
15e8d13358SBen WalkerThe event framework public interface is defined in event.h.
161a787169SDaniel Verkamp
17*1e1fd9acSwawryk## Event Framework Design Considerations {#event_design}
181a787169SDaniel Verkamp
19e8d13358SBen WalkerSimple server applications can be written in a single-threaded fashion. This
20e8d13358SBen Walkerallows for straightforward code that can maintain state without any locking or
21e8d13358SBen Walkerother synchronization. However, to scale up (for example, to allow more
22e8d13358SBen Walkersimultaneous connections), the application may need to use multiple threads.
23e8d13358SBen WalkerIn the ideal case where each connection is independent from all other
24e8d13358SBen Walkerconnections, the application can be scaled by creating additional threads and
25e8d13358SBen Walkerassigning connections to them without introducing cross-thread
26e8d13358SBen Walkersynchronization. Unfortunately, in many real-world cases, the connections are
27e8d13358SBen Walkernot entirely independent and cross-thread shared state is necessary. SPDK
28e8d13358SBen Walkerprovides an event framework to help solve this problem.
291a787169SDaniel Verkamp
30*1e1fd9acSwawryk## SPDK Event Framework Components {#event_components}
311a787169SDaniel Verkamp
32*1e1fd9acSwawryk### Events {#event_component_events}
331a787169SDaniel Verkamp
34e8d13358SBen WalkerTo accomplish cross-thread communication while minimizing synchronization
35e8d13358SBen Walkeroverhead, the framework provides message passing in the form of events. The
36e8d13358SBen Walkerevent framework runs one event loop thread per CPU core. These threads are
37e8d13358SBen Walkercalled reactors, and their main responsibility is to process incoming events
38e8d13358SBen Walkerfrom a queue. Each event consists of a bundled function pointer and its
39e8d13358SBen Walkerarguments, destined for a particular CPU core. Events are created using
40e8d13358SBen Walkerspdk_event_allocate() and executed using spdk_event_call(). Unlike a
41e8d13358SBen Walkerthread-per-connection server design, which achieves concurrency by depending
42e8d13358SBen Walkeron the operating system to schedule many threads issuing blocking I/O onto a
43e8d13358SBen Walkerlimited number of cores, the event-driven model requires use of explicitly
44e8d13358SBen Walkerasynchronous operations to achieve concurrency. Asynchronous I/O may be issued
45e8d13358SBen Walkerwith a non-blocking function call, and completion is typically signaled using
46e8d13358SBen Walkera callback function.
471a787169SDaniel Verkamp
48*1e1fd9acSwawryk### Reactors {#event_component_reactors}
491a787169SDaniel Verkamp
50e8d13358SBen WalkerEach reactor has a lock-free queue for incoming events to that core, and
51e8d13358SBen Walkerthreads from any core may insert events into the queue of any other core. The
52e8d13358SBen Walkerreactor loop running on each core checks for incoming events and executes them
53e8d13358SBen Walkerin first-in, first-out order as they are received. Event functions should
54e8d13358SBen Walkernever block and should preferably execute very quickly, since they are called
55e8d13358SBen Walkerdirectly from the event loop on the destination core.
561a787169SDaniel Verkamp
57*1e1fd9acSwawryk### Pollers {#event_component_pollers}
581a787169SDaniel Verkamp
59e8d13358SBen WalkerThe framework also defines another type of function called a poller. Pollers
60e8d13358SBen Walkermay be registered with the spdk_poller_register() function. Pollers, like
61e8d13358SBen Walkerevents, are functions with arguments that can be bundled and executed.
62e8d13358SBen WalkerHowever, unlike events, pollers are executed repeatedly until unregistered and
63e8d13358SBen Walkerare executed on the thread they are registered on. The reactor event loop
64e8d13358SBen Walkerintersperses calls to the pollers with other event processing. Pollers are
65e8d13358SBen Walkerintended to poll hardware as a replacement for interrupts. Normally, pollers
66e8d13358SBen Walkerare executed on every iteration of the main event loop. Pollers may also be
67e8d13358SBen Walkerscheduled to execute periodically on a timer if low latency is not required.
681a787169SDaniel Verkamp
69*1e1fd9acSwawryk### Application Framework {#event_component_app}
701a787169SDaniel Verkamp
711a787169SDaniel VerkampThe framework itself is bundled into a higher level abstraction called an "app". Once
721a787169SDaniel Verkampspdk_app_start() is called, it will block the current thread until the application
73b9be940aSLance Hartmannterminates by calling spdk_app_stop() or an error condition occurs during the
74b9be940aSLance Hartmanninitialization code within spdk_app_start(), itself, before invoking the caller's
75b9be940aSLance Hartmannsupplied function.
763703ebc7SMaciej Szwed
77*1e1fd9acSwawryk### Custom shutdown callback {#event_component_shutdown}
783703ebc7SMaciej Szwed
793703ebc7SMaciej SzwedWhen creating SPDK based application user may add custom shutdown callback which
803703ebc7SMaciej Szwedwill be called before the application framework starts the shutdown process.
813703ebc7SMaciej SzwedTo do that set shutdown_cb function callback in spdk_app_opts structure passed
823703ebc7SMaciej Szwedto spdk_app_start(). Custom shutdown callback should call spdk_app_stop() before
833703ebc7SMaciej Szwedreturning to continue application shutdown process.
84