more improvements
This commit is contained in:
1 parent
4810617922
commit
5d7aacc28f
17 files changed
+2417
-457
No files matched your search
@@ -14,7 +14,7 @@
|
||||
{
|
||||
Driver->Storage->IORequest - I/O request allocation and lifecycle helpers.
|
||||
|
||||
Provides heap allocation/free for TIORequest records used by the
|
||||
Provides fixed-pool allocation/free for TIORequest records used by the
|
||||
submit_io / complete_io path in driver.storage.mgr.pas.
|
||||
|
||||
@author(Aaron Hance <[email protected]>)
|
||||
@@ -27,7 +27,7 @@ uses
|
||||
memory.heap,
|
||||
driver.storage.types;
|
||||
|
||||
{ Allocate a new TIORequest on the heap and initialise its core fields.
|
||||
{ Allocate a new TIORequest from the fixed request pool and initialise its core fields.
|
||||
Caller, State, Error and ByteCount are zeroed (caller fills as needed). }
|
||||
function ioreq_alloc(reqType : TIORequestType;
|
||||
device : PStorage_Device;
|
||||
@@ -35,16 +35,90 @@ function ioreq_alloc(reqType : TIORequestType;
|
||||
sectors : uint32;
|
||||
buf : pointer) : PIORequest;
|
||||
|
||||
{ Free a heap-allocated TIORequest. Safe to call with nil. }
|
||||
{ Return a pooled TIORequest to the free list. Safe to call with nil. }
|
||||
procedure ioreq_free(req : PIORequest);
|
||||
|
||||
{ Copy an existing TIORequest into a new heap allocation (deep copy of the
|
||||
{ Copy an existing TIORequest into a new pooled allocation (deep copy of the
|
||||
record, NOT the buffer it points to). Used by dispatch_next to create an
|
||||
ISR-safe copy from the CFIFO value-element. }
|
||||
function ioreq_copy(src : PIORequest) : PIORequest;
|
||||
|
||||
implementation
|
||||
|
||||
const
|
||||
IOREQ_POOL_CAPACITY = 512;
|
||||
IOREQ_REQ_OFFSET = sizeof(pointer);
|
||||
|
||||
type
|
||||
PIORequestPoolNode = ^TIORequestPoolNode;
|
||||
TIORequestPoolNode = record
|
||||
Next : PIORequestPoolNode;
|
||||
Req : TIORequest;
|
||||
end;
|
||||
|
||||
var
|
||||
ioreqPoolReady : boolean;
|
||||
ioreqPoolBuf : pointer;
|
||||
ioreqFreeList : PIORequestPoolNode;
|
||||
|
||||
procedure ioreq_pool_init();
|
||||
var
|
||||
i : uint32;
|
||||
base : uint32;
|
||||
node : PIORequestPoolNode;
|
||||
begin
|
||||
if ioreqPoolReady then exit;
|
||||
|
||||
ioreqPoolBuf := kalloc(IOREQ_POOL_CAPACITY * sizeof(TIORequestPoolNode));
|
||||
if ioreqPoolBuf = nil then exit;
|
||||
|
||||
ioreqFreeList := nil;
|
||||
base := uint32(ioreqPoolBuf);
|
||||
if IOREQ_POOL_CAPACITY > 0 then
|
||||
for i := 0 to IOREQ_POOL_CAPACITY - 1 do begin
|
||||
node := PIORequestPoolNode(base + (i * sizeof(TIORequestPoolNode)));
|
||||
node^.Next := ioreqFreeList;
|
||||
ioreqFreeList := node;
|
||||
end;
|
||||
|
||||
ioreqPoolReady := true;
|
||||
end;
|
||||
|
||||
function ioreq_take() : PIORequest;
|
||||
var
|
||||
node : PIORequestPoolNode;
|
||||
begin
|
||||
if not ioreqPoolReady then
|
||||
ioreq_pool_init();
|
||||
if not ioreqPoolReady then begin
|
||||
ioreq_take := nil;
|
||||
exit;
|
||||
end;
|
||||
|
||||
asm pushf; cli end;
|
||||
node := ioreqFreeList;
|
||||
if node <> nil then
|
||||
ioreqFreeList := node^.Next;
|
||||
asm popf end;
|
||||
|
||||
if node = nil then
|
||||
ioreq_take := nil
|
||||
else
|
||||
ioreq_take := @node^.Req;
|
||||
end;
|
||||
|
||||
procedure ioreq_release(req : PIORequest);
|
||||
var
|
||||
node : PIORequestPoolNode;
|
||||
begin
|
||||
if req = nil then exit;
|
||||
node := PIORequestPoolNode(uint32(req) - IOREQ_REQ_OFFSET);
|
||||
asm pushf; cli end;
|
||||
node^.Next := ioreqFreeList;
|
||||
ioreqFreeList := node;
|
||||
asm popf end;
|
||||
end;
|
||||
|
||||
function ioreq_alloc(reqType : TIORequestType;
|
||||
device : PStorage_Device;
|
||||
lba : uint32;
|
||||
@@ -53,7 +127,7 @@ function ioreq_alloc(reqType : TIORequestType;
|
||||
var
|
||||
req : PIORequest;
|
||||
begin
|
||||
req := PIORequest(kalloc(SizeOf(TIORequest)));
|
||||
req := ioreq_take();
|
||||
if req = nil then begin
|
||||
ioreq_alloc := nil;
|
||||
exit;
|
||||
@@ -75,15 +149,14 @@ end;
|
||||
|
||||
procedure ioreq_free(req : PIORequest);
|
||||
begin
|
||||
if req <> nil then
|
||||
kfree(void(req));
|
||||
ioreq_release(req);
|
||||
end;
|
||||
|
||||
function ioreq_copy(src : PIORequest) : PIORequest;
|
||||
var
|
||||
dst : PIORequest;
|
||||
begin
|
||||
dst := PIORequest(kalloc(SizeOf(TIORequest)));
|
||||
dst := ioreq_take();
|
||||
if dst = nil then begin
|
||||
ioreq_copy := nil;
|
||||
exit;
|
||||
|
||||
Reference in new issue
Block a user