.TITLE HEAP_MANAGEMENT .ENABLE DEBUG ;V1.14 .SUBTITLE DATA STORAGE AREA .PSECT IMPURE_DATA,RD,WRT,NOEXE,NOSHR,LONG,CON,GBL ARG1: .LONG 0 ARG2: .LONG 0 ; ; HEAP STORAGE AREAS ; ; STORAGE FOR 1 BLOCK LONG SEGMENTS (64 BYTES) ; ONE_BLOCK: .LONG 0,0 ; ; STORAGE FOR 2 BLOCK LONG SEGMENTS (128 BYTES) ; TWO_BLOCK: .LONG 0,0 ; ; STORAGE FOR 3 BLOCK LONG SEGMENTS (192 BYTES) ; THREE_BLOCK: .LONG 0,0 ; ; STORAGE FOR 4 BLOCK LONG SEGMENTS (256 BYTES) ; FOUR_BLOCK: .LONG 0,0 ; ;V2.17 ; STORAGE FOR 5 BLOCK LONG SEGMENTS (320 BYTES) ;V2.17 ; ;V2.17 FIVE_BLOCK: ;V2.17 .LONG 0,0 ;V2.17 .PSECT PURE_DATA,RD,NOWRT,NOEXE,SHR,CON,GBL VM_ARG: .LONG 2 .ADDRESS ARG1,ARG2 .PAGE .SUBTITLE INIT HEAP SPACE .PSECT CODE,RD,NOWRT,EXE,SHR,CON,GBL .ENTRY INIT_HEAP,^M ; INIT THE HEAP QUEUE HEADERS MOVAL ONE_BLOCK,ONE_BLOCK MOVL ONE_BLOCK,ONE_BLOCK+4 MOVAL TWO_BLOCK,TWO_BLOCK MOVL TWO_BLOCK,TWO_BLOCK+4 MOVAL THREE_BLOCK,THREE_BLOCK MOVL THREE_BLOCK,THREE_BLOCK+4 MOVAL FOUR_BLOCK,FOUR_BLOCK MOVL FOUR_BLOCK,FOUR_BLOCK+4 MOVAL FIVE_BLOCK,FIVE_BLOCK ;V2.17 MOVL FIVE_BLOCK,FIVE_BLOCK+4 ;V2.17 ; LOAD THE INITIAL AMOUNTS ON EACH HEAP CALLG NULL,LOAD_ONE_BLOCK CALLG NULL,LOAD_TWO_BLOCK ;V1.15 ; CALLG NULL,LOAD_THREE_BLOCK ;V2.17 ; CALLG NULL,LOAD_FOUR_BLOCK ;V1.4 CALLG NULL,LOAD_FIVE_BLOCK ;V2.17 RET ;**-3 .PAGE .SUBTITLE ALLOCATE FROM SYSSTEM MEMORY-MORE HEAP OF APPROPRIATE SIZE .ENTRY LOAD_ONE_BLOCK,^M ; ALLOCATE TO ONE BLOCK LONG SEGMENTS ENOUGH MEMORY FOR ; 500-64 BYTE BLOCKS ADDL2 #500,ELEMENT_64 ;ADD NEW BLOCKS TO STATISTICS ;V1.4 MOVL #<500*64>,ARG1 ;500 BLOCKS (32000 BYTES) CALLG VM_ARG,G^LIB$GET_VM;ASK THE SYSTEM FOR IT BLBS R0,1$ $EXIT_S R0 1$: MOVL ARG2,R11 ;GET STARTING ADDRESS MOVL #500,R10 ;SET UP COUNTER FOR 500 BLOCKS 2$: INSQUE (R11),ONE_BLOCK ;INSTALL BLOCK OF 64 BYTES IN QUEUE OF FREE STORAGE ADDL2 #64,R11 ;ADVANCE TO NEXT BLOCK SOBGTR R10,2$ ;REPEAT UNTILL ALL BLOCKS INSERTED RET .ENTRY LOAD_TWO_BLOCK,^M ; ALLOCATE TO TWO BLOCK LONG SEGMENTS ENOUGH MEMORY FOR ; 100-128 BYTE BLOCKS ;V2.01 ADDL2 #1000,ELEMENT_128 ;V2.01 MOVL #<1000*128>,ARG1 ;1000 BLOCKS (128000 BYTES) ;V2.01 CALLG VM_ARG,G^LIB$GET_VM;ASK THE SYSTEM FOR IT BLBS R0,1$ $EXIT_S R0 1$: MOVL ARG2,R11 ;GET STARTING ADDRESS MOVL #1000,R10 ;SET UP COUNTER FOR 50 BLOCKS ;V2.01 2$: INSQUE (R11),TWO_BLOCK ;INSTALL BLOCK OF 128 BYTES IN QUEUE OF FREE STORAGE ADDL2 #128,R11 ;ADVANCE TO NEXT BLOCK SOBGTR R10,2$ ;REPEAT UNTILL ALL BLOCKS INSERTED RET .ENTRY LOAD_THREE_BLOCK,^M ; ALLOCATE TO ONE BLOCK LONG SEGMENTS ENOUGH MEMORY FOR ; 20-192 BYTE BLOCKS ;V2.01 ADDL2 #20,ELEMENT_192 ;V2.01 MOVL #<20*192>,ARG1 ;20 BLOCKS (3840 BYTES) ;V1.4 CALLG VM_ARG,G^LIB$GET_VM;ASK THE SYSTEM FOR IT ;**-1 BLBS R0,1$ $EXIT_S R0 1$: MOVL ARG2,R11 ;GET STARTING ADDRESS MOVL #20,R10 ;SET UP COUNTER FOR 20 BLOCKS ;V1.4 2$: INSQUE (R11),THREE_BLOCK ;INSTALL BLOCK OF 192 BYTES IN QUEUE OF FREE STORAGE ADDL2 #192,R11 ;ADVANCE TO NEXT BLOCK SOBGTR R10,2$ ;REPEAT UNTILL ALL BLOCKS INSERTED RET .ENTRY LOAD_FOUR_BLOCK,^M ; ALLOCATE TO ONE BLOCK LONG SEGMENTS ENOUGH MEMORY FOR ; 2-256 BYTE BLOCKS ADDL2 #2,ELEMENT_256 ;V1.4 MOVL #<2*256>,ARG1 ;2 BLOCKS (512 BYTES) CALLG VM_ARG,G^LIB$GET_VM;ASK THE SYSTEM FOR IT BLBS R0,1$ $EXIT_S R0 1$: MOVL ARG2,R11 ;GET STARTING ADDRESS MOVL #2,R10 ;SET UP COUNTER FOR 2 BLOCKS 2$: INSQUE (R11),FOUR_BLOCK ;INSTALL BLOCK OF 512 BYTES IN QUEUE OF FREE STORAGE ADDL2 #256,R11 ;ADVANCE TO NEXT BLOCK SOBGTR R10,2$ ;REPEAT UNTILL ALL BLOCKS INSERTED RET .ENTRY LOAD_FIVE_BLOCK,^M ;V2.17 ; ALLOCATE TO ONE BLOCK LONG SEGMENTS ENOUGH MEMORY FOR ;V2.17 ; 2-320 BYTE BLOCKS ;V2.17 ADDL2 #2,ELEMENT_320 ;V2.17 MOVL #<2*320>,ARG1 ;2 BLOCKS (640 BYTES) ;V2.17 CALLG VM_ARG,G^LIB$GET_VM;ASK THE SYSTEM FOR IT ;V2.17 BLBS R0,1$ ;V2.17 $EXIT_S R0 ;V2.17 1$: MOVL ARG2,R11 ;GET STARTING ADDRESS ;V2.17 MOVL #2,R10 ;SET UP COUNTER FOR 2 BLOCKS ;V2.17 2$: INSQUE (R11),FIVE_BLOCK ;INSTALL BLOCK OF 320 BYTES ;V2.17 ADDL2 #320,R11 ;ADVANCE TO NEXT BLOCK ;V2.17 SOBGTR R10,2$ ;REPEAT UNTILL ALL BLOCKS INSERTED ;V2.17 RET ;V2.17 .PAGE .SUBTITLE ALLOCATE HEAP SPACE .ENTRY ALLOCATE,^M ; ; I=ALLOCATE(NUMBER OF BYTES) ; ; WHERE I IS THE ADDRESS OF THE N*64 BYTE BLOCK ALLOCATED ; MOVL @4(AP),R0 ;GET THE COUNT BITL #^X3F,R0 ;DOES IT NEED TO BE ROUNDED UP TO ;NEXT 64 BYTE BLOCK BEQL 10$ BICL2 #^X3F,R0 ;LOP OFF LOW ORDER BITS ADDL2 #^X40,R0 ;AND ROUND UP TO NEXT BLOCK SIZE 10$: DIVL3 #64,R0,R1 ;NUMBER OF BLOCKS CASEL R1,#1,#4 ;ALLOCATE FROM APPROPRIATE HEAP ;V2.17 11$: .WORD GET_1-11$ .WORD GET_2-11$ .WORD GET_3-11$ .WORD GET_4-11$ .WORD GET_5-11$ ;V2.17 ; OTHER SIZE WANTED-ALOCATE AS NEEDED MOVL R0,ARG1 ;LOAD BLOCK SIZE CALLG VM_ARG,G^LIB$GET_VM BLBS R0,1$ $EXIT_S R0 1$: MOVC5 #0,NULL,#0,ARG1,@ARG2 ;V3.00 MOVL ARG2,R0 INCL ELEMENT_LARGE ;V1.4 INCL ELEMENT_LARGE+4 ;V1.4 INCL ELEMENT_LARGE+8 ;V1.4 RET ;V1.4 GET_1: INCL ELEMENT_64+4 ;V1.4 INCL ELEMENT_64+8 ;V1.4 REMQUE @ONE_BLOCK,R11 ;GET BLOCK ;V3.00 BVC 1$ ;BRANCH IF OK ;V3.00 CALLG NULL,LOAD_ONE_BLOCK ;LOAD UP WITH MORE MEMORY ;V3.00 REMQUE @ONE_BLOCK,R11 ;ALLOCATE ;V3.00 1$: MOVC5 #0,NULL,#0,#64,(R11) ;V3.00 MOVL R11,R0 ;V3.00 RET GET_2: INCL ELEMENT_128+4 ;V1.4 INCL ELEMENT_128+8 ;V1.4 REMQUE @TWO_BLOCK,R11 ;GET BLOCK ;V3.00 BVC 1$ ;BRANCH IF OK ;V3.00 CALLG NULL,LOAD_TWO_BLOCK ;LOAD UP WITH MORE MEMORY ;V3.00 REMQUE @TWO_BLOCK,R11 ;ALLOCATE ;V3.00 1$: MOVC5 #0,NULL,#0,#128,(R11) ;V3.00 MOVL R11,R0 ;V3.00 RET GET_3: INCL ELEMENT_192+4 ;V1.4 INCL ELEMENT_192+8 ;V1.4 REMQUE @THREE_BLOCK,R11;GET BLOCK ;V3.00 BVC 1$ ;BRANCH IF OK ;V3.00 CALLG NULL,LOAD_THREE_BLOCK ;LOAD UP WITH MORE MEMORY ;V3.00 REMQUE @THREE_BLOCK,R11 ;ALLOCATE ;V3.00 1$: MOVC5 #0,NULL,#0,#192,(R11) ;V3.00 MOVL R11,R0 ;V3.00 RET GET_4: INCL ELEMENT_256+4 ;V1.4 INCL ELEMENT_256+8 ;V1.4 REMQUE @FOUR_BLOCK,R11 ;GET BLOCK ;V3.00 BVC 1$ ;BRANCH IF OK ;V3.00 CALLG NULL,LOAD_FOUR_BLOCK ;LOAD UP WITH MORE MEMORY ;V3.00 REMQUE @FOUR_BLOCK,R11 ;ALLOCATE ;V3.00 1$: MOVC5 #0,NULL,#0,#256,(R11) ;V3.00 MOVL R11,R0 ;V3.00 RET GET_5: INCL ELEMENT_320+4 ;V2.17 INCL ELEMENT_320+8 ;V2.17 REMQUE @FIVE_BLOCK,R11 ;GET BLOCK ;V3.00 BVC 1$ ;BRANCH IF OK ;V3.00 CALLG NULL,LOAD_FIVE_BLOCK ;LOAD UP WITH MORE MEMORY ;V3.00 REMQUE @FIVE_BLOCK,R11 ;ALLOCATE ;V3.00 1$: MOVC5 #0,NULL,#0,#320,(R11) ;V3.00 MOVL R11,R0 ;V3.00 RET ;V2.17 .PAGE .ENTRY FREE,^M ; ; CALL FREE(SIZE IN BYTES,BLOCK ADDRESS) ; ; MOVL @4(AP),R0 ;GET THE COUNT BITL #^X3F,R0 ;DOES IT NEED TO BE ROUNDED UP TO ;NEXT 64 BYTE BLOCK BEQL 10$ BICL2 #^X3F,R0 ;LOP OFF LOW ORDER BITS ADDL2 #^X40,R0 ;AND ROUND UP TO NEXT BLOCK SIZE 10$: DIVL3 #64,R0,R1 CASEL R1,#1,#4 ;SELECT WHICH HEAP ;V2.17 11$: .WORD PUT_1-11$ .WORD PUT_2-11$ .WORD PUT_3-11$ .WORD PUT_4-11$ .WORD PUT_5-11$ ;V2.17 ; LARGE SIZE BLOCK-RETURN TO SYSTEM STORAGE MOVL R0,ARG1 ;LOAD BLOCK SIZE MOVL @8(AP),ARG2 CALLG VM_ARG,G^LIB$FREE_VM BLBS R0,1$ $EXIT_S R0 1$: DECL ELEMENT_LARGE ;V1.4 DECL ELEMENT_LARGE+4 ;V1.4 RET ;V1.4 PUT_1: MOVL @8(AP),R0 ;V1.4 INSQUE (R0),ONE_BLOCK ;V1.4 DECL ELEMENT_64+4 ;V1.4 RET ;**-3 PUT_2: MOVL @8(AP),R0 INSQUE (R0),TWO_BLOCK DECL ELEMENT_128+4 ;V1.4 RET PUT_3: MOVL @8(AP),R0 INSQUE (R0),THREE_BLOCK DECL ELEMENT_192+4 ;V1.4 RET PUT_4: MOVL @8(AP),R0 INSQUE (R0),FOUR_BLOCK DECL ELEMENT_256+4 ;V1.4 RET PUT_5: MOVL @8(AP),R0 ;V2.17 INSQUE (R0),FIVE_BLOCK ;V2.17 DECL ELEMENT_320+4 ;V2.17 RET ;V2.17 .END