6H(8KB),好像是大了点;但文件小于2KB的都放在i节点了,而无须磁盘空间分配;所以,还是很合理的。
在一个本地数据块内的连续行分配,在一个页区内的连续页分配,在一个单元内的连续数据块分配;i节点号分配,数据块记录号分配等等。这些项目的分配方法是需要使用到线性表的;因为分配是在4G的空间进行,要使用到64K个64K位的位图变量;是大模式。本来,连续行或连续页分配就挺复杂的;感觉再用链表就更复杂了。分配与释放是需要分成2个方法;newH和releaseH。
一个作为大模式分配的64K个资源单位的单位数据块,需要一个指向该单位块的指针,和一个64K位的位图变量;每位对于一个单位。可能会有很多个的这种连续资源单位分配的单位块;一个数据块可以装256个64K位的位图变量,对应着256个连续资源单位分配的单位块。理论上,64K个单位块需要256块位图变量数据块来管理。实际上,位图变量数据块是动态的,按需增长。最初,只是一个位图变量数据块;而位图变量数据块中的256个位图变量,也并非全部使用。比如,文件目录系统中;一个单位是指代表一个文件或目录的i节点。新建一个文件或目录,就是在大模式中请求分配一个空闲位,也就是分配一个i节点。类似的还有在一个数据库表中增加一条记录、为文件分配连续n页等等。大模式的单位序号是1W表示,连续单位数最大是半字1Z表示。因为最多有256个位图变量数据块、每个位图变量数据块最多有256个位图变量;所以单位序号的高16位的高8位是位图变量数据块序号,低8位是位图变量数据块中的位图变量序号;而低16位是相应位图变量的位序号。
大模式属性表:在磁盘空间中会有单元号,但在内存中只是块号。
DMUB{ // 4KH + 48H + 1W
BU1Z [256] WTKP; // 256个位图变量/块,本地内存的块号指针数组;不用或未分配的为0
BU1Z [256] WTKXU; // 每块256个位图变量中,空闲的位图变量数的数组。
BU1Z [256] MMLX1; // 每块256个位图变量中,最大连续为1的数值之最大值数组。
BU16H [256] MLYXUW1;// 256个位图变量块中256个最大连续为1的16位最大值数组的数组。
BU1W MAXLX1; // 位图变量中的最大的连续为1的位数及起始位号所属的行号。
}
每块256个位图变量中,可能有些位图变量还没使用;未使用的位图变量,其对应的最大连续为1的16位最大值为0;但位图变量的所有位都初始化为1。空闲的位图变量数的16位是空闲数,最多为256。没有使用到的位图块,其块号指针为0;其对应的位图变量最大连续为1的数值之最大值数为0;其对应的空闲的位图变量数为:0x0100。
newH分配方法:第一步,在最大连续为1的数值之最大值数组寻找是否有满足要求的位图变量块序号;有,拷贝相应块序号的256个最大连续为1的16位最大值数组(16H),比较得到满足要求的位图变量序号;将对应的位图变量拷贝进硬件模块进行分配。返回结果:32位的单位序号;耗时378ns。否,第二步,在空闲的位图变量数的数组中寻找大于等于1的第一个位图变量块的序号;失败跳错误处理;成功,用空闲的位图变量拷贝进硬件模块进行分配,空闲的位图变量数-1。
newH{ // 大模式分配方法:数据库记录、内存连续行、磁盘的连续数据块、连续页分配。
// 入口:R0-R4,返回R0:申请的连续行数或连续数据块或连续页数等及开始地址。
// R0-R4 = ( 7.CMP.0.16, 申请的连续1位数.0, &DMUB, &DMUB.MAXLX1, &变量)
// 占用:44W, 6H。 耗时:非新位图变量,378ns。否,411ns、32.418us
R27 = R2; R28 = R2 + 16; R29 = R2 +32; R30 = R2 + 48;// R27-R30指向DUMB成员
R2 = R29; R24 = R1; // R2 = &DMUB.MMLX1;保存R1。
GKLIYK(); // 返回R0 = 第一个符合条件的字符开始地址(位图变量块号的序号)。25ns
BT0 PSR.YJ, #ne3; // 失败跳、寻找还没分配的位图变量。到此,33ns
R26H = R0L; // 保存块序号到R26H,
R0 = 7.CMP.0.16; // 求满足要求的位图变量最大值的位图变量序号
ne1: // 这段耗时:343ns
R2 = R30 + R0L<<4; // R2指向块序号的块的256个位图变量最大值数组成员。
// DMUB.MLYXUW1.块序号成员(R0L<<4,每个成员占16行)。
R25 = R2; // 保存到R25。
GKLIYK(); // 返回R0L = 第一个符合条件的字符开始地址(位图变量序号)。
R26L = R0L;
ne2: // 这段耗时:314ns
R2 = R27.R26H + R0L<<8;// R2指向符合条件的位图变量。.WTKP.块序号 + 变量行号。
R0 = 0.allot.1.0; R1 = R24; // 分配指令,恢复R1。
GKLIYK(); // 分配、拷贝相应位图变量的256行。
R25.R26L = (R3).H; //保存最大值到位图变量最大值数组。
R23L = R0L; // 保存16位在变量位图中的序号。
R2 = R25;
R0 = 4.CMP.0.16; // 求256个位图变量最大值数组中的最大值。
GKLIYK(); // 返回R0L = 第一个符合条件的字符开始地址(最大值的序号)。
R29.R26H = R25.R0L;// 保存最大值之最大值。DMUB.MMLX1.R26H
R0H = R26L + R26H <<8; // 返回R0H为单位块序号、块中的位图变量序号。
R0L = R23L; // 返回R0为单位序号。
RET
ne3:
R2 = R28; // R2 = &DMUB.WTKXU。
R1H = 1;
R0 = 7.CMP.0.16; // 求256个空闲的位图变量数大于1的块序号。
GKLIYK(); // 返回R0L = 第一个符合条件的字符开始地址(块序号)。
R26H = R0L;
CMPZ R28.R0L, #0X0100;// 是空闲块?
JZ ne4; // 是、跳申请1个位图变量数据块。
R28.R0L-; //空闲位图变量数减1
R1 = 0; R0 = 6.CMP.0.16;
JMP ne1; // 求第一个为0的变量序号、并分配。本段耗时35ns
ne4:
Allot1( 0.Allot.0.1, 1.0,&mem_XMUB, &mem_XMUB.MAXLX1 );
R27.R26H = R0L; // 保存块号
KY_init(); // 块初始化为全1;DMUB.MLYXUW1.R0L<<4的16行初始化为0。耗时,32.01us
R26L = 0; R28.R26H = 0X00FF;
JMP ne2; // 本段耗时32.071us
}
releaseH{
// 入口:R0-R4,返回R0:位图的最大连续单位数的开始单位号。
// R0-R4 = ( 0.release.1.0, 释放的连续1位数, &DMUB,&DMUB.MAXLX1, 单位序号 )
// 占用:12W, 2H。 耗时: ns
R1H = R1L; R1L = R4L; R30L = R4H;
R30L = >>8; R30H = R4H <<8; // R30L为块序号,R30H为位图变量序号
R2 = R2.R30L + R30H; // R2指向对应的位图变量
GKLIYK(); // 释放,如果整个位图释放了,最大值变为0;位图变量空闲数+1,如为0x0100
// 就要块释放。否,保存最大值、最大值判断、最大之最大值判断并保存。
。。。
}
晕了,费那么大力;这样复杂的内容、代码量才10H,还要不断修改。离目标代码量512H还很遥远,系统核心的核心只是2条指令2W;即使是进程、线程调度也就几行代码;如何是好?看来,要把应用程序的90%的代码量由系统来完成,各种框架、模式都集成到系统里去。
3、数据库连接
对于连接这种资源,可以看