chiark / gitweb /
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