* Port:
- Send() now also gets the message to send as parameter. - Added methods to reserve and unreserve space in the buffer. * RequestAllocator: Uses the port buffer reservation methods now. This allows to let more than one RequestAllocator use a Port in a stack-like manner. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29565 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
c1f05b2803
commit
b19ee1e164
@ -33,10 +33,14 @@ public:
|
||||
|
||||
const Info* GetInfo() const;
|
||||
|
||||
void* GetBuffer() const;
|
||||
int32 GetCapacity() const;
|
||||
void* GetBuffer() const { return fBuffer; }
|
||||
int32 GetCapacity() const { return fCapacity; }
|
||||
|
||||
status_t Send(int32 size);
|
||||
void Reserve(int32 endOffset);
|
||||
void Unreserve(int32 endOffset);
|
||||
int32 ReservedSize() const { return fReservedSize; }
|
||||
|
||||
status_t Send(const void* message, int32 size);
|
||||
status_t Receive(void** _message, size_t* _size,
|
||||
bigtime_t timeout = -1);
|
||||
|
||||
@ -46,6 +50,7 @@ private:
|
||||
Info fInfo;
|
||||
uint8* fBuffer;
|
||||
int32 fCapacity;
|
||||
int32 fReservedSize;
|
||||
status_t fInitStatus;
|
||||
bool fOwner;
|
||||
};
|
||||
|
@ -61,6 +61,8 @@ private:
|
||||
Port* fPort;
|
||||
Request* fRequest;
|
||||
int32 fRequestSize;
|
||||
int32 fPortReservedOffset;
|
||||
int32 fRequestOffset;
|
||||
area_id fAllocatedAreas[MAX_REQUEST_ADDRESS_COUNT];
|
||||
int32 fAllocatedAreaCount;
|
||||
DeferredInitInfo fDeferredInitInfos[MAX_REQUEST_ADDRESS_COUNT];
|
||||
|
@ -21,10 +21,12 @@ static const int32 kMaxPortSize = 64 * 1024; // 64 kB
|
||||
|
||||
// constructor
|
||||
Port::Port(int32 size)
|
||||
: fBuffer(NULL),
|
||||
fCapacity(0),
|
||||
fInitStatus(B_NO_INIT),
|
||||
fOwner(true)
|
||||
:
|
||||
fBuffer(NULL),
|
||||
fCapacity(0),
|
||||
fReservedSize(0),
|
||||
fInitStatus(B_NO_INIT),
|
||||
fOwner(true)
|
||||
{
|
||||
// adjust size to be within the sane bounds
|
||||
if (size < kMinPortSize)
|
||||
@ -57,10 +59,12 @@ Port::Port(int32 size)
|
||||
|
||||
// constructor
|
||||
Port::Port(const Info* info)
|
||||
: fBuffer(NULL),
|
||||
fCapacity(0),
|
||||
fInitStatus(B_NO_INIT),
|
||||
fOwner(false)
|
||||
:
|
||||
fBuffer(NULL),
|
||||
fCapacity(0),
|
||||
fReservedSize(0),
|
||||
fInitStatus(B_NO_INIT),
|
||||
fOwner(false)
|
||||
{
|
||||
// check parameters
|
||||
if (!info || info->owner_port < 0 || info->client_port < 0
|
||||
@ -126,35 +130,39 @@ Port::GetInfo() const
|
||||
}
|
||||
|
||||
|
||||
// GetBuffer
|
||||
void*
|
||||
Port::GetBuffer() const
|
||||
// Reserve
|
||||
void
|
||||
Port::Reserve(int32 endOffset)
|
||||
{
|
||||
return fBuffer;
|
||||
if (endOffset > fReservedSize)
|
||||
fReservedSize = endOffset;
|
||||
}
|
||||
|
||||
|
||||
// GetCapacity
|
||||
int32
|
||||
Port::GetCapacity() const
|
||||
// Unreserve
|
||||
void
|
||||
Port::Unreserve(int32 endOffset)
|
||||
{
|
||||
return fCapacity;
|
||||
if (endOffset < fReservedSize)
|
||||
fReservedSize = endOffset;
|
||||
}
|
||||
|
||||
|
||||
// Send
|
||||
status_t
|
||||
Port::Send(int32 size)
|
||||
Port::Send(const void* message, int32 size)
|
||||
{
|
||||
if (fInitStatus != B_OK)
|
||||
return fInitStatus;
|
||||
if (size <= 0 || size > fCapacity)
|
||||
if (size <= 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
port_id port = (fOwner ? fInfo.client_port : fInfo.owner_port);
|
||||
status_t error;
|
||||
do {
|
||||
error = write_port(port, 0, fBuffer, size);
|
||||
error = write_port(port, 0, message, size);
|
||||
} while (error == B_INTERRUPTED);
|
||||
|
||||
return (fInitStatus = error);
|
||||
}
|
||||
|
||||
|
@ -14,13 +14,15 @@
|
||||
|
||||
// constructor
|
||||
RequestAllocator::RequestAllocator(Port* port)
|
||||
: fError(B_NO_INIT),
|
||||
fPort(NULL),
|
||||
fRequest(NULL),
|
||||
fRequestSize(0),
|
||||
fAllocatedAreaCount(0),
|
||||
fDeferredInitInfoCount(0),
|
||||
fRequestInPortBuffer(false)
|
||||
:
|
||||
fError(B_NO_INIT),
|
||||
fPort(NULL),
|
||||
fRequest(NULL),
|
||||
fRequestSize(0),
|
||||
fPortReservedOffset(0),
|
||||
fAllocatedAreaCount(0),
|
||||
fDeferredInitInfoCount(0),
|
||||
fRequestInPortBuffer(false)
|
||||
{
|
||||
Init(port);
|
||||
}
|
||||
@ -39,6 +41,7 @@ RequestAllocator::Init(Port* port)
|
||||
if (port) {
|
||||
fPort = port;
|
||||
fError = fPort->InitCheck();
|
||||
fPortReservedOffset = fPort->ReservedSize();
|
||||
}
|
||||
return fError;
|
||||
}
|
||||
@ -47,20 +50,26 @@ RequestAllocator::Init(Port* port)
|
||||
void
|
||||
RequestAllocator::Uninit()
|
||||
{
|
||||
if (!fRequestInPortBuffer)
|
||||
if (fRequestInPortBuffer)
|
||||
fPort->Unreserve(fPortReservedOffset);
|
||||
else
|
||||
free(fRequest);
|
||||
|
||||
for (int32 i = 0; i < fAllocatedAreaCount; i++)
|
||||
delete_area(fAllocatedAreas[i]);
|
||||
fAllocatedAreaCount = 0;
|
||||
|
||||
for (int32 i = 0; i < fDeferredInitInfoCount; i++) {
|
||||
if (fDeferredInitInfos[i].inPortBuffer)
|
||||
free(fDeferredInitInfos[i].data);
|
||||
}
|
||||
|
||||
fDeferredInitInfoCount = 0;
|
||||
fError = B_NO_INIT;
|
||||
fPort = NULL;
|
||||
fRequest = NULL;
|
||||
fRequestSize = 0;
|
||||
fPortReservedOffset = 0;
|
||||
}
|
||||
|
||||
// Error
|
||||
@ -96,11 +105,18 @@ RequestAllocator::AllocateRequest(int32 size)
|
||||
{
|
||||
if (fError != B_OK)
|
||||
RETURN_ERROR(fError);
|
||||
if (size < (int32)sizeof(Request) || size > fPort->GetCapacity())
|
||||
|
||||
fRequestOffset = (fPortReservedOffset + 7) / 8 * 8;
|
||||
|
||||
if (size < (int32)sizeof(Request)
|
||||
|| fRequestOffset + size > fPort->GetCapacity()) {
|
||||
RETURN_ERROR(fError = B_BAD_VALUE);
|
||||
fRequest = (Request*)fPort->GetBuffer();
|
||||
}
|
||||
|
||||
fRequest = (Request*)((uint8*)fPort->GetBuffer() + fRequestOffset);
|
||||
fRequestSize = size;
|
||||
fRequestInPortBuffer = true;
|
||||
fPort->Reserve(fRequestOffset + fRequestSize);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -129,6 +145,7 @@ RequestAllocator::ReadRequest(bigtime_t timeout)
|
||||
|
||||
// init the request
|
||||
fRequest = (Request*)message;
|
||||
fRequestOffset = 0;
|
||||
fRequestSize = messageSize;
|
||||
fRequestInPortBuffer = false;
|
||||
|
||||
@ -185,9 +202,10 @@ RequestAllocator::AllocateAddress(Address& address, int32 size, int32 align,
|
||||
// get the next free aligned offset in the port buffer
|
||||
int32 offset = (fRequestSize + align - 1) / align * align;
|
||||
// allocate the data
|
||||
if (offset + size <= fPort->GetCapacity()) {
|
||||
if (fRequestOffset + offset + size <= fPort->GetCapacity()) {
|
||||
// there's enough free space in the port buffer
|
||||
fRequestSize = offset + size;
|
||||
fPort->Reserve(fRequestOffset + fRequestSize);
|
||||
if (deferredInit) {
|
||||
DeferredInitInfo& info
|
||||
= fDeferredInitInfos[fDeferredInitInfoCount];
|
||||
|
@ -77,9 +77,8 @@ RequestPort::SendRequest(RequestAllocator* allocator)
|
||||
// check initialization and parameters
|
||||
if (InitCheck() != B_OK)
|
||||
RETURN_ERROR(InitCheck());
|
||||
if (!allocator || allocator->GetRequest() != fPort.GetBuffer()
|
||||
|| allocator->GetRequestSize() < (int32)sizeof(Request)
|
||||
|| allocator->GetRequestSize() > fPort.GetCapacity()) {
|
||||
if (!allocator || allocator->GetRequest() == NULL
|
||||
|| allocator->GetRequestSize() < (int32)sizeof(Request)) {
|
||||
RETURN_ERROR(B_BAD_VALUE);
|
||||
}
|
||||
allocator->FinishDeferredInit();
|
||||
@ -97,7 +96,8 @@ RequestPort::SendRequest(RequestAllocator* allocator)
|
||||
debugger("Request is not a kernel request.");
|
||||
}
|
||||
#endif
|
||||
RETURN_ERROR(fPort.Send(allocator->GetRequestSize()));
|
||||
RETURN_ERROR(fPort.Send(allocator->GetRequest(),
|
||||
allocator->GetRequestSize()));
|
||||
}
|
||||
|
||||
// SendRequest
|
||||
|
Loading…
Reference in New Issue
Block a user