亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? myldbgetmem.inc

?? 一個(gè)本地database引擎,支持中文T_Sql查詢,兼容DELPHI標(biāo)準(zhǔn)數(shù)據(jù)庫控件
?? INC
?? 第 1 頁 / 共 3 頁
字號:
// Three layers:
// - Address space administration
// - Committed space administration
// - Suballocator
//
// Helper module: administrating block descriptors
//


//
// Operating system interface
//
const
  LMEM_FIXED = 0;
  LMEM_ZEROINIT = $40;

  MEM_COMMIT   = $1000;
  MEM_RESERVE  = $2000;
  MEM_DECOMMIT = $4000;
  MEM_RELEASE  = $8000;

  PAGE_NOACCESS  = 1;
  PAGE_READWRITE = 4;

type
  DWORD = Integer;
  BOOL  = LongBool;

  TRTLCriticalSection = packed record
    DebugInfo: Pointer;
    LockCount: Longint;
    RecursionCount: Longint;
    OwningThread: Integer;
    LockSemaphore: Integer;
    Reserved: DWORD;
  end;

function LocalAlloc(flags, size: Integer): Pointer; stdcall;
  external kernel name 'LocalAlloc';
function LocalFree(addr: Pointer): Pointer; stdcall;
  external kernel name 'LocalFree';

function VirtualAlloc(lpAddress: Pointer;
  dwSize, flAllocationType, flProtect: DWORD): Pointer; stdcall;
  external kernel name 'VirtualAlloc';
function VirtualFree(lpAddress: Pointer; dwSize, dwFreeType: DWORD): BOOL; stdcall;
  external kernel name 'VirtualFree';

procedure InitializeCriticalSection(var lpCriticalSection: TRTLCriticalSection); stdcall;
  external kernel name 'InitializeCriticalSection';
procedure EnterCriticalSection(var lpCriticalSection: TRTLCriticalSection); stdcall;
  external kernel name 'EnterCriticalSection';
procedure LeaveCriticalSection(var lpCriticalSection: TRTLCriticalSection); stdcall;
  external kernel name 'LeaveCriticalSection';
procedure DeleteCriticalSection(var lpCriticalSection: TRTLCriticalSection); stdcall;
  external kernel name 'DeleteCriticalSection';

// Common Data structure:

type
  TBlock = packed record
    addr: PChar;
    size: Integer;
  end;

// Heap error codes

const
  cHeapOk           = 0;          // everything's fine
  cReleaseErr       = 1;          // operating system returned an error when we released
  cDecommitErr      = 2;          // operating system returned an error when we decommited
  cBadCommittedList = 3;          // list of committed blocks looks bad
  cBadFiller1       = 4;          // filler block is bad
  cBadFiller2       = 5;          // filler block is bad
  cBadFiller3       = 6;          // filler block is bad
  cBadCurAlloc      = 7;          // current allocation zone is bad
  cCantInit         = 8;          // couldn't initialize
  cBadUsedBlock     = 9;          // used block looks bad
  cBadPrevBlock     = 10;         // prev block before a used block is bad
  cBadNextBlock     = 11;         // next block after a used block is bad
  cBadFreeList      = 12;         // free list is bad
  cBadFreeBlock     = 13;         // free block is bad
  cBadBalance       = 14;         // free list doesn't correspond to blocks marked free

var
  initialized   : Boolean;
  heapErrorCode : Integer;
  heapLock      : TRTLCriticalSection;

//
// Helper module: administrating block descriptors.
//
type
  PBlockDesc = ^TBlockDesc;
  TBlockDesc = packed record
    next: PBlockDesc;
    prev: PBlockDesc;
    addr: PChar;
    size: Integer;
  end;

type
  PBlockDescBlock = ^TBlockDescBlock;
  TBlockDescBlock = packed record
    next: PBlockDescBlock;
    data: array [0..99] of TBlockDesc;
  end;

var
  blockDescBlockList: PBlockDescBlock;
  blockDescFreeList : PBlockDesc;


function GetBlockDesc: PBlockDesc;
// Get a block descriptor.
// Will return nil for failure.
var
  bd:  PBlockDesc;
  bdb: PBlockDescBlock;
  i:   Integer;
begin
  if blockDescFreeList = nil then begin
    bdb := LocalAlloc(LMEM_FIXED, sizeof(bdb^));
    if bdb = nil then begin
      result := nil;
      exit;
    end;
    bdb.next := blockDescBlockList;
    blockDescBlockList := bdb;
    for i := low(bdb.data) to high(bdb.data) do begin
      bd := @bdb.data[i];
      bd.next := blockDescFreeList;
      blockDescFreeList := bd;
    end;
  end;
  bd := blockDescFreeList;
  blockDescFreeList := bd.next;
  result := bd;
end;


procedure MakeEmpty(bd: PBlockDesc);
begin
  bd.next := bd;
  bd.prev := bd;
end;


function AddBlockAfter(prev: PBlockDesc; const b: TBlock): Boolean;
var
  next, bd: PBlockDesc;
begin
  bd := GetBlockDesc;
  if bd = nil then
    result := False
  else begin
    bd.addr := b.addr;
    bd.size := b.size;

    next := prev.next;
    bd.next := next;
    bd.prev := prev;
    next.prev := bd;
    prev.next := bd;

    result := True;
  end;
end;


procedure DeleteBlock(bd: PBlockDesc);
var
  prev, next: PBlockDesc;
begin
  prev := bd.prev;
  next := bd.next;
  prev.next := next;
  next.prev := prev;
  bd.next := blockDescFreeList;
  blockDescFreeList := bd;
end;


function MergeBlockAfter(prev: PBlockDesc; const b: TBlock) : TBlock;
var
  bd, bdNext: PBlockDesc;
begin
  bd := prev.next;
  result := b;
  repeat
    bdNext := bd.next;
    if bd.addr + bd.size = result.addr then begin
      DeleteBlock(bd);
      result.addr := bd.addr;
      inc(result.size, bd.size);
    end else if result.addr + result.size = bd.addr then begin
      DeleteBlock(bd);
      inc(result.size, bd.size);
    end;
    bd := bdNext;
  until bd = prev;
  if not AddBlockAfter(prev, result) then
    result.addr := nil;
end;


function RemoveBlock(bd: PBlockDesc; const b: TBlock): Boolean;
var
  n: TBlock;
  start: PBlockDesc;
begin
  start := bd;
  repeat
    if (bd.addr <= b.addr) and (bd.addr + bd.size >= b.addr + b.size) then begin
      if bd.addr = b.addr then begin
        Inc(bd.addr, b.size);
        Dec(bd.size, b.size);
        if bd.size = 0 then
          DeleteBlock(bd);
      end else if bd.addr + bd.size = b.addr + b.size then
        Dec(bd.size, b.size)
      else begin
        n.addr := b.addr + b.size;
        n.size := bd.addr + bd.size - n.addr;
        bd.size := b.addr - bd.addr;
        if not AddBlockAfter(bd, n) then begin
          result := False;
          exit;
        end;
      end;
      result := True;
      exit;
    end;
    bd := bd.next;
  until bd = start;
  result := False;
end;



//
// Address space administration:
//

const
  cSpaceAlign = 64*1024;
  cSpaceMin   = 1024*1024;
  cPageAlign  = 4*1024;

var
  spaceRoot: TBlockDesc;


function GetSpace(minSize: Integer): TBlock;
// Get at least minSize bytes address space.
// Success: returns a block, possibly much bigger than requested.
// Will not fail - will raise an exception or terminate program.
begin
  if minSize < cSpaceMin then
    minSize := cSpaceMin
  else
    minSize := (minSize + (cSpaceAlign-1)) and not (cSpaceAlign-1);

  result.size := minSize;
  result.addr := VirtualAlloc(nil, minSize, MEM_RESERVE, PAGE_NOACCESS);
  if result.addr = nil then
    exit;

  if not AddBlockAfter(@spaceRoot, result) then begin
    VirtualFree(result.addr, 0, MEM_RELEASE);
    result.addr := nil;
    exit;
  end;
end;


function GetSpaceAt(addr: PChar; minSize: Integer): TBlock;
// Get at least minSize bytes address space at addr.
// Return values as above.
// Failure: returns block with addr = nil.
begin
  result.size := cSpaceMin;
  result.addr := VirtualAlloc(addr, cSpaceMin, MEM_RESERVE, PAGE_READWRITE);
  if result.addr = nil then begin
    minSize := (minSize + (cSpaceAlign-1)) and not (cSpaceAlign-1);
    result.size := minSize;
    result.addr := VirtualAlloc(addr, minSize, MEM_RESERVE, PAGE_READWRITE);
  end;
  if result.addr <> nil then begin
    if not AddBlockAfter(@spaceRoot, result) then begin
      VirtualFree(result.addr, 0, MEM_RELEASE);
      result.addr := nil;
    end;
  end;
end;


function FreeSpace(addr: Pointer; maxSize: Integer): TBlock;
// Free at most maxSize bytes of address space at addr.
// Returns the block that was actually freed.
var
  bd, bdNext: PBlockDesc;
  minAddr, maxAddr, startAddr, endAddr: PChar;
begin
  minAddr := PChar($FFFFFFFF);
  maxAddr := nil;
  startAddr := addr;
  endAddr   := startAddr + maxSize;
  bd := spaceRoot.next;
  while bd <> @spaceRoot do begin
    bdNext := bd.next;
    if (bd.addr >= startAddr) and (bd.addr + bd.size <= endAddr) then begin
      if minAddr > bd.addr then
        minAddr := bd.addr;
      if maxAddr < bd.addr + bd.size then
        maxAddr := bd.addr + bd.size;
      if not VirtualFree(bd.addr, 0, MEM_RELEASE) then
        heapErrorCode := cReleaseErr;
      DeleteBlock(bd);
    end;
    bd := bdNext;
  end;
  result.addr := nil;
  if maxAddr <> nil then begin
    result.addr := minAddr;
    result.size := maxAddr - minAddr;
  end;
end;


function Commit(addr: Pointer; minSize: Integer): TBlock;
// Commits memory.
// Returns the block that was actually committed.
// Will return a block with addr = nil on failure.
var
  bd: PBlockDesc;
  loAddr, hiAddr, startAddr, endAddr: PChar;
begin
  startAddr := PChar(Integer(addr) and not (cPageAlign-1));
  endAddr := PChar(((Integer(addr) + minSize) + (cPageAlign-1)) and not (cPageAlign-1));
  result.addr := startAddr;
  result.size := endAddr - startAddr;
  bd := spaceRoot.next;
  while bd <> @spaceRoot do begin
    // Commit the intersection of the block described by bd and [startAddr..endAddr)
    loAddr := bd.addr;
    hiAddr := loAddr + bd.size;
    if loAddr < startAddr then
      loAddr := startAddr;
    if hiAddr > endAddr then
      hiAddr := endAddr;
    if loAddr < hiAddr then begin
      if VirtualAlloc(loAddr, hiAddr - loAddr, MEM_COMMIT, PAGE_READWRITE) = nil then begin
        result.addr := nil;
        exit;
      end;
    end;
    bd := bd.next;
  end;
end;


function Decommit(addr: Pointer; maxSize: Integer): TBlock;
// Decommits address space.
// Returns the block that was actually decommitted.
var
  bd: PBlockDesc;
  loAddr, hiAddr, startAddr, endAddr: PChar;
begin
  startAddr := PChar((Integer(addr) + + (cPageAlign-1)) and not (cPageAlign-1));
  endAddr := PChar((Integer(addr) + maxSize) and not (cPageAlign-1));
  result.addr := startAddr;
  result.size := endAddr - startAddr;
  bd := spaceRoot.next;
  while bd <> @spaceRoot do begin
    // Decommit the intersection of the block described by bd and [startAddr..endAddr)
    loAddr := bd.addr;
    hiAddr := loAddr + bd.size;
    if loAddr < startAddr then
      loAddr := startAddr;
    if hiAddr > endAddr then
      hiAddr := endAddr;
    if loAddr < hiAddr then begin
      if not VirtualFree(loAddr, hiAddr - loAddr, MEM_DECOMMIT) then
        heapErrorCode := cDecommitErr;
    end;
    bd := bd.next;
  end;
end;


//
// Committed space administration
//
const
  cCommitAlign = 16*1024;

var
  decommittedRoot: TBlockDesc;


function GetCommitted(minSize: Integer): TBlock;
// Get a block of committed memory.
// Returns a committed memory block, possibly much bigger than requested.
// Will return a block with a nil addr on failure.
var
  bd: PBlockDesc;
begin
  minSize := (minSize + (cCommitAlign-1)) and not (cCommitAlign-1);
  repeat
    bd := decommittedRoot.next;
    while bd <> @decommittedRoot do begin
      if bd.size >= minSize then begin
        result := Commit(bd.addr, minSize);
        if result.addr = nil then
          exit;
        Inc(bd.addr, result.size);
        Dec(bd.size, result.size);
        if bd.size = 0 then
          DeleteBlock(bd);
        exit;
      end;
      bd := bd.next;
    end;
    result := GetSpace(minSize);
    if result.addr = nil then
      exit;
    if MergeBlockAfter(@decommittedRoot, result).addr = nil then begin
      FreeSpace(result.addr, result.size);
      result.addr := nil;
      exit;
    end;
  until False;
end;


function GetCommittedAt(addr: PChar; minSize: Integer): TBlock;
// Get at least minSize bytes committed space at addr.
// Success: returns a block, possibly much bigger than requested.
// Failure: returns a block with addr = nil.
var
  bd: PBlockDesc;
  b: TBlock;
begin
  minSize := (minSize + (cCommitAlign-1)) and not (cCommitAlign-1);
  repeat

    bd := decommittedRoot.next;
    while (bd <> @decommittedRoot) and (bd.addr <> addr) do
      bd := bd.next;

    if bd.addr = addr then begin
      if bd.size >= minSize then
        break;
      b := GetSpaceAt(bd.addr + bd.size, minSize - bd.size);
      if b.addr <> nil then begin
        if MergeBlockAfter(@decommittedRoot, b).addr <> nil then
          continue
        else begin
          FreeSpace(b.addr, b.size);
          result.addr := nil;
          exit;
        end;
      end;
    end;

    b := GetSpaceAt(addr, minSize);
    if b.addr = nil then
      break;

    if MergeBlockAfter(@decommittedRoot, b).addr = nil then begin
      FreeSpace(b.addr, b.size);
      result.addr := nil;
      exit;
    end;
  until false;

  if (bd.addr = addr) and (bd.size >= minSize) then begin
    result := Commit(bd.addr, minSize);
    if result.addr = nil then
      exit;
    Inc(bd.addr, result.size);
    Dec(bd.size, result.size);
    if bd.size = 0 then
      DeleteBlock(bd);
  end else
    result.addr := nil;
end;


function FreeCommitted(addr: PChar; maxSize: Integer): TBlock;
// Free at most maxSize bytes of address space at addr.
// Returns the block that was actually freed.
var
  startAddr, endAddr: PChar;
  b: TBlock;
begin
  startAddr := PChar(Integer(addr + (cCommitAlign-1)) and not (cCommitAlign-1));
  endAddr := PChar(Integer(addr + maxSize) and not (cCommitAlign-1));
  if endAddr > startAddr then begin
    result := Decommit(startAddr, endAddr - startAddr);
    b := MergeBlockAfter(@decommittedRoot, result);
    if b.addr <> nil then
      b := FreeSpace(b.addr, b.size);
    if b.addr <> nil then
      RemoveBlock(@decommittedRoot, b);
  end else
    result.addr := nil;
end;

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日本一区二区视频在线观看| 亚洲精品视频一区二区| 国产高清在线精品| 欧美一区午夜视频在线观看| 久久99国产精品麻豆| 久久精品亚洲乱码伦伦中文 | 亚洲成人手机在线| 欧美一级片在线观看| 精品一区二区三区香蕉蜜桃| 中文字幕乱码一区二区免费| 一本久道久久综合中文字幕| 亚洲成人一区在线| 欧美精品一区在线观看| 成人午夜精品在线| 中文字幕一区二区三区不卡在线| 在线观看国产日韩| 奇米影视在线99精品| 国产亚洲va综合人人澡精品| 成人高清视频免费观看| 亚洲丝袜制服诱惑| 欧美三级日韩在线| 韩日av一区二区| 成人欧美一区二区三区1314| 欧美日韩一区三区| 国产精品资源在线看| 亚洲三级电影全部在线观看高清| 欧美日韩成人综合| 国产乱淫av一区二区三区| 亚洲视频免费观看| 欧美一区二区播放| 成人黄色a**站在线观看| 亚洲二区在线视频| 国产偷v国产偷v亚洲高清| 欧美午夜精品久久久久久孕妇| 美女视频网站久久| 亚洲欧美区自拍先锋| 欧美一区2区视频在线观看| 成人国产精品免费网站| 亚洲高清一区二区三区| 久久这里只有精品6| 欧美在线不卡视频| 国模少妇一区二区三区| 亚洲最新在线观看| 2024国产精品| 欧美亚洲国产一卡| 国产精品18久久久久| 亚洲国产日韩一级| 国产精品美女久久久久久久| 欧美一级日韩一级| 91视频国产观看| 国内精品久久久久影院一蜜桃| 亚洲一区二区三区四区在线 | 精品久久久影院| 色噜噜狠狠色综合中国| 国产在线一区观看| 亚洲一区二区3| 欧美国产在线观看| 日韩视频不卡中文| 日本韩国精品一区二区在线观看| 久久99国产乱子伦精品免费| 一区二区三区影院| 国产无人区一区二区三区| 欧美一区二区三区视频免费播放| 99久久婷婷国产综合精品电影 | 91在线免费看| 久久99国产精品免费| 亚洲一区二区影院| 国产精品对白交换视频| 2020国产精品久久精品美国| 欧美视频中文字幕| aaa欧美大片| 国产一区二区三区免费在线观看 | 国产精品一区二区在线观看不卡| 香蕉av福利精品导航| 国产精品久久久久久亚洲毛片 | 亚洲最大色网站| 中文字幕在线观看一区二区| 亚洲精品一区二区三区精华液| 欧美亚洲日本国产| 色天天综合久久久久综合片| 国产乱码精品1区2区3区| 日本中文字幕一区| 亚洲电影一区二区三区| 亚洲人成在线观看一区二区| 国产日本亚洲高清| 精品精品国产高清一毛片一天堂| 欧美日本一区二区三区四区| 在线亚洲高清视频| 一本色道a无线码一区v| av亚洲精华国产精华| 国产成人午夜片在线观看高清观看| 男男成人高潮片免费网站| 精品国产髙清在线看国产毛片| 亚洲日本va在线观看| 国产白丝精品91爽爽久久| 欧美视频一区二区在线观看| 中文字幕一区二区三| 经典三级一区二区| 91精品国产高清一区二区三区蜜臀| 亚洲免费在线电影| av在线不卡观看免费观看| 亚洲三级在线观看| 精品一区二区三区视频在线观看| 国产婷婷色一区二区三区在线| 欧美一区二区三区免费视频 | 欧美日韩亚洲综合一区| 91麻豆免费看| 99久久99久久免费精品蜜臀| 成人视屏免费看| 国产99一区视频免费| 国产剧情一区二区三区| 国产成人av资源| 成人免费观看男女羞羞视频| 成人av午夜影院| 91在线观看高清| 99国产精品久久久久久久久久久| 99精品偷自拍| 在线看国产一区二区| 欧美午夜电影网| 欧美人妖巨大在线| 91精品国产色综合久久不卡电影| 91精品久久久久久久91蜜桃| 欧美一区二区三区免费大片| 精品成人一区二区三区四区| 久久亚洲春色中文字幕久久久| 国产亚洲欧美中文| 国产精品大尺度| 亚洲精品日韩一| 亚洲成人一区二区在线观看| 免费成人av在线| 精品一区二区久久| 国产成人精品1024| 91同城在线观看| 欧美亚洲综合另类| 51精品秘密在线观看| 精品国产伦一区二区三区免费| 久久精品亚洲精品国产欧美| 国产精品美女www爽爽爽| 亚洲免费视频成人| 日韩电影在线观看电影| 寂寞少妇一区二区三区| 成人污视频在线观看| 日本韩国欧美在线| 欧美一区二区美女| 欧美激情综合五月色丁香小说| 亚洲欧美一区二区久久| 日韩电影在线观看电影| 国产成人精品www牛牛影视| 97久久超碰国产精品| 欧美老女人在线| 久久综合九色综合久久久精品综合| 中文字幕乱码一区二区免费| 亚洲永久免费视频| 精品一区二区三区视频在线观看| thepron国产精品| 在线成人av网站| 国产色产综合产在线视频| 亚洲综合激情网| 久久99精品网久久| 91在线视频网址| 91精品国产综合久久婷婷香蕉 | 亚洲精品视频一区| 日本aⅴ精品一区二区三区| 成人黄色免费短视频| 欧美嫩在线观看| 国产精品美女久久久久高潮| 丝袜美腿高跟呻吟高潮一区| 国产精品亚洲午夜一区二区三区| 色狠狠av一区二区三区| 精品成人免费观看| 一二三区精品视频| 国模娜娜一区二区三区| 欧洲精品中文字幕| 26uuu久久综合| 亚洲综合久久av| 成人中文字幕合集| 精品一区二区三区av| 国产一区二区毛片| 成人毛片老司机大片| 亚洲精品一区二区三区蜜桃下载| 日韩精品一区二区在线观看| 日韩一级片在线观看| 日韩一区二区三区在线视频| 欧美精品v国产精品v日韩精品| 欧美人狂配大交3d怪物一区| 欧美精品粉嫩高潮一区二区| 欧美日韩国产经典色站一区二区三区| 在线观看欧美精品| 欧美日韩精品综合在线| 日韩欧美国产三级| 亚洲婷婷综合久久一本伊一区| 久久99精品国产.久久久久久| 91亚洲精华国产精华精华液| 日韩视频免费观看高清完整版在线观看 | 亚洲丝袜精品丝袜在线| 久久国产福利国产秒拍| 在线一区二区三区| 国产精品免费丝袜| 国产一区二区三区黄视频 | 久久久噜噜噜久久人人看|