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