Initial revision
[ssr] / StraySrc / SDLS / DLLManager / s / suballoc
1 ;
2 ; suballoc.s
3 ;
4 ; Handling of requests for small link blocks
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's Dynamic Linking System (SDLS)
12 ;
13 ; SDLS is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
16 ; any later version.
17 ;
18 ; SDLS is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ; GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public License
24 ; along with SDLS. If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard header ------------------------------------------------------
28
29 GET libs:swis
30 GET libs:header
31
32 ;----- External dependencies ------------------------------------------------
33
34 GET sh.wSpace
35 GET sh.linkblock
36
37 ;----- Word to the wise -----------------------------------------------------
38 ;
39 ; The DLink manager requires lots of small blocks for linked lists and
40 ; things. To avoid mangling the RMA, we allocate very big blocks and then
41 ; split them up into littler ones. The format of the very big blocks is as
42 ; follows:
43 ;
44 ; +0 link to next one
45 ; +4 [data]
46 ;
47 ; The data blocks are allocated such that they are just big enough for the
48 ; data -- the caller must specify the actual size of the block when freeing.
49 ; Freed blocks are *not* returned to the OS. There isn't much point -- it
50 ; would take ages, and they're only going to be allocated again anyway. All
51 ; big blocks are returned to the OS when the module quits.
52
53 ;----- Magic numbers --------------------------------------------------------
54
55 bigBlockSize EQU 1024*lk_strSize+4 ;Allocate 1024 small blocks
56 ;at a time
57
58 ;----- Main code ------------------------------------------------------------
59
60 AREA |DLLM$$Code|,CODE,READONLY
61
62 GBLL debug
63 debug SETL {FALSE}
64
65 ; --- sub_alloc ---
66 ;
67 ; On entry: --
68 ; On exit: R0 == pointer to block allocated, or 0 if no memory
69 ;
70
71 EXPORT sub_alloc
72 sub_alloc ROUT
73
74 STMFD R13!,{R1-R4,R14}
75 LDR R0,sub__free ;Get the free list offset
76 CMP R0,#0 ;Are there any free blocks?
77 BEQ %01sub_alloc ;No -- better allocate some
78
79 00sub_alloc LDR R2,[R0] ;Get next pointer from block
80 STR R2,sub__free ;This is now first free block
81 LDMFD R13!,{R1-R4,PC}^ ;Restore registers and return
82
83 01sub_alloc MOV R0,#6 ;Allocate some more from RMA
84 LDR R3,=bigBlockSize ;Allocate correct size
85 SWI XOS_Module ;Allocate the block
86 LDMVSFD R13!,{R1-R4,PC} ;Return on an error
87
88 LDR R4,sub__blocks ;Load the pointer
89 STR R4,[R2] ;Store in next ptr of new blk
90 STR R2,sub__blocks ;And link new block into list
91
92 MOV R0,#0 ;Next free pointer start at 0
93 SUB R3,R3,#lk_strSize ;Offset to next field of sub
94 02sub_alloc STR R0,[R2,R3] ;Store in next field
95 ADD R0,R2,R3 ;Point to that block
96 SUBS R3,R3,#lk_strSize ;Point to previous block
97 BGT %02sub_alloc ;If more to do, continue...
98 B %00sub_alloc ;Then allocate as normal
99
100 LTORG
101
102 ; --- sub_free ---
103 ;
104 ; On entry: R0 == pointer to block
105 ; On exit: R0 corrupted
106
107 EXPORT sub_free
108 sub_free ROUT
109
110 STMFD R13!,{R14} ;Preserve registers
111 LDR R14,sub__free ;Get current first block
112 STR R14,[R0] ;Store in newly freed block
113 STR R0,sub__free ;And insert new block in list
114 LDMFD R13!,{PC}^ ;Oh, and return to caller
115
116 LTORG
117
118 ; --- sub_die ---
119 ;
120 ; On entry: --
121 ; On exit: R0 corrupted
122
123 EXPORT sub_die
124 sub_die ROUT
125
126 STMFD R13!,{R1-R3,R14} ;Preserve used registers
127 MOV R3,#0 ;No errors yet
128 LDR R2,sub__blocks ;Point to list of blocks
129 MOV R0,#0 ;Blank out bigblock pointer
130 STR R0,sub__blocks ;In case it fails a bit
131 STR R0,sub__free
132 00sub_die CMP R2,#0 ;Are we at the end?
133 BEQ %01sub_die ;Yes -- leave the loop
134 LDR R1,[R2] ;Get next pointer right now
135 MOV R0,#7 ;Free memory
136 SWI XOS_Module ;Free the block up
137 MOVVS R3,R0 ;Remember the error, if any
138 MOV R2,R1 ;Move on to next block
139 B %00sub_die ;And try again
140
141 01sub_die MOVS R0,R3 ;Copy the error pointer back
142 LDMFD R13!,{R1-R3,R14} ;Restore the other registers
143 ORRNES PC,R14,#V_flag ;Set error indicator if reqd
144 BICS PC,R14,#V_flag ;Otherwise clear it
145
146 LTORG
147
148 ;----- That's all folks -----------------------------------------------------
149
150 END