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