The Pedigree Project 0.1
Classes | Public Types | Public Member Functions | Static Public Member Functions | Protected Attributes | Private Member Functions | Static Private Member Functions | Private Attributes | Friends | List of all members
Event Class Referenceabstract

#include <Event.h>

+ Inheritance diagram for Event:
+ Collaboration diagram for Event:

Classes

class  Delivery
 
class  Retirement
 
class  SendLease
 

Public Types

enum class  HandlerPrivilege { Kernel , User }
 
enum class  UserReturnDelivery { NotApplicable , Delivered , Failed }
 

Public Member Functions

 Event (uintptr_t handlerAddress, bool isDeletable, size_t specificNestingLevel=~0UL, HandlerPrivilege handlerPrivilege=HandlerPrivilege::Kernel)
 
virtual bool isDeletable ()
 
virtual size_t serialize (uint8_t *pBuffer)=0
 
uintptr_t getHandlerAddress ()
 
HandlerPrivilege getHandlerPrivilege () const
 
bool isValidHandlerMapping (size_t mappingFlags) const
 
virtual bool isSignalEvent () const
 
virtual bool prefersAlternateUserStack () const
 
virtual bool requiresExactUserReturnState () const
 
virtual UserReturnDelivery deliverAtUserReturn (InterruptState &)
 
virtual UserReturnDelivery deliverAtUserReturn (SyscallState &)
 
virtual bool isDeliverableWhileProcessSuspended () const
 
virtual Event * cloneForDelivery ()
 
size_t getSpecificNestingLevel ()
 
virtual size_t getNumber ()=0
 
 Event (const Event &other)
 
Event & operator= (const Event &other)
 
size_t pendingCount ()
 
bool tryAcquireRegistration (SendLease &registration)
 
virtual void waitForDeliveries ()
 
void retire ()
 
void beginRetirement (Retirement &retirement)
 

Static Public Member Functions

static uintptr_t getTrampoline ()
 
static uintptr_t getSecondaryTrampoline ()
 
static uintptr_t getHandlerBuffer ()
 
static size_t getHandlerBufferSize ()
 
static uintptr_t getLastHandlerBuffer ()
 
static bool unserialize (uint8_t *pBuffer, Event &event)
 
static size_t getEventType (uint8_t *pBuffer)
 

Protected Attributes

uintptr_t m_HandlerAddress
 
HandlerPrivilege m_HandlerPrivilege
 
bool m_bIsDeletable
 
size_t m_NestingLevel
 
uint64_t m_Magic
 
List< Thread * > m_Threads
 
Spinlock m_Lock
 

Private Member Functions

SendLease beginSend ()
 
void endSend ()
 
void finishRetirement ()
 
bool registerThread (Thread *thread)
 
void deregisterThread (Thread *thread)
 
void completeDelivery (Thread *thread)
 
void beginDispatch (Delivery *delivery)
 
void endDispatch (Delivery *delivery)
 

Static Private Member Functions

static constexpr size_t handlerBufferSize (size_t pageSize)
 

Private Attributes

bool m_DeleteWhenUnused
 
bool m_DeliveriesClosed
 
bool m_DrainClaimed
 
size_t m_SendersInFlight
 
Delivery * m_pFirstActiveDelivery
 
WaitQueue m_DeliveryWaiters
 

Friends

class Thread
 

Detailed Description

The abstract base class for an asynchronous event. An event can hold any amount of information up to a hard maximum size of EVENT_LIMIT (usually 4096 bytes). An event is serialized using the virtual serialize() function and sent to a recipient thread in either user or kernel mode, where it is unserialized.

Definition at line 49 of file Event.h.

Member Enumeration Documentation

◆ HandlerPrivilege

enum class Event::HandlerPrivilege
strong

Privilege level at which the event handler is allowed to execute.

Definition at line 52 of file Event.h.

◆ UserReturnDelivery

enum class Event::UserReturnDelivery
strong

Result of an Event which consumes an exact return-to-user context.

Definition at line 58 of file Event.h.

Constructor & Destructor Documentation

◆ Event() [1/2]

Event::Event ( uintptr_t  handlerAddress,
bool  isDeletable,
size_t  specificNestingLevel = ~0UL,
HandlerPrivilege  handlerPrivilege = HandlerPrivilege::Kernel 
)

Constructs an Event object.

Parameters
handlerAddressThe address of the handling function.
isDeletableCan the object be deleted after map()? This is used for creating objects without worrying about destroying them.
specificNestingLevelIs the event pinned to a specific nesting level? If this value is not ~0UL, then the event will only be fired if the current nesting level is specificNestingLevel .
handlerPrivilegeThe privilege level at which the handler may execute.
Note
As can be surmised, handlerAddress is NOT reentrant. If you use this Event in multiple threads concurrently, you CANNOT change the handler address.

Definition at line 34 of file Event.cc.

◆ ~Event()

Event::~Event ( )
virtual

Definition at line 172 of file Event.cc.

◆ Event() [2/2]

Event::Event ( const Event &  other)

Definition at line 249 of file Event.cc.

Member Function Documentation

◆ beginDispatch()

void Event::beginDispatch ( Delivery *  delivery)
private

Tracks an Event::Delivery while its kernel callback is active.

Definition at line 397 of file Event.cc.

References m_Lock, and m_pFirstActiveDelivery.

◆ beginRetirement()

void Event::beginRetirement ( Retirement &  retirement)

Begins retirement while keeping storage pinned so the owner can remove raw pointers from external notification registries.

Definition at line 484 of file Event.cc.

References m_bIsDeletable, m_DeliveriesClosed, m_DeliveryWaiters, m_DrainClaimed, m_Lock, and m_SendersInFlight.

Referenced by retire().

+ Here is the caller graph for this function:

◆ beginSend()

Event::SendLease Event::beginSend ( )
private

Admits and pins one sender before it touches any other Event state.

Definition at line 280 of file Event.cc.

References m_DeliveriesClosed, m_DeliveryWaiters, m_Lock, and m_SendersInFlight.

Referenced by Thread::replaceSignalEvent(), Thread::sendEvent(), and tryAcquireRegistration().

+ Here is the caller graph for this function:

◆ cloneForDelivery()

virtual Event * Event::cloneForDelivery ( )
inlinevirtual

Returns the instance to enqueue for one delivery. Most events enqueue themselves; signal dispositions return an independently owned snapshot.

Reimplemented in SignalEvent, and LinuxAmd64Signal::AsyncEvent.

Definition at line 277 of file Event.h.

◆ completeDelivery()

void Event::completeDelivery ( Thread *  thread)
private

Completes exactly one delivery. Deletable events are retired only after their final queued or active delivery releases its registration.

Definition at line 348 of file Event.cc.

References List< T, nodePoolSize >::begin(), List< T, nodePoolSize >::count(), List< T, nodePoolSize >::end(), List< T, nodePoolSize >::erase(), m_bIsDeletable, m_DeleteWhenUnused, m_DeliveryWaiters, m_Lock, m_SendersInFlight, and m_Threads.

Referenced by Thread::replaceSignalEvent(), Thread::sendEvent(), Thread::shutdown(), and Thread::transferProcessSignalsTo().

+ Here is the caller graph for this function:

◆ deliverAtUserReturn() [1/2]

virtual UserReturnDelivery Event::deliverAtUserReturn ( InterruptState &  )
inlinevirtual

Delivers this event by editing an interrupt return frame in place.

Reimplemented in LinuxAmd64Signal::AsyncEvent.

Definition at line 259 of file Event.h.

Referenced by PerProcessorScheduler::checkEventState().

+ Here is the caller graph for this function:

◆ deliverAtUserReturn() [2/2]

virtual UserReturnDelivery Event::deliverAtUserReturn ( SyscallState &  )
inlinevirtual

Delivers this event by editing a syscall return frame in place.

Reimplemented in LinuxAmd64Signal::AsyncEvent.

Definition at line 264 of file Event.h.

◆ deregisterThread()

void Event::deregisterThread ( Thread *  thread)
private

Deregisters exactly one enqueue without transferring ownership.

Definition at line 321 of file Event.cc.

References List< T, nodePoolSize >::begin(), List< T, nodePoolSize >::count(), List< T, nodePoolSize >::end(), List< T, nodePoolSize >::erase(), m_DeleteWhenUnused, m_DeliveryWaiters, m_Lock, m_SendersInFlight, and m_Threads.

Referenced by Thread::cullEvent(), Thread::replaceSignalEvent(), and Thread::sendEvent().

+ Here is the caller graph for this function:

◆ endDispatch()

void Event::endDispatch ( Delivery *  delivery)
private

Definition at line 412 of file Event.cc.

◆ endSend()

void Event::endSend ( )
private

Definition at line 290 of file Event.cc.

◆ finishRetirement()

void Event::finishRetirement ( )
private

Definition at line 502 of file Event.cc.

◆ getEventType()

size_t Event::getEventType ( uint8_t *  pBuffer)
static

Given a serialized event, returns the type of that event (a constant from eventNumbers.h).

Definition at line 243 of file Event.cc.

◆ getHandlerAddress()

uintptr_t Event::getHandlerAddress ( )
inline

Returns the handler address.

Definition at line 231 of file Event.h.

Referenced by PerProcessorScheduler::checkEventState(), and PosixSubsystem::getSignalDisposition().

+ Here is the caller graph for this function:

◆ getHandlerBuffer()

uintptr_t Event::getHandlerBuffer ( )
static

Retrieves the event handler buffer memory address.

Definition at line 213 of file Event.cc.

References PhysicalMemoryManager::getPageSize(), and getTrampoline().

Referenced by PerProcessorScheduler::checkEventState(), and getLastHandlerBuffer().

+ Here is the caller graph for this function:

◆ getHandlerBufferSize()

size_t Event::getHandlerBufferSize ( )
static

Retrieves the target-page-rounded size of one event handler buffer.

Definition at line 217 of file Event.cc.

References PhysicalMemoryManager::getPageSize().

Referenced by PerProcessorScheduler::checkEventState(), and getLastHandlerBuffer().

+ Here is the caller graph for this function:

◆ getHandlerPrivilege()

HandlerPrivilege Event::getHandlerPrivilege ( ) const
inline

Returns the privilege level at which the handler may execute.

Definition at line 236 of file Event.h.

Referenced by PerProcessorScheduler::checkEventState().

+ Here is the caller graph for this function:

◆ getLastHandlerBuffer()

uintptr_t Event::getLastHandlerBuffer ( )
static

Retrieves the last handler buffer memory address.

Definition at line 221 of file Event.cc.

References getHandlerBuffer(), and getHandlerBufferSize().

◆ getNumber()

virtual size_t Event::getNumber ( )
pure virtual

Returns the event number / ID.

Implemented in IoEvent, PollEvent, SelectEvent, Semaphore::SemaphoreEvent, SignalEvent, Time::DelayTimerEvent, and RelayEvent.

Referenced by PerProcessorScheduler::checkEventState(), Thread::replaceSignalEvent(), and Thread::sendEvent().

+ Here is the caller graph for this function:

◆ getSecondaryTrampoline()

uintptr_t Event::getSecondaryTrampoline ( )
static

Retrieves the secondary trampoline memory address.

Definition at line 209 of file Event.cc.

References getTrampoline().

◆ getSpecificNestingLevel()

size_t Event::getSpecificNestingLevel ( )
inline

Returns the specific nesting level, or ~0UL if there is none defined.

Definition at line 282 of file Event.h.

◆ getTrampoline()

uintptr_t Event::getTrampoline ( )
static

Retrieves the main trampoline memory address.

Definition at line 201 of file Event.cc.

References EMIT_IF, VirtualAddressSpace::getKernelAddressSpace(), and VirtualAddressSpace::getKernelEventBlockStart().

Referenced by PerProcessorScheduler::checkEventState(), getHandlerBuffer(), and getSecondaryTrampoline().

+ Here is the caller graph for this function:

◆ handlerBufferSize()

static constexpr size_t Event::handlerBufferSize ( size_t  pageSize)
inlinestaticconstexprprivate

Definition at line 347 of file Event.h.

◆ isDeletable()

bool Event::isDeletable ( )
virtual

Returns true if the event is on the heap and can be deleted when handled. This is for creating fire-and-forget messages and not worrying about memory leaks.

Definition at line 225 of file Event.cc.

References m_bIsDeletable.

Referenced by PerProcessorScheduler::checkEventState(), SignalEvent::cloneForDelivery(), and LinuxAmd64Signal::AsyncEvent::cloneForDelivery().

+ Here is the caller graph for this function:

◆ isDeliverableWhileProcessSuspended()

virtual bool Event::isDeliverableWhileProcessSuspended ( ) const
inlinevirtual

Returns whether this event can run before a suspended process resumes.

Reimplemented in SignalEvent.

Definition at line 269 of file Event.h.

◆ isSignalEvent()

virtual bool Event::isSignalEvent ( ) const
inlinevirtual

Returns true if this event is subject to the thread's signal mask.

Reimplemented in SignalEvent.

Definition at line 244 of file Event.h.

Referenced by PerProcessorScheduler::checkEventState(), Thread::markDeferredUserReturnSignalInterruption(), Thread::replaceSignalEvent(), and Thread::sendEvent().

+ Here is the caller graph for this function:

◆ isValidHandlerMapping()

bool Event::isValidHandlerMapping ( size_t  mappingFlags) const

Returns whether page-table flags permit this handler's privilege.

Definition at line 229 of file Event.cc.

References VirtualAddressSpace::Execute, VirtualAddressSpace::KernelMode, and m_HandlerPrivilege.

Referenced by PerProcessorScheduler::checkEventState().

+ Here is the caller graph for this function:

◆ operator=()

Event & Event::operator= ( const Event &  other)

Definition at line 256 of file Event.cc.

◆ pendingCount()

size_t Event::pendingCount ( )

Gets the number of queued or actively dispatched deliveries.

Definition at line 386 of file Event.cc.

References List< T, nodePoolSize >::count(), m_Lock, and m_Threads.

◆ prefersAlternateUserStack()

virtual bool Event::prefersAlternateUserStack ( ) const
inlinevirtual

Returns whether a userspace handler prefers the thread's signal stack.

Reimplemented in SignalEvent.

Definition at line 249 of file Event.h.

Referenced by PerProcessorScheduler::checkEventState().

+ Here is the caller graph for this function:

◆ registerThread()

bool Event::registerThread ( Thread *  thread)
private

Registers one enqueue while delivery admission remains open.

Definition at line 312 of file Event.cc.

References m_DeliveriesClosed, m_Lock, m_Threads, and List< T, nodePoolSize >::pushBack().

Referenced by Thread::replaceSignalEvent(), and Thread::sendEvent().

+ Here is the caller graph for this function:

◆ requiresExactUserReturnState()

virtual bool Event::requiresExactUserReturnState ( ) const
inlinevirtual

Returns true when this event cannot run without the raw user context.

Reimplemented in LinuxAmd64Signal::AsyncEvent.

Definition at line 254 of file Event.h.

Referenced by PerProcessorScheduler::checkEventState().

+ Here is the caller graph for this function:

◆ retire()

void Event::retire ( )

Closes delivery admission and deletes this heap-owned Event after the final queued or active delivery drains. The caller must discard its pointer immediately.

Definition at line 479 of file Event.cc.

References beginRetirement().

Referenced by PosixSubsystem::getSignalDisposition().

+ Here is the caller graph for this function:

◆ serialize()

virtual size_t Event::serialize ( uint8_t *  pBuffer)
pure virtual

Given a buffer EVENT_LIMIT bytes long, take the variables present in this object and convert them to a binary form.

It can be assumed that this function will only be called when the Event is about to be dispatched, and so the inhibited mask of the current Thread is available to be changed to what the event handler requires. This change will be undone when the handler completes.

Parameters
pBufferThe buffer to serialize to.
Returns
The number of bytes serialized.

Implemented in RelayEvent, IoEvent, PollEvent, SelectEvent, Semaphore::SemaphoreEvent, SignalEvent, and Time::DelayTimerEvent.

Referenced by PerProcessorScheduler::checkEventState().

+ Here is the caller graph for this function:

◆ tryAcquireRegistration()

bool Event::tryAcquireRegistration ( SendLease &  registration)

Pins this Event while an external notification source stores its pointer. Returns an empty lease once retirement has begun.

Definition at line 392 of file Event.cc.

References beginSend().

Referenced by BufferMonitors::add(), File::monitor(), and RingBuffer< T, preallocatedSize >::monitor().

+ Here is the caller graph for this function:

◆ unserialize()

bool Event::unserialize ( uint8_t *  pBuffer,
Event &  event 
)
static

Given a serialized Event in binary form, attempt to unserialize into the given object. If this is impossible, return false.

Note
It is impossible to make static functions virtual, but it is required that all subclasses of Event implement this function statically.

Definition at line 238 of file Event.cc.

◆ waitForDeliveries()

void Event::waitForDeliveries ( )
virtual

Closes delivery admission and waits until every queued or active delivery has drained. Calling this from this Event's own active kernel handler is a contract violation; heap owners which can retire from a handler must use retire().

Definition at line 433 of file Event.cc.

References List< T, nodePoolSize >::count(), EMIT_IF, ProcessorBase::information(), m_bIsDeletable, m_DeliveriesClosed, m_DeliveryWaiters, m_DrainClaimed, m_Lock, m_pFirstActiveDelivery, m_SendersInFlight, and m_Threads.

Friends And Related Symbol Documentation

◆ Thread

friend class Thread
friend

Definition at line 345 of file Event.h.

Member Data Documentation

◆ m_bIsDeletable

bool Event::m_bIsDeletable
protected

Can the object be deleted after map?

Definition at line 330 of file Event.h.

Referenced by beginRetirement(), completeDelivery(), isDeletable(), and waitForDeliveries().

◆ m_DeleteWhenUnused

bool Event::m_DeleteWhenUnused
private

A completed delivery requested deletion once all leases drain.

Definition at line 374 of file Event.h.

Referenced by completeDelivery(), and deregisterThread().

◆ m_DeliveriesClosed

bool Event::m_DeliveriesClosed
private

No delivery can register after close-and-drain begins.

Definition at line 377 of file Event.h.

Referenced by beginRetirement(), beginSend(), registerThread(), and waitForDeliveries().

◆ m_DeliveryWaiters

WaitQueue Event::m_DeliveryWaiters
private

Waiters for the final queued or active delivery to drain.

Definition at line 389 of file Event.h.

Referenced by beginRetirement(), beginSend(), completeDelivery(), deregisterThread(), and waitForDeliveries().

◆ m_DrainClaimed

bool Event::m_DrainClaimed
private

Exactly one owner may execute the permanent close-and-drain.

Definition at line 380 of file Event.h.

Referenced by beginRetirement(), and waitForDeliveries().

◆ m_HandlerAddress

uintptr_t Event::m_HandlerAddress
protected

Handler address.

Definition at line 324 of file Event.h.

◆ m_HandlerPrivilege

HandlerPrivilege Event::m_HandlerPrivilege
protected

Privilege level at which the handler may execute.

Definition at line 327 of file Event.h.

Referenced by isValidHandlerMapping().

◆ m_Lock

Spinlock Event::m_Lock
protected

Spinlock for controlling access to the thread list.

Definition at line 342 of file Event.h.

Referenced by beginDispatch(), beginRetirement(), beginSend(), completeDelivery(), deregisterThread(), pendingCount(), registerThread(), and waitForDeliveries().

◆ m_Magic

uint64_t Event::m_Magic
protected

Magic number for verification.

Definition at line 336 of file Event.h.

◆ m_NestingLevel

size_t Event::m_NestingLevel
protected

Specific nesting level, or ~0UL.

Definition at line 333 of file Event.h.

◆ m_pFirstActiveDelivery

Delivery* Event::m_pFirstActiveDelivery
private

Intrusive active-callback list; Delivery owns the link storage.

Definition at line 386 of file Event.h.

Referenced by beginDispatch(), and waitForDeliveries().

◆ m_SendersInFlight

size_t Event::m_SendersInFlight
private

sendEvent calls admitted before close-and-drain.

Definition at line 383 of file Event.h.

Referenced by beginRetirement(), beginSend(), completeDelivery(), deregisterThread(), and waitForDeliveries().

◆ m_Threads

List<Thread*> Event::m_Threads
protected

One entry per queued or actively dispatched delivery.

Definition at line 339 of file Event.h.

Referenced by completeDelivery(), deregisterThread(), pendingCount(), registerThread(), and waitForDeliveries().


The documentation for this class was generated from the following files: