b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync/* $Id$ */
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync/** @file
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * IPRT - Internal RTReq header.
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync */
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync/*
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * Copyright (C) 2006-2011 Oracle Corporation
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync *
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * available from http://www.virtualbox.org. This file is free software;
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * you can redistribute it and/or modify it under the terms of the GNU
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * General Public License (GPL) as published by the Free Software
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync *
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * The contents of this file may alternatively be used under the terms
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * of the Common Development and Distribution License Version 1.0
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * VirtualBox OSE distribution, in which case the provisions of the
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * CDDL are applicable instead of those of the GPL.
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync *
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * You may elect to license modified versions of this file under the
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * terms and conditions of either the GPL or the CDDL or both.
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync */
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync#ifndef ___internal_req_h
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync#define ___internal_req_h
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync#include <iprt/types.h>
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsyncRT_C_DECLS_BEGIN
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync/**
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync * Request state.
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsynctypedef enum RTREQSTATE
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync{
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** The state is invalid. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync RTREQSTATE_INVALID = 0,
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** The request have been allocated and is in the process of being filed. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync RTREQSTATE_ALLOCATED,
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** The request is queued by the requester. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync RTREQSTATE_QUEUED,
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** The request is begin processed. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync RTREQSTATE_PROCESSING,
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** The request is completed, the requester is begin notified. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync RTREQSTATE_COMPLETED,
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** The request packet is in the free chain. (The requester */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync RTREQSTATE_FREE
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync} RTREQSTATE;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync/**
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync * RT Request packet.
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync *
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync * This is used to request an action in the queue handler thread.
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsyncstruct RTREQ
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync{
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** Magic number (RTREQ_MAGIC). */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync uint32_t u32Magic;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** Set if the event semaphore is clear. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync volatile bool fEventSemClear;
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsync /** Set if the push back semaphore should be signaled when the request
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsync * is picked up from the queue. */
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsync volatile bool fSignalPushBack;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** Set if pool, clear if queue. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync volatile bool fPoolOrQueue;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** IPRT status code for the completed request. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync volatile int32_t iStatusX;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** Request state. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync volatile RTREQSTATE enmState;
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsync /** The reference count. */
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsync volatile uint32_t cRefs;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** Pointer to the next request in the chain. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync struct RTREQ * volatile pNext;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync union
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync {
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** Pointer to the pool this packet belongs to. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync RTREQPOOL hPool;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** Pointer to the queue this packet belongs to. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync RTREQQUEUE hQueue;
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsync /** Opaque owner access. */
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsync void *pv;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync } uOwner;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync
8867771015571c5542d39e393d7fe6304421a928vboxsync /** Timestamp take when the request was submitted to a pool. Not used
8867771015571c5542d39e393d7fe6304421a928vboxsync * for queued request. */
8867771015571c5542d39e393d7fe6304421a928vboxsync uint64_t uSubmitNanoTs;
c999f225d03074008a0c21cdd5d3594da476e243vboxsync /** Requester completion event sem. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync RTSEMEVENT EventSem;
c999f225d03074008a0c21cdd5d3594da476e243vboxsync /** Request pushback event sem. Allocated lazily. */
c999f225d03074008a0c21cdd5d3594da476e243vboxsync RTSEMEVENTMULTI hPushBackEvt;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** Flags, RTREQ_FLAGS_*. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync uint32_t fFlags;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** Request type. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync RTREQTYPE enmType;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** Request specific data. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync union RTREQ_U
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync {
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** RTREQTYPE_INTERNAL. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync struct
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync {
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** Pointer to the function to be called. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync PFNRT pfn;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** Number of arguments. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync uint32_t cArgs;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync /** Array of arguments. */
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync uintptr_t aArgs[64];
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync } Internal;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync } u;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync};
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync
fe14fe6d46ce87a9b25cbdacb3a20b1f87bf34c7vboxsync/** Internal request representation. */
fe14fe6d46ce87a9b25cbdacb3a20b1f87bf34c7vboxsynctypedef RTREQ RTREQINT;
fe14fe6d46ce87a9b25cbdacb3a20b1f87bf34c7vboxsync/** Pointer to an internal request representation. */
fe14fe6d46ce87a9b25cbdacb3a20b1f87bf34c7vboxsynctypedef RTREQINT *PRTREQINT;
4f3f6eb7aecf332523a1b44ff1e0cda506408273vboxsync
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync/**
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * Internal queue instance.
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync */
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsynctypedef struct RTREQQUEUEINT
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync{
17ef1920962b3df57bf6d2704ced1586396d96f0vboxsync /** Magic value (RTREQQUEUE_MAGIC). */
17ef1920962b3df57bf6d2704ced1586396d96f0vboxsync uint32_t u32Magic;
17ef1920962b3df57bf6d2704ced1586396d96f0vboxsync /** Set if busy (pending or processing requests). */
17ef1920962b3df57bf6d2704ced1586396d96f0vboxsync bool volatile fBusy;
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync /** Head of the request queue. Atomic. */
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync volatile PRTREQ pReqs;
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync /** The last index used during alloc/free. */
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync volatile uint32_t iReqFree;
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync /** Number of free request packets. */
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync volatile uint32_t cReqFree;
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync /** Array of pointers to lists of free request packets. Atomic. */
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync volatile PRTREQ apReqFree[9];
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync /** Requester event sem.
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * The request can use this event semaphore to wait/poll for new requests.
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync */
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync RTSEMEVENT EventSem;
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync} RTREQQUEUEINT;
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync/** Pointer to an internal queue instance. */
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsynctypedef struct RTREQQUEUEINT *PRTREQQUEUEINT;
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsync/** Pointer to a request thread pool instance. */
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsynctypedef struct RTREQPOOLINT *PRTREQPOOLINT;
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsync
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsync
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsync/* req.cpp */
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsyncDECLHIDDEN(int) rtReqAlloc(RTREQTYPE enmType, bool fPoolOrQueue, void *pvOwner, PRTREQ *phReq);
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsyncDECLHIDDEN(int) rtReqReInit(PRTREQINT pReq, RTREQTYPE enmType);
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsyncDECLHIDDEN(void) rtReqFreeIt(PRTREQINT pReq);
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsyncDECLHIDDEN(int) rtReqProcessOne(PRTREQ pReq);
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsync
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsync/* reqpool.cpp / reqqueue.cpp. */
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsyncDECLHIDDEN(void) rtReqQueueSubmit(PRTREQQUEUEINT pQueue, PRTREQINT pReq);
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsyncDECLHIDDEN(void) rtReqPoolSubmit(PRTREQPOOLINT pPool, PRTREQINT pReq);
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsyncDECLHIDDEN(bool) rtReqQueueRecycle(PRTREQQUEUEINT pQueue, PRTREQINT pReq);
9de47c4ec7b0fc9a384e4b815153de399da7b8devboxsyncDECLHIDDEN(bool) rtReqPoolRecycle(PRTREQPOOLINT pPool, PRTREQINT pReq);
17ef1920962b3df57bf6d2704ced1586396d96f0vboxsync
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsyncRT_C_DECLS_END
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync#endif
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync