|
The Pedigree Project 0.1
|
#include <RequestQueue.h>
Inheritance diagram for RequestQueue:
Collaboration diagram for RequestQueue:Classes | |
| class | IntakeLane |
| struct | IntakeNode |
| class | PreallocatedRequest |
| class | Request |
| class | RequestQueueOverrunChecker |
Public Member Functions | |
| RequestQueue (const String &name) | |
| virtual void | initialise () |
| virtual void | destroy () |
| MUST_USE_RESULT uint64_t | addRequest (size_t priority, uint64_t p1=0, uint64_t p2=0, uint64_t p3=0, uint64_t p4=0, uint64_t p5=0, uint64_t p6=0, uint64_t p7=0, uint64_t p8=0) |
| MUST_USE_RESULT uint64_t | addRequest (size_t priority, ActionOnDuplicate action, uint64_t p1=0, uint64_t p2=0, uint64_t p3=0, uint64_t p4=0, uint64_t p5=0, uint64_t p6=0, uint64_t p7=0, uint64_t p8=0) |
| uint64_t | addAsyncRequest (size_t priority, uint64_t p1=0, uint64_t p2=0, uint64_t p3=0, uint64_t p4=0, uint64_t p5=0, uint64_t p6=0, uint64_t p7=0, uint64_t p8=0) |
| MUST_USE_RESULT bool | publishAsyncRequest (size_t priority, uint64_t p1=0, uint64_t p2=0, uint64_t p3=0, uint64_t p4=0, uint64_t p5=0, uint64_t p6=0, uint64_t p7=0, uint64_t p8=0) |
| bool | canWaitForCompletion () |
| MUST_USE_RESULT bool | waitForPreallocated (PreallocatedRequest &request) |
| MUST_USE_RESULT PreallocatedPublishResult | publishPreallocated (PreallocatedRequest &request, size_t priority, uint64_t p1=0, uint64_t p2=0, uint64_t p3=0, uint64_t p4=0, uint64_t p5=0, uint64_t p6=0, uint64_t p7=0, uint64_t p8=0) |
| MUST_USE_RESULT PreallocatedPublishResult | republishPreallocatedWhileReleasing (PreallocatedRequest &request, size_t priority, uint64_t p1=0, uint64_t p2=0, uint64_t p3=0, uint64_t p4=0, uint64_t p5=0, uint64_t p6=0, uint64_t p7=0, uint64_t p8=0) |
| MUST_USE_RESULT bool | halt () |
| MUST_USE_RESULT bool | resume () |
| LifecycleState | getLifecycleState () |
| bool | drain () |
Protected Types | |
| enum class | NextRequestResult { Item , Empty , Retry } |
Protected Member Functions | |
| virtual bool | workerPlacement (ThreadPlacement &) const |
| virtual uint64_t | executeRequest (uint64_t p1, uint64_t p2, uint64_t p3, uint64_t p4, uint64_t p5, uint64_t p6, uint64_t p7, uint64_t p8)=0 |
| RequestQueue (const RequestQueue &) | |
| void | operator= (const RequestQueue &) |
| virtual bool | compareRequests (const Request &a, const Request &b) |
| virtual void | cancelRequest (const Request &request) |
| int | work () |
| NextRequestResult | getNextRequest (Request *&request) |
| bool | drainIntakeLocked (size_t priority) |
| void | publishRequest (Request *request) |
| Request * | findDuplicate (const Request &request) |
| void | discardRequest (Request *request) |
| uint64_t | addAsyncRequestInternal (size_t priority, uint64_t p1, uint64_t p2, uint64_t p3, uint64_t p4, uint64_t p5, uint64_t p6, uint64_t p7, uint64_t p8) |
| PreallocatedPublishResult | publishPreallocatedRequest (PreallocatedRequest &request, PreallocatedRequest::State availableState, size_t priority, uint64_t p1, uint64_t p2, uint64_t p3, uint64_t p4, uint64_t p5, uint64_t p6, uint64_t p7, uint64_t p8) |
| void | releasePreallocatedRequest (Request *request) |
| void | invokeCancelRequest (const Request &request) |
| bool | callbackActiveOnCurrentThread () const |
| void | releaseRequest (Request *request) |
| uint64_t | waitForRequest (Request *request) |
| bool | startWorker () |
| bool | stopWorker () |
| void | closePreallocatedAdmission () |
| void | waitForPreallocatedPublishers () |
Static Protected Member Functions | |
| static int | trampoline (void *p) |
| static void | completeRequest (Request *request, uint64_t returnValue, bool rejected) |
| static void | retainRequest (Request *request) |
Protected Attributes | |
| IntakeLane | m_IntakeLanes [REQUEST_QUEUE_NUM_PRIORITIES] |
| Request * | m_pRequestQueue [REQUEST_QUEUE_NUM_PRIORITIES] |
| Request * | m_pRequestQueueTail [REQUEST_QUEUE_NUM_PRIORITIES] |
| Request * | m_pActiveRequest |
| Atomic< size_t > | m_State |
| Mutex | m_LifecycleMutex |
| WaitQueue | m_RequestQueueWaiters |
| WaitQueue | m_WorkerWaiters |
| Thread * | m_pThread |
| Atomic< PerProcessorScheduler * > | m_pWorkerScheduler |
| SchedulerWorkerWake | m_WorkerWake |
| Atomic< size_t > | m_bWorkerReady |
| Atomic< size_t > | m_bWorkerActive |
| size_t | m_WorkerProgressGeneration |
| RequestQueueOverrunChecker | m_OverrunChecker |
| Timer * | m_pOverrunTimer |
| Atomic< size_t > | m_PublicationState |
| size_t | m_nMaxAsyncRequests |
| Atomic< size_t > | m_nAsyncRequests |
| Atomic< size_t > | m_nTotalRequests |
| Atomic< size_t > | m_nActiveRequests |
| NormalStaticString | m_Name |
Static Protected Attributes | |
| static constexpr size_t | PublicationClosed = static_cast<size_t>(1) << ((sizeof(size_t) * 8) - 1) |
| static constexpr size_t | PublicationCountMask = ~PublicationClosed |
Implements a request queue with one worker thread.
Synchronous callers wait on a request completion owned by the queue. Asynchronous requests are placed directly on the same queue and never need a wrapper thread.
Definition at line 52 of file RequestQueue.h.
| enum RequestQueue::ActionOnDuplicate |
Definition at line 269 of file RequestQueue.h.
|
strong |
Definition at line 278 of file RequestQueue.h.
|
strongprotected |
Definition at line 452 of file RequestQueue.h.
|
strong |
Definition at line 56 of file RequestQueue.h.
|
strong |
Definition at line 252 of file RequestQueue.h.
| RequestQueue::RequestQueue | ( | const String & | name | ) |
Creates a new RequestQueue.
Definition at line 197 of file RequestQueue.cc.
References m_pRequestQueue.
|
virtual |
Definition at line 242 of file RequestQueue.cc.
| uint64_t RequestQueue::addAsyncRequest | ( | size_t | priority, |
| uint64_t | p1 = 0, |
||
| uint64_t | p2 = 0, |
||
| uint64_t | p3 = 0, |
||
| uint64_t | p4 = 0, |
||
| uint64_t | p5 = 0, |
||
| uint64_t | p6 = 0, |
||
| uint64_t | p7 = 0, |
||
| uint64_t | p8 = 0 |
||
| ) |
Adds an asynchronous request to the queue without waiting for execution.
Definition at line 591 of file RequestQueue.cc.
Referenced by CacheManager::addCacheRequest().
Here is the caller graph for this function:
|
protected |
Definition at line 736 of file RequestQueue.cc.
| uint64_t RequestQueue::addRequest | ( | size_t | priority, |
| ActionOnDuplicate | action, | ||
| uint64_t | p1 = 0, |
||
| uint64_t | p2 = 0, |
||
| uint64_t | p3 = 0, |
||
| uint64_t | p4 = 0, |
||
| uint64_t | p5 = 0, |
||
| uint64_t | p6 = 0, |
||
| uint64_t | p7 = 0, |
||
| uint64_t | p8 = 0 |
||
| ) |
Adds a request to the queue with optional behavior on duplicate detection.
Definition at line 506 of file RequestQueue.cc.
References callbackActiveOnCurrentThread(), discardRequest(), drainIntakeLocked(), executeRequest(), findDuplicate(), ProcessorBase::information(), Scheduler::instance(), Mutex::isOwnedByCurrentThread(), m_LifecycleMutex, m_nTotalRequests, m_RequestQueueWaiters, m_State, publishRequest(), retainRequest(), and Scheduler::yield().
| uint64_t RequestQueue::addRequest | ( | size_t | priority, |
| uint64_t | p1 = 0, |
||
| uint64_t | p2 = 0, |
||
| uint64_t | p3 = 0, |
||
| uint64_t | p4 = 0, |
||
| uint64_t | p5 = 0, |
||
| uint64_t | p6 = 0, |
||
| uint64_t | p7 = 0, |
||
| uint64_t | p8 = 0 |
||
| ) |
Adds a request to the queue. Blocks until it finishes and returns the result, deferring signal and terminal interruption until completion.
| priority | The priority to attach to this request. Lower number is higher priority. During a destroy-time cancelRequest() callback, nested allocation-backed publication is rejected before allocation or another cancellation callback; the caller retains any proposed payload. |
Definition at line 501 of file RequestQueue.cc.
References addRequest().
Referenced by CacheManager::addCacheRequest(), addRequest(), ScsiDisk::flushCachePage(), ScsiDisk::retireCachePageCallback(), and ScsiDisk::syncAll().
Here is the caller graph for this function:
|
protected |
True when the current Thread is inside this queue's callback.
Definition at line 851 of file RequestQueue.cc.
Referenced by CacheManager::addCacheRequest(), addRequest(), canWaitForCompletion(), destroy(), drain(), halt(), publishAsyncRequest(), and resume().
Here is the caller graph for this function:
|
inlineprotectedvirtual |
Releases payload ownership for a request that will not execute.
This runs without the queue guard for rejected candidates (including stopped queues, duplicates and capacity limits) and queued requests cancelled by destroy(). Implementations used by allocation-free producers must not sleep. Derived destructors must call destroy() while their override and member state are still alive. During destroy(), the lifecycle is serialized: halt() and resume() on this queue return false, while recursive destroy() is a fatal contract violation.
Reimplemented in ScsiController, CacheManager, ZombieQueue, Ehci, Ohci, Uhci, Xhci, and UsbHubDevice.
Definition at line 444 of file RequestQueue.h.
Referenced by invokeCancelRequest().
Here is the caller graph for this function:| bool RequestQueue::canWaitForCompletion | ( | ) |
False for worker/callback callers or contexts which cannot sleep.
Definition at line 855 of file RequestQueue.cc.
References callbackActiveOnCurrentThread(), ProcessorBase::getInterrupts(), ProcessorBase::information(), Mutex::isOwnedByCurrentThread(), m_LifecycleMutex, and m_RequestQueueWaiters.
Referenced by waitForPreallocated().
Here is the caller graph for this function:
|
protected |
Definition at line 420 of file RequestQueue.cc.
|
inlineprotectedvirtual |
Defaults to never comparing as equal. Used to determine duplicates among allocation-backed synchronous and asynchronous requests. Preallocated tokens use identity instead and are never passed here. This runs under the queue's non-sleeping guard and therefore must not block.
Reimplemented in CacheManager, and AtaController.
Definition at line 429 of file RequestQueue.h.
Referenced by findDuplicate().
Here is the caller graph for this function:
|
staticprotected |
Complete a request and wake every synchronous caller.
Definition at line 1029 of file RequestQueue.cc.
Referenced by destroy(), and work().
Here is the caller graph for this function:
|
virtual |
Destroys the queue and joins its worker.
Every external IRQ, timer, and thread producer must already be quiesced. Closing admission drains callers which already entered the publication gate; it cannot extend this object's lifetime around future callers. The queue worker itself must not call this synchronous drain operation.
Definition at line 434 of file RequestQueue.cc.
References callbackActiveOnCurrentThread(), completeRequest(), drainIntakeLocked(), invokeCancelRequest(), Mutex::isOwnedByCurrentThread(), m_LifecycleMutex, m_nActiveRequests, m_nTotalRequests, m_pActiveRequest, m_pRequestQueue, m_RequestQueueWaiters, and m_State.
Referenced by UsbMassStorageDevice::prepareForDisconnection(), IsaAtaController::shutdown(), PciAtaController::shutdown(), and CacheManager::shutdown().
Here is the caller graph for this function:
|
protected |
Reject and delete a candidate that was never published.
Definition at line 1044 of file RequestQueue.cc.
References invokeCancelRequest().
Referenced by addRequest().
Here is the caller graph for this function:| bool RequestQueue::drain | ( | ) |
Waits until every request published before and during the wait has completed. Producers must already be quiesced; the queue remains accepting so callbacks may publish dependent work while draining.
Definition at line 887 of file RequestQueue.cc.
References callbackActiveOnCurrentThread(), ProcessorBase::information(), m_nTotalRequests, m_RequestQueueWaiters, and m_State.
Referenced by ScsiController::shutdownDiskCaches().
Here is the caller graph for this function:
|
protected |
Move one priority's accepted intake into its guarded ready list.
Definition at line 944 of file RequestQueue.cc.
References m_IntakeLanes, and m_pRequestQueue.
Referenced by addRequest(), and destroy().
Here is the caller graph for this function:
|
protectedpure virtual |
Callback - classes are expected to inherit and override this function. It's called when a request needs to be executed (by the worker thread).
Implemented in IsaAtaController, PciAtaController, ScsiController, CacheManager, ZombieQueue, UsbHubDevice, Ehci, Ohci, Uhci, and Xhci.
Referenced by addRequest(), and work().
Here is the caller graph for this function:
|
protected |
Find an equivalent queued or executing request.
Definition at line 1011 of file RequestQueue.cc.
References compareRequests(), m_pActiveRequest, and m_pRequestQueue.
Referenced by addRequest().
Here is the caller graph for this function:| RequestQueue::LifecycleState RequestQueue::getLifecycleState | ( | ) |
Returns the current worker lifecycle state.
Definition at line 847 of file RequestQueue.cc.
References m_State.
Referenced by UsbHubDevice::executeRequest(), UsbHubDevice::initialiseDriver(), and UsbHubDevice::portReset().
Here is the caller graph for this function:
|
protected |
Get the next request without bypassing a transient higher priority.
Definition at line 972 of file RequestQueue.cc.
References m_IntakeLanes, and m_pRequestQueue.
Referenced by work().
Here is the caller graph for this function:| bool RequestQueue::halt | ( | ) |
Stop and join the worker, retaining queued requests for resume(). A worker self-call returns false without changing the queue. A failed external join returns false with admission closed and the lifecycle in Stopping; a later halt() or destroy() must retry the drain.
Definition at line 807 of file RequestQueue.cc.
References callbackActiveOnCurrentThread(), Mutex::isOwnedByCurrentThread(), and m_LifecycleMutex.
|
virtual |
Initialises the queue, spawning the worker thread.
Reimplemented in CacheManager.
Definition at line 261 of file RequestQueue.cc.
References resume().
Referenced by CacheManager::initialise(), UsbHubDevice::initialiseDriver(), and PciAtaController::PciAtaController().
Here is the caller graph for this function:
|
protected |
Calls a derived cancellation hook inside a cleanup-safe boundary.
Definition at line 1049 of file RequestQueue.cc.
References cancelRequest().
Referenced by destroy(), and discardRequest().
Here is the caller graph for this function:| bool RequestQueue::publishAsyncRequest | ( | size_t | priority, |
| uint64_t | p1 = 0, |
||
| uint64_t | p2 = 0, |
||
| uint64_t | p3 = 0, |
||
| uint64_t | p4 = 0, |
||
| uint64_t | p5 = 0, |
||
| uint64_t | p6 = 0, |
||
| uint64_t | p7 = 0, |
||
| uint64_t | p8 = 0 |
||
| ) |
Publish distinct asynchronous work, including from this queue's worker. This path allocates a request, then uses the non-waiting intake gate: it does not compare requests or wait for backlog space. The caller must be in a waitable thread context and retains payload ownership on rejection. It is not a hard-IRQ publication path.
Definition at line 597 of file RequestQueue.cc.
References callbackActiveOnCurrentThread(), ProcessorBase::executionContext(), ProcessorBase::getInterrupts(), Mutex::isOwnedByCurrentThread(), m_LifecycleMutex, m_nTotalRequests, m_PublicationState, m_State, and publishRequest().
| RequestQueue::PreallocatedPublishResult RequestQueue::publishPreallocated | ( | PreallocatedRequest & | request, |
| size_t | priority, | ||
| uint64_t | p1 = 0, |
||
| uint64_t | p2 = 0, |
||
| uint64_t | p3 = 0, |
||
| uint64_t | p4 = 0, |
||
| uint64_t | p5 = 0, |
||
| uint64_t | p6 = 0, |
||
| uint64_t | p7 = 0, |
||
| uint64_t | p8 = 0 |
||
| ) |
Publishes allocation-free work using a preallocated token.
This path performs no allocation, deallocation, logging, or blocking. It does not participate in compareRequests(): token identity provides coalescing, and allocation-backed requests are always a distinct duplicate domain. Preallocated work bypasses the allocation-backed asynchronous backlog limit. The same token cannot be republished until execution or cancellation has returned it to Idle. TokenBusy is returned only for work whose queue admission can no longer fail. The queue and token owner must outlive this call; destroy() requires every producer to be quiesced first.
Raw hardware handlers must defer through the typed IRQ dispatcher, not call RequestQueue publication directly.
Definition at line 640 of file RequestQueue.cc.
|
protected |
Definition at line 654 of file RequestQueue.cc.
|
protected |
Publish an accepted request through its priority's MPSC intake.
Definition at line 922 of file RequestQueue.cc.
References m_IntakeLanes, m_pWorkerScheduler, and PerProcessorScheduler::ringIrqWorkDoorbell().
Referenced by addRequest(), and publishAsyncRequest().
Here is the caller graph for this function:
|
protected |
Returns an executed or cancelled preallocated request to its owner.
Definition at line 1054 of file RequestQueue.cc.
References m_RequestQueueWaiters.
|
protected |
Definition at line 1104 of file RequestQueue.cc.
| RequestQueue::PreallocatedPublishResult RequestQueue::republishPreallocatedWhileReleasing | ( | PreallocatedRequest & | request, |
| size_t | priority, | ||
| uint64_t | p1 = 0, |
||
| uint64_t | p2 = 0, |
||
| uint64_t | p3 = 0, |
||
| uint64_t | p4 = 0, |
||
| uint64_t | p5 = 0, |
||
| uint64_t | p6 = 0, |
||
| uint64_t | p7 = 0, |
||
| uint64_t | p8 = 0 |
||
| ) |
Republishes a token while its release callback is retiring it.
This is accepted only from the Releasing state. A release callback may use this narrowly scoped allocation-free handoff to preserve an already-observed follow-up; other same-queue publication is rejected.
Definition at line 647 of file RequestQueue.cc.
| bool RequestQueue::resume | ( | ) |
Resume RequestQueue operations.
Definition at line 820 of file RequestQueue.cc.
References Timer::armHandler(), callbackActiveOnCurrentThread(), Machine::getTimer(), Mutex::isOwnedByCurrentThread(), m_LifecycleMutex, startWorker(), and Timer::supportsDeadlines().
Referenced by initialise().
Here is the caller graph for this function:
|
staticprotected |
Reference management for requests shared by worker and callers.
Definition at line 1100 of file RequestQueue.cc.
Referenced by addRequest().
Here is the caller graph for this function:
|
protected |
Start/stop helpers called with m_LifecycleMutex held.
Definition at line 268 of file RequestQueue.cc.
References Scheduler::instance(), m_bWorkerReady, m_PublicationState, m_pWorkerScheduler, m_RequestQueueWaiters, m_State, trampoline(), and Scheduler::yield().
Referenced by resume().
Here is the caller graph for this function:
|
protected |
Definition at line 357 of file RequestQueue.cc.
|
staticprotected |
Thread trampoline
Definition at line 917 of file RequestQueue.cc.
References work().
Referenced by startWorker().
Here is the caller graph for this function:| bool RequestQueue::waitForPreallocated | ( | PreallocatedRequest & | request | ) |
Joins execution, cancellation, and release callback retirement. The caller retains this queue and owns the token until this returns.
Definition at line 869 of file RequestQueue.cc.
References canWaitForCompletion(), m_RequestQueueWaiters, and WaitQueue::Guard::waitForCompletion().
|
protected |
Definition at line 424 of file RequestQueue.cc.
|
protected |
Definition at line 1116 of file RequestQueue.cc.
|
protected |
Thread worker function
Definition at line 1141 of file RequestQueue.cc.
References completeRequest(), executeRequest(), getNextRequest(), ProcessorBase::information(), Scheduler::instance(), m_bWorkerActive, m_bWorkerReady, m_nActiveRequests, m_nTotalRequests, m_pActiveRequest, m_RequestQueueWaiters, m_State, m_WorkerProgressGeneration, WaitQueue::Guard::wait(), and Scheduler::yield().
Referenced by trampoline().
Here is the caller graph for this function:
|
inlineprotectedvirtual |
Definition at line 409 of file RequestQueue.h.
|
protected |
Keeps a preempted worker accounted inside queue critical sections.
Definition at line 542 of file RequestQueue.h.
Referenced by work().
|
protected |
The worker has entered work() and installed its lifetime deferral.
Definition at line 539 of file RequestQueue.h.
Referenced by startWorker(), and work().
|
protected |
Lock-free intake shared by allocated and preallocated producers.
Definition at line 512 of file RequestQueue.h.
Referenced by drainIntakeLocked(), getNextRequest(), and publishRequest().
|
protected |
Serialises initialise/halt/resume/destroy, including worker joins.
Definition at line 526 of file RequestQueue.h.
Referenced by CacheManager::addCacheRequest(), addRequest(), canWaitForCompletion(), destroy(), halt(), publishAsyncRequest(), and resume().
|
protected |
One while the single worker is executing or releasing a request.
Definition at line 576 of file RequestQueue.h.
|
protected |
Definition at line 578 of file RequestQueue.h.
|
protected |
Definition at line 570 of file RequestQueue.h.
|
protected |
Allocation admission limit and total active async request count.
Definition at line 569 of file RequestQueue.h.
|
protected |
Number of queued or executing requests.
Definition at line 573 of file RequestQueue.h.
Referenced by addRequest(), destroy(), drain(), publishAsyncRequest(), and work().
|
protected |
Definition at line 547 of file RequestQueue.h.
|
protected |
The request currently being executed by the worker.
Definition at line 519 of file RequestQueue.h.
Referenced by destroy(), findDuplicate(), and work().
|
protected |
Definition at line 548 of file RequestQueue.h.
|
protected |
The request queue
Definition at line 515 of file RequestQueue.h.
Referenced by destroy(), drainIntakeLocked(), findDuplicate(), getNextRequest(), and RequestQueue().
|
protected |
Definition at line 516 of file RequestQueue.h.
|
protected |
Definition at line 532 of file RequestQueue.h.
|
protected |
High bit closes preallocated publication; low bits count publishers.
Definition at line 551 of file RequestQueue.h.
Referenced by publishAsyncRequest(), and startWorker().
|
protected |
Scheduler which owns the worker and its IRQ doorbell.
Definition at line 535 of file RequestQueue.h.
Referenced by publishRequest(), and startWorker().
|
protected |
Non-sleeping request-list lock and worker wait queue.
Definition at line 529 of file RequestQueue.h.
Referenced by addRequest(), canWaitForCompletion(), destroy(), drain(), releasePreallocatedRequest(), startWorker(), waitForPreallocated(), and work().
|
protected |
Worker lifecycle, atomically visible to the worker wait predicate.
Definition at line 522 of file RequestQueue.h.
Referenced by addRequest(), destroy(), drain(), getLifecycleState(), publishAsyncRequest(), startWorker(), and work().
|
protected |
Changes whenever the worker claims another queued request.
Definition at line 545 of file RequestQueue.h.
Referenced by work().
|
protected |
Definition at line 530 of file RequestQueue.h.
|
protected |
Definition at line 536 of file RequestQueue.h.
|
staticconstexprprotected |
Definition at line 508 of file RequestQueue.h.
|
staticconstexprprotected |
Definition at line 509 of file RequestQueue.h.