第二十章 內存等空間管理類的實現

                   第二十章   內存等空間管理類的實現

     空間、時間對我來說,或許永遠是一個迷。即使我曾經深入到原子的最深處,即使人類科學家是自欺欺人,即使我瞭解到的最深層次的部分真理是正確的;那又能怎樣?那都是過去式,在那光明與黑暗一體之地、我的靈魂受傷了;我不得不回到電腦這塊充滿垃圾的地方修心養性。

    或許我的論述方法不好,要完全理解本章是有點難度;你要對簡單的空間概念需要一定的理解,即使只是論述1D的線性平面空間中的2個基本方法:分配與釋放,但也很複雜。要知道LINUX單是內存管理源代碼就3萬6千行,文件系統的54萬多行中磁盤空間管理佔多少?網絡的約38行中的網絡連接管理佔多少?將近500萬行的驅動和架構、內核中用於空間管理的佔多少?我不清楚,猜想LINUX中用於空間管理的爲100萬行吧;這還沒有包含數據庫的管理。爲此,本章的論述可能會重複再重複,囉嗦再囉嗦;沒辦法、這將是一場艱辛的戰鬥!即使前面已經有了基礎、規劃,即使是連戰七天七夜、也不在乎,我會盡最大努力的。APO的用於空間管理的只是160行源代碼,這比原先計劃是600行的要少了很多,意料之外啊。其實,越複雜的事情都是很簡單的實現!我真的不清楚那些複雜腦袋的產物爲何如此龐大?學院派的大神們,該臉紅了;不要像老鼠上天平:自嘆自稱,夠重啊!

     如果我們用一個二進制位來表示一個資源單位;資源單位可能是一段連續行、或一段連續數據塊、或文件中的一條記錄、或一個socket文件號、或一個進程號、或一個進程中的一個線程號、或一段連續單元、或一個內存v節點、或進程中的一個打開的文件描述符、或數據庫線性表中的一個字段、或進程中的一個類號、或進程中的一個對象號、或一個消息號、或一個過程號等等。這樣,對應於小模式,需要64K個位來表示;也即BU64K A;  64K位的位圖變量A就對應一個小模式,小模式使用連續的256行作爲64K位的位圖變量。而中模式是使用一個64K位的位圖變量數據塊,該塊有256個64K位的位圖變量;可以管理16M個單位。而大模式則需要64K個64K位的位圖變量來描述。一個64K位的位圖變量只是佔存儲空間256E,並不多;但大模式需要佔存儲空間256個數據塊,就比較多了。爲減少空間的浪費;對於大模式,我們通常是動態生成的。最初只是分配一個位圖變量數據塊(中模式),如果還不能滿足時,再申請分配一個位圖變量數據塊。。。最終會生成有n個(n <= 256)位圖變量數據塊。只要我們編寫了大、中、小模式的分配、釋放方法放於系統方法表內;那麼,所有的程序類都將受益;無須重複的代碼。增加、刪除數據庫表中的一條記錄,或目錄下的一個文件,或磁盤空間中的一段連續數據塊,或數據庫下的一個表文件,或內存空間中的一個v節點,或本地內存中的一段連續行、或一個TCP連接等等;都是調用大、中模式下的分配、釋放方法。增加、刪除數據庫表中的一個字段,或一個進程中的一個對象號或類號或線程號或過程號或消息號或打開的文件號,或磁盤空間中的一段連續單元,或一個進程,或本地內存中的一段連續數據塊等等;都是調用小模式下的分配、釋放方法。APO中的位圖是位爲1,表示空閒;位爲0表示佔用。增加、刪除只是對位圖變量的操作,而不是對對象的具體內容進行。比如,刪除一個文件;只是對代表文件所佔磁盤空間的位圖變量中的一些位做釋放;如果,這些空間沒有被其它文件佔用;那麼空間還是原來文件的內容。

    連續幾天都不在狀態,似乎神賦予的能力都沒了,受到了封印;思感退化到小學生的天真、混沌時代。我不斷的努力掙脫,日夜奮戰;試圖將許多零碎的、閃光的思想片段,拼接成一個美麗的圖案。修改n遍了,還是沒法滿意,只好暫時先這樣;以後,再不斷修改完善;沒關係的,我窮得只剩下時間了。

一、多功能硬件模塊介紹

     這是集成在32位用戶CPU核內的多功能輔助性的64K位硬件模塊,功能非常強大!硬件模塊YJMK有3個32位的參數與控制寄存器B2、B3、B4,和256E的高速內存YJMK,執行指令是SS1。 SS1指令啓動後,需約6-10ns完成;期間用戶CPU空轉,直到SS1完成;CPU才能執行下一條指令。

BU256E  YJMK; // 64K位的硬件模塊YJMK變量,分爲256行,每行256位。
B2H: 高8位指令屬性,低8位指令碼。最高位爲SS1啓動位;完成時,B2H.15 = 0。
B2L: 低16位是你要COPY進去的位圖行數 (也就是你的位圖大小)。

B2H.7-0 低8位指令碼:

0x00  allot(分配指令),

0x01  release(釋放指令)= Set(位置1),

0x02  clr(位清0),

0x03  BIX(位查詢指令),

0x04  CMP(比較指令),

0x05  compress(壓縮指令),

0x06  insert(插入指令),

0x07  replace(替換指令),

0x08—0xff   保留爲將來的擴充指令。

 

B2H.14-8  七位指令屬性,爲一些指令的功能屬性。比如:

CMP(比較指令)的屬性:最多隻是比較256行中的值;位圖內容不變。

B2H.11-8   4位CMP屬性: B2H.11,  1、字比較,0、字符比較,其它3位B2H.10-8:

000: 最小值、   001:最大值

010: 等於       011: 不等於

100:小於、      101:大於

110:小於等於、  111:大於等於

如、比較B3的字與1-256行中字第一個相等的位置:B2H.11-8、1010。

如、比較B3H的字符與1-256行中字符第一個相等的位置:B2H.11-8、0010。

如、比較1-256行中字符小於B3H的字符第一個的位置:B2H.11-8、0100。

如果要求出所有的位置、那隻能是比較128行,另128E放位置結果。

如、比較B3H的字符與1-127行中字符相等的位置:B2H.14-8、1000010。結果都在128E-255E裏面,B4L爲符合條件的位置序號數。

B3:  32位是你需要與n行中的32位值比較的數值。n <= 256

B3H: 16位是你需要與n行中的16位值比較的數值。

B4L: 返回結果:是第一個符合條件的字或字符開始地址;B4H不變,可作記錄號高半字。如果已經比較完、並失敗; PSR.YJ = 0;B2H.15 = 0。

PSR.YJ是狀態寄存器中的硬件模塊成功標誌。

B2H.15爲SS1啓動位;完成時,B2H.15 = 0。B2H.14爲256E的高速內存YJMK分塊標誌位,1、分爲2個128E的內存,0、不分塊。一些指令是需要分塊的,如BIX(位查詢指令)、和快速CMP(比較指令)等。硬件模塊的256E,可以分成2部分:輸入128E,輸出128E;如果輸入128E中符合條件的結果全部給出在輸出,那麼標誌PSR.IN置位,請求再輸入128E;如果輸出128E中的結果滿,那麼標誌PSR.OUT置位,請求讀出結果。

對於BIX(位查詢指令):我們可以將32K的位圖放到輸入128E,這樣,執行BIX1就可以找出位圖中從低位到高位的所有爲1的序號值、順序放在輸出128E中。如果爲1的序號值不止128E/16 = 2K個,那麼標誌PSR.OUT置位,請求讀出結果。讀了2K個後,我們可以再SS1啓動、再來。。。。類似的,BIX0就是位0查詢指令了。

對於快速CMP(比較指令):在數據庫查詢非常高效;如果一個字段是映射到字符或字數值,需要做數值條件查詢。那麼,我們可以一次拷貝128E = 1KW = 2KZ的數據段到硬件模塊輸入128E來進行比較,結果序號都在輸出128E中。如果平均一個128E數據段可查詢到n條(n < 1k)符合條件的記錄;那麼,在內存中的數據庫表查找速度對字方式約是:1K/0.1us = 10G條記錄/秒,對字符方式約是:20G條記錄/秒;即約爲200億條記錄/秒。

CIR指令:compress(壓縮),insert(插入), replace(替換)。

壓縮:可對1-256E中的指定字符或字進行清除,並壓縮存放。

插入:可對1-256E中的指定字符或字位置插入一個字符或字。

替換:可對1-256E中的指定字符或字進行替換,或指定位置的字符或字進行替換。

與位操作相關指令:

B3H: 高16位是你的申請或釋放的連續1位數。

B3L: 低16位是申請的連續1位數的返回結果開始位地址,或釋放的連續1位數的開始位地址。

B4:  返回結果:是位圖的最大連續1位數及開始位所屬的行號。
   
allot(分配指令):搜索位圖滿足B3H個連續1位數的開始位地址到B3L;成功PSR.YJ = 1、還將B3H個連續1位數的1全部取反(變爲0,表示佔用)。等同搜索成功後,執行爲部分清0的clr指令。已經搜索完位圖、失敗,位圖內容不變,
PSR.YJ = 0;B2H.15 = 0。

release(釋放指令):將你請求釋放的連續位數的開始位地址起的B3H個連續位0全部置爲1,釋放定成功;等同部分位置1的Set指令。 返回結果 B4是位圖的最大連續1位數及開始位所屬的行號。

二、位圖空間

      簡單說空間就是指裝東西的容器,在電腦界、只是裝二進制位的容器,簡稱位容器。標準的位容器有:字節B是8位、16位是字符Z、32位是字W、256位是行E。程序裏的一切都是位容器,對象、變量、指令碼、等等都是描述位容器、或如何操作位容器。連續64K個位的位容器,我們稱爲位圖變量。256個不一定連續的位圖變量組成的容器,我們稱爲中模式位圖空間;類似的,256箇中模式空間組成的容器,我們稱爲大模式位圖空間。

     世界上大大小小的容器多如牛毛,大到無法述說的天地、小到光子;我們是需要指明一個基本空間作爲參考物、比如地球,才能分辨或比較事物的層次、大小。不說是一顆微塵,就算一個原子,裏面所含的光子數也遠超過地球上的生物數量。一花一世界,人類對事物的認知可以說還在表面。即使是電腦界的位容器,也是眼花繚亂、不可勝數。我們必須抽象出簡單的描述位容器的規律,這是一件非常耗神的事情。

 

     一個平面線性4G單位的空間A,可以分割成64K個有64K個單位的子空間;這時,如果將不一定是連續的256個子空間組成中模式空間,那麼、我們也可以將空間A看作是由一部分子空間和一部分中模式空間的混合組成。如果我們將一個平面線性4G單位空間映射到一個4G位圖空間,一個二進制位對應一個單位;那麼,我們就可以使用位圖來描述線性4G單位空間的大、中、小模式。對於大模式的4G個位的空間,我們可以使用256個64K位的位圖爲單位(16M位)來分割;這樣,大模式空間就分解爲256箇中模式空間;而每個中模式空間又分解爲256個小模式空間(64K個位的位圖變量空間)。這樣一來,對大模式的管理最終會變成爲小模式的管理、速度就能加快。

 

     不管大、中、小模式空間,我們都需要一個基本空間;所有的空間都必須是以基本空間爲根本。在APO中,本地內存基本空間是一個單元、劃分成64K個子空間(數據塊);所有的:進程號空間、內存v節點空間、等等,都是建立在本地內存基本空間上面。其它,如進程的文件號空間、數據庫文件內的記錄號空間、等等,也都是建立在磁盤基本空間上面;磁盤基本空間是一個卷、劃分成64K個子空間(單元)。大、中、小模式空間只是從管理的角度來對空間進行的抽象劃分模式;當各種各樣、大大小小的空間交織在一起時,會顯得混亂與複雜。所有的空間,包括磁盤空間最終都要在本地內存空間中進行管理。不管怎樣,空間都是要映射到位圖空間來管理;這時,我們就只是簡單考慮空間的尺度單位了。

     雖然一個位圖變量是對應一個子空間,但中模式空間中的256個位圖變量,可以對應到64K個子空間中的任意不一定連續的256個子空間;因爲中模式空間的位圖變量可以是動態生成的。

太多的空間管理了,我們必須對基本空間作出一些管理規定:

1)、基本空間劃分成64K個子空間,一個子空間有64K個連續單位。

2)、基本空間管理:連續子空間的分配、釋放(小模式管理),基本空間內的連續單位的分配、釋放(大模式管理)。

     基本空間的位號是32位:高16位是位圖變量序號,低16位是子空間下的位序號。基本空間的位圖變量與子空間是一一對應的,位圖變量序號就是子空間序號;這點是和非基本空間不一樣的!

APO中通常是有2類的基本空間:(基本空間的位圖變量數據塊都是在一開始就按實際分配內存。)

1)、本地內存基本空間:單位行E,子空間是一個數據塊64KE= 2MB,
基本空間管理:連續數據塊的分配、釋放,數據塊內的連續行的分配、釋放。

2)、磁盤基本空間:單位一個數據塊64KE,子空間是一個單元64K個數據塊 = 128GB,基本空間管理:連續單元的分配、釋放,單元內的連續數據塊的分配、釋放。

三、 1位的模式空間管理

    如數據庫文件的記錄號,每次只是分配、或釋放一個位。不管大、中、小模式空間,只要是每次只能是分配、或釋放一個位的;都是使用到1位的模式空間管理。主要是應用於xx號的分配、或釋放。
 
1、 1位的大模式空間管理:

LMODE1{        // 1位的大模式空間管理參數 72KE + 305E + 1W

  BU1W [256] BMPDBP;// 中模式空間的管理位圖數據塊指針數組。

  BU1Z [256] FBMPVN;// 中模式空間空閒的位圖變量數的數組。

  BU1E       LFNZB;//256箇中模式空間有空閒位1的位行。

  BU289E [256] BMPVP1{ // 1位的中模式空間管理參數的數組

   BU1W [256] SSPN;// 位圖變量對應的基本空間位號數組,未分配0、禁止1。

   BU1E [256]FNZB;// 位圖變量256行的每一行所對應的非0位的數組

   BU1E   IFNZB; // 256個位圖變量有空閒位1的位行。

  }

  BU1Z LACTN;    // 中模式空間的實際數。

  BU1Z UNITLEN;  // 位圖變量一個位的長度。

}

 

   BMPDBP中模式空間的管理位圖數據塊指針,必須一開始就安裝好。FBMPVN中模式空間空閒的位圖變量數的數組,SSPN位圖變量對應的基本空間位號數組、未分配0、禁止1,LACTN中模式空間的實際數,UNITLEN位圖變量一個位的長度;這些參數,應用於大模式空間的動態生成。

 

1位大模式分配、釋放方法lmanage1()。    

入口:

分配時:R0-R2 = ( 0.allot.0.1, 1.0,LMODE1 ),

釋放時:R0-R2 = ( 0.release.0.1, 1.位圖變量的位序號, LMODE1 ),

R31H 爲位圖變量序號(高8位中模式空間序號、低8位相應的位圖變量序號)。

出口:

R31H、爲位圖變量序號,R31L爲位圖變量的1位開始位序號,

R0H爲0、成功,失敗則R0H = -1。

佔用:28W, R30-R31。

耗時:分配、96ns/97ns,釋放、48ns,出錯、9ns/33ns/67ns。

lmanage1(){ // 大模式1位的分配、釋放方法。

  B2 = R0;  R0 = R1 AND 0X00ff; // 初始化硬件模塊。

  B3 = R0;// 只是對YJMK的第0行進行SS1。

  R3 = R2.LFNZB; // R3指向LMODE1.LFNZB。

  if  R1L != 0  goto  free1; // 如果是釋放,跳。

  BT0  (R3).E, mal3;// LMODE1.LFNZB爲0、跳,無空閒位失敗返回。

  YJMK.E = R3.E; // 拷貝LFNZB,分配1位。

  SS1;  // B3L爲LFNZB的第一個爲1的位序號(中模式空間的序號)

  R30H = B3L; // 保存中模式空間的序號到R30H。

mal1:

  R4 = R2.R30H.W;// R4爲相應的中模式空間的管理位圖數據塊指針。

  R2 = +49;  // R2指向中模式空間參數區LMODE1.BMPVP1

  R2 = + R30H*289;// R2指向相應的中模式參數區BMPVP1。

  call imana1; // 調用中模式空間1位分配、釋放方法。

  if RH = -1 goto failret;

  R30H = >>8; R3.R30H = 0;

  BT0 (R2.IFNZB).E, mal2;// 相應中模式空間無空閒位,相應位清0。

  R3.R30H = 1; // 否則置1。

mal2:

  R0H = 0;  RET  // 成功、返回。

mal3:

  R0H = -1; RET // 出錯、返回。

free1:

  R30H = R31H; R30H = >>8; //R30H中模式空間的序號。

  R3.R30H = 1; // 釋放相應中模式空間相應位。

  JMP  mal1;

}

 

2、 1位的中模式管理

IMODE1{           // 289E + 5Z。

  BU1W  BMPDBP;   // 中模式空間的管理位圖數據塊指針(SMBMP)。

  BU1Z  FBMPVN;   // 中模式空間空閒的位圖變量數。

  BU1Z ACTN;     // 中模式空間中,位圖變量的實際數。

  BU1Z BITLEN;   // 位圖變量一個位的長度。

  BMPVP1{         // 中模式的256個位圖變量參數 289E

   BU1W [256] SSPN;// 位圖變量對應的基本空間位號數組,未分配0、禁止1。

   BU1E [256]FNZB;// 位圖變量256行的每一行所對應的非0位的數組

   BU256IFNZB;    // 256個位圖變量有空閒位1的數組。

   }

}

 

中模式位圖空間的1位分配、釋放管理方法:imanage1()       

入口:

分配:R0 = 0.allot.0.1,

釋放:R0 = 0.release.0.1,

R1H: 爲分配或釋放的連續位數,1

R1L: 分配時、爲0,釋放時是位圖變量的位序號,

R2 = BMPVP1, R4 = BMPDBP,

釋放時:R31H低8位爲位圖變量序號

出口:

R31H、爲位圖變量序號,R31L爲連續位數的開始位序號,

R0H爲0、成功,失敗則R0H = -1。

佔用:23W, R30-R31。

耗時:分配、68ns/69ns,釋放、30ns,出錯:9ns、43ns。

imanage1(){ // 中模式的1位分配、釋放管理方法。

  B2 = R0;  R0 = R1 AND 0X00ff; // 初始化硬件模塊。

  B3 = R0;// 只是對YJMK的第0行進行SS1。

imana1:

  R3 = R2.IFNZB; // R3指向IMODE1.IFNZB。

  if R1L != 0  goto  ifree1; // 如果是釋放,跳。

  BT0  (R3).E, mal3;// 失敗返回、IFNZB爲0、無空閒位。

  YJMK.E = R3.E; // 拷貝IFNZB

  SS1;  // B3L 爲 IFNZB的第一個爲1的位序號(位圖變量序號)

  R30L = B3L;  // 保存位圖變量序號R30L。

  R31H = R30L + R30H<<8; // 保存位圖變量序號R31H。

  call  ifl1;

  BT0  PSR.YJ, mal3; // 失敗、返回。

  R3.R30L = 0;

  BT0 (R2.FNZB.R30L).E, mal2;// 如果該行的最大連續位是0,跳返回。

  R3.R30L = 1; // 分配1位後,還有空閒、相應位置1。

  JMP mal2;

ifree1:

  R30L = R31H AND 0X00FF;  R3.R30L =1;

ifl1:

  R31L = R30L;

  R3 = R2.FNZB.R30L; //R3指向相應FNZB。

  R2 = R4 + R31L<<8; // R2指向位圖變量序號的相應位圖變量。

  JMP  mana1;// 跳位圖變量的1位分配、或釋放。

}

3、 1位的小模式管理

SMODE1{           // 257E + 1W。

  BU256E SMBMP; // 小模式空間的管理位圖變量。

  BU256   FNZB; // 256行的每一行所對應的非0位,未使用的行爲0。

  BU1Z    ACTRN; // 位圖變量的實際行數。

  BU1Z    BITLEN;// 位圖變量一個位的對應的長度E。

}

      位圖變量的實際行數,決定了位圖變量的實際大小,未使用的行爲0。比如,本地內存空間實際只有32GB,而位圖變量是按照128GB設計的;實際的位圖變量只有32GB/512MB = 64行,後面的64-255行都是未使用的、行爲0(初始化時設置);數據塊分配、釋放只會在前面的64行進行。1位與連續多位的分配、釋放速度是大不一樣的,所以、會有2種不同的編程方式。

64K位的位圖變量的1位分配、釋放管理方法:manage1()       

入口:

R0命令碼: 1位、0.allot/release.0.1。

R1H: 爲分配或釋放的連續位數,1

R1L: 分配時、爲0,釋放時是位圖變量的位序號,

R2: 64K位的位圖變量指針SMBMP,

R3:指向FNZB。

出口:

釋放:返回修改後的位圖,

分配成功:R31L爲1位的開始位序號,

分配失敗:不修改位圖、PSR.YJ = 0。

佔用:25W,

耗時:釋放21ns,分配40ns、41ns,分配出錯:18ns。

manage1(){// 64K位的位圖變量的1位分配、釋放管理方法。

  B2 = R0;  R0 = R1 AND 0X00ff; // 初始化硬件模塊。

  B3 = R0;// 只是對第0行進行SS1。

mana1:

  if  R1L = 0  goto  allot; // 如果是分配,跳。

  R1L = R1L>>8;R3.R1L = 1;// FNZB的相應位釋放爲1。

  R2 = +R1L;   // 只拷貝相對應的一行

all1:

  YJMK.E = R2.E; // 賦值R2指針指向的一行。

  SS1;           // 分配、或釋放序號對應的1位。

  R2.E = YJMK.E; // 回傳

  RET

allot:  // 先拷貝FNZB,找到空閒的位行;失敗,報錯。

  YJMK.E = R3.E; // 拷貝FNZB。

  SS1;      // B3L 爲FNZB的第一個爲1的位序號(位圖行號)

  BT0  PSR.YJ, failret;// 失敗返回、FNZB爲0、無空閒位。

  R0H = B3L; // R0H爲位圖行號。

  R2 = +R0H; // 在有空閒位的行中分配1位。

  CALL  all1;// 分配1位。

  R3.R0H = 0;

  if B4H = 0 goto  all2; // 如果該行的最大連續位是0,跳。

  R3.R0H = 1; // 分配1位後,還有空閒、FNZB相應位置1。

all2:

  R31L = B3L; R31L = + R0H<<8; // 分配的位序號。

failret:

  RET

}

 

四、連續n位的模式空間管理

 

    如基本空間等,都需要使用到連續n位的分配、或釋放。

1、 大模式空間的連續位管理

LMODE{              // 大模式空間管理參數 12KE + 64E + 1W

  BU1W [256] BMPDBP;// 中模式空間管理位圖數據塊指針數組。

  BU1Z [256] FBMPVN;// 中模式空間空閒的位圖變量數的數組。

  BU1Z [256] MMAXCB1;// 中模式空間最大連續位1數值之最大值數組

  BU48E [256] BMPVP{ // 中模式空間管理參數的數組

   BU1W [256] SSPN;// 位圖變量對應的基本空間位號數組,未分配0、禁止1。

   BU1Z [256]MAXCB1;// 位圖變量最大連續位1數值的數組。

  }

  BU1Z LACTN;    // 中模式空間的實際數。

  BU1Z UNITLEN;  // 位圖變量一個位的長度。

}

 

    中模式空間的256個位圖變量中,可能有些位圖變量還沒使用;未使用的位圖變量,其對應的最大連續爲1的16位最大值爲0;但位圖變量的所有位都初始化爲1。16位中模式空間空閒的位圖變量數,最多爲256。沒有使用到的中模式空間,其管理位圖數據塊指針爲0;其對應的位圖變量最大連續爲1的數值之最大值數爲0;其對應的空閒的位圖變量數爲:0x0100、256個。

大模式連續位管理方法:lmanage()    

入口:

分配:R0-R2 = ( 7.CMP.0.16, 申請的連續1位數.0, LMODE ),

釋放:R0-R2 = ( 0.release.1.0, 釋放的連續1位數.位圖變量的位序號, LMODE ),
釋放時:R31H 爲位圖變量序號。

出口:

R31H、爲位圖變量序號,R31L爲連續位數的開始位序號,

R0H爲0、成功,失敗則R0H = -1。

佔用:21W, R29-R31。

耗時:釋放345ns,分配398ns,分配出錯:230ns、76ns、35ns

lmanage(){ //大模式連續位的分配、釋放方法。

   B2 = R0;  B3 = R1; // 初始化硬件模塊。

   R4 = R2;  R2 = + 48;// R2指向LMODE.MMAXCB1

   if  R1L != 0  goto  free; // 如果是釋放,跳。

   kxcmp();// R30L符合條件的字符開始序號(中模式空間的序號)。

   BT0  PSR.YJ, mal3;// 失敗跳、返回。

mall1:

   R29L = R30L;

   R3 = R2; // 保存R3指向LMODE.MMAXCB1

   R4 = R4.R30L.W;// R4爲相應的中模式空間的管理位圖數據塊指針。

   R2 = +16;   // R2中模式空間參數區LMODE.BMPVP

   R2 = + R30L*48;// R2中模式空間參數區LMODE.BMPVP.序號

   call imanag; // 中模式連續位管理方法。

   if RH = -1 goto failret;

   R3.R29L.Z = R30H; // 保存最大連續位1數值之最大值。

   RET

free:

   R30L = R31H; R30L = >>8; // R30L中模式空間的序號。

   JMP  mall1;

}


2、中模式連續位管理

     有16M個單位、則是中模式空間,比如內存v節點管理(也是網絡TCP連接管理)就是一箇中模式管理。大模式管理也是分解成小於256個的中模式空間管理來進行的。
我們不要求中模式空間的256個子空間之間是連續的,但子空間的64K個單位的位圖變量必須是連續的。所以,需要256個位圖變量的序號;每個子空間對應一個64K位的位圖變量,那麼,位圖變量存在一個最大連續位1數值參數。爲了節省空間,中模式空間的256個子空間,並非是全部使用的,有一個動態增長的過程;需要一個空閒的位圖變量數的參數。我們也需要一個管理中模式空間的256個64K位的位圖變量的位圖數據塊指針。

    中模式空間通常是從大模式空間中產生的。比如本地內存空間劃分爲64K個數據塊(子空間);中模式空間內存v節點的單位是4E,一個位圖變量是表示64K*4E = 4個連續數據塊;所以,我們需要4個連續數據塊的一個開始數據塊序號(16位數據塊號、16位起始行號(0)),來對應一個位圖變量。又比如:一個記錄型文件,假設文件空間是一箇中模式空間、單位是8KE,那麼文件空間內的一個位圖變量子空間是連續8K個數據塊;同樣,我們需要一個開始數據塊序號(16位單元號、16位數據塊號)。不管是什麼空間,最終都是在其所屬的基本空間安家、其位圖變量映射的子空間必須與基本空間的子空間號和子空間下的單位號掛鉤。

 

IMODE{            // 48E + 5Z。

  BU1W  BMPDBP;   // 中模式空間的管理位圖數據塊指針(SMBMP)。

  BU1Z  FBMPVN;  // 中模式空間空閒的位圖變量數。

  BU1Z ACTN;     // 中模式空間中,位圖變量的實際數。

  BU1Z UNITLEN;  // 位圖變量一個單位的長度。

  BMPVP{          // 中模式的256個位圖變量參數 272E

   BU1W [256] SSPN;// 位圖變量對應的基本空間位號數組,未分配0、禁止1。

   BU1Z [256]MAXCB1;// 位圖變量最大連續位1數值的數組。

  }

}


中模式位圖空間的連續位分配、釋放管理方法:vmanage()       

入口:

分配:R0 = 命令碼:7.CMP.0.16,

釋放:R0 = 0.release.1.0, 

R1H: 爲分配或釋放的連續位數,

R1L: 分配時、爲0,釋放時是位圖變量的位序號,

R2 = BMPVP, R4 = BMPDBP,

釋放時:R31H爲位圖變量序號

出口:

R31H、爲位圖變量序號,R31L爲連續位數的開始位序號,

R30H爲256個位圖變量最大值數組中的最大值,

R0H爲0、成功,失敗則R0H = -1。

佔用:24W, R30-R31。

耗時:釋放326ns,分配357ns,分配出錯:190ns、35ns

imanage(){ // 中模式的連續位分配、釋放管理方法。

   B2 = R0;  B3 = R1; // 初始化硬件模塊。

imanag:

   R30H = R30L; R2 = +32; // R2指向BMPVP.MAXCB1。

   if R1L != 0  goto  ifree; // 如果是釋放,跳。

   kxcmp();// 返回R30L爲第一個大於等於R1H的字符序號(位圖變量序號)

   BT0 PSR.YJ, mal3; // 失敗跳。

   R31H = R30L + R30H<<8; // 保存位圖變量序號到R31H。

   R0 = 0.allot.1.0;

val1:

   R3 = R2; // 保存R3 = BMPVP.MAXCB1。

   R30H = R30L;

   R2 = R4 + R30H<<8;// R2指向位圖變量序號的相應位圖變量。

   manage(); // 分配、拷貝相應位圖變量的256行。

   BT0  PSR.YJ, mal3; // 失敗返回。

   R3.R30L.Z = R0H; // 保存最大連續位1數值到相應位置。

   R2 = R3;

   R0 = 1.CMP.0.16;  // 求256個位圖變量最大值數組中的最大值。

   kxcmp(); // 返回R30L第一個符合條件的字符開始地址(最大值的序號)。

   R30H = R2.R30L.Z; // R30H爲最大值之最大值。

   JMP  mal2; // 成功。

ifree:

   R30L = R31H AND 0X00FF; // R30L爲位圖變量序號。

   R0 = 0.release.1.0

  JMP  val1;

}


比較、尋找空閒數的序號方法:kxcmp()        

入口:命令碼R0 = .CMP.0.16 、16位比較;R2 = 空閒數的數組首指針。

出口:返回符合條件的序號R30L。

佔用:9W、R30L

耗時:26ns

kxcmp(){

    B2 = R0;  B3H = R1H; // 初始化硬件模塊

    COPY.E( YJMK, R2, R0L );// 編譯後4條指令,耗時:12 ns

    SS1;    // 比較R0L行,找到非空序號。

    R30L = B4L;

    RET
}

3、小模式連續位管理

    一個平面線性4G單位的空間A,可以分割成64K個子空間;每個子空間有64K個單位。如果將空間看作是有64K個單位、則是小模式管理;單位可以是子空間、也可以是大模式空間的單位(小模式空間是子空間時)。映射到位圖空間,小模式空間就對應一個64K個位的位圖變量;或說是256個256位、即256E的位圖變量,如果每一個行的256位中有非零的位,則參數FNZB的相應位爲1、否則爲0;參數FNZB主要是用於快速位分配。

SMODE{            // 256E + 1W。

  BU256E SMBMP; // 小模式空間的管理位圖變量。

  BU1Z    MAXCB1;// 位圖變量的最大連續爲1的位數。

  BU1Z    ACTRN; // 位圖變量的實際行數。

}

    位圖變量的實際行數,決定了位圖變量的實際大小,未使用的行爲0。比如,本地內存空間實際只有32GB,而位圖變量是按照128GB設計的;實際的位圖變量只有32GB/512MB = 64行,後面的64-255行都是未使用的、行爲0(初始化時設置);數據塊分配、釋放只會在前面的64行進行。1位與連續多位的分配、釋放速度是大不一樣的,所以、會有2種不同的編程方式。

64K位的位圖變量的連續位分配、釋放管理方法:manage()       

入口:

R0命令碼:連續位、0.allot/release.1.0,

R1H: 爲分配或釋放的連續位數,

R1L: 分配時、爲0,釋放時是位圖變量的位序號,

R2: 64K位的位圖變量指針SMBMP。

出口:

釋放:返回修改後的位圖,

分配成功:

R0 = 位圖變量的最大連續1位數及開始位所屬的行號,返回修改後的位圖;

R31L = 分配的位圖變量開始位序號。

分配失敗:不修改位圖、PSR.YJ = 0。

佔用:17W,R31L。

耗時:釋放279ns,分配282ns,分配出錯:149ns。

manage(){ // 64K位的位圖變量的連續位分配、釋放管理方法。

  B2 = R0;  B3 = R1; // 初始化硬件模塊。

  COPY.E( YJMK, R2, 256 );// 編譯後4條指令,耗時:4+ 128 ns

  SS1;             // 釋放、或分配序號對應的連續N位。

  if R1L != 0 goto release; // 如果是釋放,跳。2W

  BT0  PSR.YJ, failret; // 失敗返回;不回傳。

  R0 = B4; R31L = B3L;    // 返回結果

release:

  COPY.E( R2, YJMK, 256 );// 成功則回傳。

  RET

五、位圖變量動態生成

    釋放總是成功的,但當我們申請分配失敗時,需要查找空閒的位圖變量;併爲之在基本空間中分配相對應的子空間,之後,再次分配。這時,對於基本空間是使用連續子空間分配、還是使用連續單位分配;就要看具體情況了。UNITLEN位圖變量一個單位的長度,是指在基本空間中的連續子空間值、或是連續單位值。


    爲了節省空間,中模式空間的256個子空間,並非是全部使用的,有一個動態增長的過程;需要一個空閒的位圖變量數的參數。有時候,即使是位圖變量的256行,也是一個動態增長的過程;需要一個空閒的位圖變量行數的參數。比如,進程的打開文件表項、或說是文件號,並非是每一個進程都需要打開64K個文件的;我們不可能一開始就分配一個數據塊用於進程的打開文件表項;這將是一個按需增長的過程。這些靈活因素,導致我們需要一個位圖變量動態生成方法。

位圖變量動態生成方法:bmpdgm()       

入口:

R0命令碼:7.CMP.0.16,

R1L: 48指向BMPVP.SSPN.序號, 289爲BMPVP1.SSPN,

R2: 指向FBMPVN中模式空間空閒的位圖變量數的數組。

R3:指向SSPN位圖變量對應的基本空間位號數組,未分配0、禁止1。

出口:

安裝子空間序號到相應位置,接着,再調用分配。

佔用:13W,R29-R31。

耗時:149ns。

lbmpdgm(){// 大模式位圖變量動態生成方法。

lbmp:

  R0 = 5.CMP.0.16;//求第一個位圖變量空閒數大於0的中模式空間序號  

  kxcmp( ,0 );// R30L爲位圖變量空閒數大於0的第一個中模式空間序號。

  BT0  PSR.YJ, mal3; // 失敗出錯返回。

  R3.R30L.Z-; // 空閒位圖變量數減1。

ibmp:

   R2 = R3 + R30L*R1L;// R2指向BMPVP.SSPN.序號,或BMPVP1.SSPN.序號。

   R0 = A.CMP.0.16; // 求第一個爲0的子空間序號。

   kxcmp(,0);// R30L爲第一個0的空閒位圖變量對應子空間序號。

   R29H = R30L;

   RET

// 接着,我們需要爲位圖變量分配一個對應的空閒子空間,如果是基本空間的連續

// 單位分配,用lmanage(7.CMP.0.16, UNITLEN值.0, LMODE )。如果是基本空

// 間的連續子空間分配,使用manage( 0.allot.1.0,UNITLEN值.0, SMODE )。

// 接着,跳lbmp2,安裝子空間序號到相應位置;接着,再一次調用分配。

lbmp2:

   R2.R29H.W = R31;// 安裝子空間序號到相應位置。

   RET

}

 

    太艱難了,耗費了160行代碼,還不清楚有多少錯誤;我們終於開始進入APO操作系統的空間管理主題。

六、內存管理

    本地內存作爲一個基本空間,只是一個單元64K個數據塊,對應有一個全局的64K位圖變量;需要一個小模式塊分配管理。最初的256塊在系統初始化時,已經分配給系統使用無須管理;即使有空餘的塊也是應急時用。

    本地內存空間本來就有限,如果代碼中聲明一個字變量,也要分配一個頁(4KB);那就很不合理,很扯蛋了;現代操作系統內存分配的粒度還是比較粗的。APO中,對於本地內存用連續行分配方式較之其它更爲合理,可以說無碎片問題,粒度可小到1E(32B、8W、16Z)。

本地內存管理:空間4GE、單位行E( 32B, 16Z, 8W ),子空間就是一個數據塊64KE。
1、申請分配、或釋放本地內存空間4GE的連續n個數據塊。
2、申請分配、或釋放本地內存空間4GE的某個數據塊中的連續n行。

1、連續內存塊管理

MEM_SMODE{ // 最大128GB的本地內存空間64K個數據塊,256E + 1W。

  BU256E  SMBMP; // 小模式空間的管理位圖變量。

  BU1Z    MAXCB1;// 位圖變量的最大連續爲1的位數。

  BU1Z    ACTRN; // 位圖變量的實際行數。

}


連續內存數據塊的分配與釋放方法:

manage( 0.allot/release.1.0, 連續數據塊數.0/數據塊號, MEM_SMODE );

分配成功: R31L = 分配的位圖變量開始位序號(數據塊號)。

分配失敗:不修改位圖、PSR.YJ = 0。

2、內存塊的連續行管理(大模式)

MEM_LMODE{  // 本地內存最大4G行的管理參數 12KE + 64E + 1W

  BU1W [256] BMPDBP;// 中模式空間管理位圖數據塊指針數組。

  BU1Z [256] FBMPVN;// 中模式空間空閒的位圖變量數的數組。不使用

  BU1Z [256] MMAXCB1;// 中模式空間最大連續位1數值之最大值數組

  BU48E [256] BMPVP{ // 中模式空間管理參數的數組

   BU1W [256] SSPN;  // 位圖變量對應的基本空間位號數組,不使用

   BU1Z [256]MAXCB1;// 位圖變量最大連續位1數值的數組。

  }

  BU1Z LACTN;    // 中模式空間(512MB一塊)的實際數。

  BU1Z UNITLEN;  // 位圖變量一個位的長度。不使用

}

 

    參數FBMPVN和 SSPN並不需要,本地內存作爲一個基本空間;位圖變量的序號就是數據塊序號,位圖變量的位序號就是數據塊內的開始行號。
   
內存連續行的分配方法:

lmanage( 7.CMP.0.16, 申請的連續1位數.0, MEM_LMODE ); 

返回:R31H、爲數據塊序號,R31L爲數據塊內的連續行數的開始行序號,

R0H爲0、成功,失敗則R0H = -1。

內存連續行的釋放方法:釋放時,R31H 爲數據塊序號。

lmanage( 0.release.1.0, 釋放的連續1位數.數據塊的行序號, MEM_LMODE ); 


七、本地內存v節點(或網絡v節點、TCP連接)管理

VNODE_IMODE1{     // 289E + 5Z。

  BU1W  BMPDBP;   // 中模式空間的管理位圖數據塊指針(SMBMP)。

  BU1Z  FBMPVN;   // 中模式空間空閒的位圖變量數。

  BU1Z ACTN;     // 中模式空間中,位圖變量的實際數。

  BU1Z BITLEN;   // 位圖變量一個位的長度。4

  BMPVP1{         // 中模式的256個位圖變量參數 289E

   BU1W [256] SSPN;// 位圖變量對應的基本空間位號數組,未分配0、禁止1。

   BU1E [256]FNZB;// 位圖變量256行的每一行所對應的非0位的數組

   BU256IFNZB;    // 256個位圖變量有空閒位1的數組。

  }

}

佔用:23W, R29-R31。

本地內存v節點的1位分配方法:imanage1(),分配一個v節點號。       

  imanage1( 0.allot.0.1,1.0, VNODE_IMODE1.BMPVP1,, VNODE_IMODE1.BMPDBP );

  if RH = 0 goto  mal2; // 成功返回R31。

  bmpdgm(7.CMP.0.16, 289,VNODE_IMODE1.FBMPVN, VNODE_IMODE1.SSPN );

  manage( 0.allot.1.0, 4.0, MEM_SMODE );//分配一個內存連續4數據塊。

  if R0H = -1 goto  print‘內存v節點滿’;//出錯返回

  R2 = R3 + R30L*R1L;//R2指向BMPVP1.序號。

  call lbmp2; // 安裝子空間序號到相應位置。

  R2.IFNZB.R29H = 1; R2.FNZB.R29H.E =1;

  imanage1( 0.allot.0.1, 1.0, .BMPVP1,, .BMPDBP );//再次分配。

  RET

出口:R31H、爲位圖變量序號,R31L爲連續位數的開始位序號,

R0H爲0、成功,失敗則R0H = -1。

 

本地內存v節點的1位釋放方法:imanage1(),釋放一個v節點號。

imanage1( 0.release.0.1,1.位圖變量的位序號,.BMPVP1,, .BMPDBP );

釋放時:R31H低8位爲位圖變量序號


     中模式空間16M個單位、單位4E( 128B, 64Z, 32W ),子空間就是一個64K單位 = 4個內存數據塊(UNITLEN = 4)。申請分配、或釋放中模式空間16M個單位的某個子空間64K單位中的一個單位。APO系統在一開始只是分配一個位圖變量,對應本地內存連續4個數據塊;當不夠用時(申請分配失敗),調用位圖變量動態生成方法bmpdgm()來擴充。


八、卷磁盤數據塊模式管理

卷磁盤數據塊模式管理:空間4G個單位、單位爲一個數據塊64KE( 2MB, 1MZ, 512KW ),子空間就是一個單元(64K個數據塊)。
1、申請分配、或釋放卷磁盤空間的連續n個單元。
2、申請分配、或釋放卷磁盤空間的某個單元中的連續n個數據塊。

    卷磁盤作爲一個基本空間,只是一個卷64K個單元,對應有一個全局的64K位圖變量;需要一個小模式單元分配管理。一個單元128GB,只有大於128GB的文件分配才爲使用連續單元分配方法;大部分的文件是使用大模式的連續數據塊分配方法。那些不到一個數據塊(2MB)的小文件,則集中到一些固定記錄文件裏;用於小文件集合的記錄文件類型有:小文件內容小於等於,1E、8E、32E、128E、512E、2KE、8KE、32KE。共8種類型的小文件記錄集文件,如果文件內容小於等於32KE、則文件內容按照大小被放入這8種類型的小文件記錄集文件裏;如果文件內容大於32KE,則使用大模式的連續數據塊分配方法、或連續單元分配方法。

1、卷磁盤連續單元管理

DISKV_SMODE{ // 最大8PB的卷磁盤空間64K個單元,256E + 1W。

  BU256E SMBMP; // 小模式空間的管理位圖變量。

  BU1Z    MAXCB1;// 位圖變量的最大連續爲1的位數。

  BU1Z    ACTRN; // 位圖變量的實際行數。

}


卷磁盤連續單元的分配與釋放方法:

manage( 0.allot/release.1.0, 連續單元數.0/單元號, DISKV_SMODE );

分配成功: R31L = 分配的位圖變量開始位序號(單元號)。

分配失敗:不修改位圖、PSR.YJ = 0。

2、卷磁盤連續數據塊管理(大模式)

DISKV_LMODE{  // 卷磁盤最大4G數據塊的管理參數 12KE + 64E + 1W

  BU1W [256] BMPDBP;// 中模式空間管理位圖數據塊指針數組。

  BU1Z [256] FBMPVN;// 中模式空間空閒的位圖變量數的數組。不使用

  BU1Z [256] MMAXCB1;// 中模式空間最大連續位1數值之最大值數組

  BU48E [256] BMPVP{ // 中模式空間管理參數的數組

   BU1W [256] SSPN;  // 位圖變量對應的基本空間位號數組,不使用

   BU1Z [256]MAXCB1;// 位圖變量最大連續位1數值的數組。

  }

  BU1Z LACTN;    // 中模式空間(512MB一塊)的實際數。

  BU1Z UNITLEN;  // 位圖變量一個位的長度。不使用

}

 

    參數FBMPVN和 SSPN並不需要,卷磁盤作爲一個基本空間;位圖變量的序號就是單元序號,位圖變量的位序號就是數據塊開始號。
   
卷磁盤連續數據塊的分配方法:

lmanage( 7.CMP.0.16, 申請的連續1位數.0, DISKV_LMODE ); 

返回:R31H、爲單元序號,R31L爲連續數據塊數的開始號,

R0H爲0、成功,失敗則R0H = -1。

卷磁盤連續數據塊的釋放方法:釋放時,R31H 爲單元序號。

lmanage( 0.release.1.0, 釋放連續1位數.數據塊開始號, DISKV_LMODE ); 


九、記錄型文件空間管理(數據庫管理)

    數據庫管理,表文件的n個字段記錄號管理,小文件記錄集文件的小文件記錄號管理等等,都是屬於記錄型文件的空間管理;爲通常的大模式、或中模式的記錄號管理。中模式管理,效率更高,只需一個位圖變量數據塊,可管理1600多萬條記錄;對於普通的應用已經足夠。

 

十、進程v節點、進程號管理


   進程v節點、進程號管理:小小模式空間8K個單位、單位8E( 256B, 128Z, 64W )申請分配、或釋放小小模式空間8K個單位中的一個單位。

十一、進程的打開文件表項、文件號管理

   進程的打開文件表項、文件號管理:小模式空間64K個單位、單位1E( 32B, 16Z, 8W )
申請分配、或釋放小模式空間64K個單位中的一個單位。


    艱苦啊!十天十夜了,還沒完沒了,暈倒!下一章,保留爲APO的文件I/O庫;第二十二章  網絡MAC。需要3天時間,清空當前的一切思想;準備啓動網絡思緒線程。

APO操作系統分爲六大部件:

1、APO文件目錄系統,

2、內核、進程、線程、調度,

3、空間管理,

4、GPU、顯示管理,

5、網絡,

6、其它設備驅動。

    每一個部件的代碼量約爲160行,這樣、整個APO操作系統的代碼量不到1000行。最爲艱苦的“空間管理”,已經基本完工,剩下的不太難,日子應該會好過些。


西邊的太陽快要落山了,

   微山湖上靜悄悄,

     彈起我心愛的土琵琶,

        唱起那動人的歌謠,


。。。。。。。。。。

待續


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章