SHTHEAP.LST 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. Listing:
  2. 1 (* Release 3.10 *)
  3. 2 (*-------------------------------------------------------------------------*
  4. 3 * *
  5. 4 * SHTHEAP.MOD - Short heaps *
  6. 5 * *
  7. 6 * COPYRIGHT (C) 1987..1992 Clarion Software Corporation. *
  8. 7 * All Rights Reserved *
  9. 8 * *
  10. 9 *--------------------------------------------------------------------------*)
  11. 10
  12. 11 (*# call(o_a_copy => on,
  13. 12 o_a_size => on) *)
  14. 13 (*%F _fdata *)
  15. 14 (*# call(seg_name => null) *)
  16. 15 (*# data(seg_name => null) *)
  17. 16 (*%E *)
  18. 17 (*# module(implementation=>off) *)
  19. 18 (*# check(stack=>off,
  20. 19 index=>off,
  21. 20 range=>off,
  22. 21 overflow=>off,
  23. 22 nil_ptr=>off) *)
  24. 23
  25. 24 IMPLEMENTATION MODULE ShtHeap ;
  26. 25
  27. 26 IMPORT Lib, SYSTEM, CoreSig;
  28. 27
  29. 28 TYPE Offset = CARDINAL;
  30. 29 Block = RECORD
  31. 30 Siz: Size;
  32. ***** ^ undeclared identifier
  33. 31 Nxt: Pointer;
  34. ***** ^ undeclared identifier
  35. 32 END;
  36. ***** ^ not supported yet
  37. 33
  38. 34
  39. 35 PROCEDURE Initialize ( H: Segment; Z: Size );
  40. ***** ^ undeclared identifier
  41. ***** ^ undeclared identifier
  42. 36 VAR B,F: POINTER H TO Block;
  43. ***** ^ 'FORWARD' expected
  44. 37 BEGIN
  45. 38 Z := (Z DIV Align) * Align;
  46. 39 IF Z < 10 THEN
  47. 40 Lib.RunTimeError(CoreSig._FatalErrorPos(), 9AH, 'ShtHeap.Initialize : Size Too Small');
  48. 41 END;
  49. 42 B := Pointer ( 0 );
  50. 43 F := Pointer ( Align );
  51. 44 B^.Siz := Z;
  52. 45 B^.Nxt := F;
  53. 46 F^.Siz := Z - Align;
  54. 47 F^.Nxt := Nil;
  55. 48 END Initialize;
  56. 49
  57. 50
  58. 51 PROCEDURE Increase ( H: Segment; Z: Size );
  59. 52 VAR B,L,I: POINTER H TO Block;
  60. 53 BEGIN
  61. 54 IF Debug THEN
  62. 55 Test ( H );
  63. 56 END;
  64. 57 Z := (Z DIV Align) * Align;
  65. 58 B := Pointer ( 0 );
  66. 59 IF Z > MAX(Size) - B^.Siz THEN
  67. 60 Lib.RunTimeError(CoreSig._FatalErrorPos(), 9BH, 'ShtHeap.Increase : Size Too Large');
  68. 61 END;
  69. 62 I := B;
  70. 63 REPEAT
  71. 64 L := I;
  72. 65 I := I^.Nxt;
  73. 66 UNTIL I = Nil;
  74. 67 IF (L # B) AND (Offset ( L ) + L^.Siz = B^.Siz) THEN
  75. 68 INC ( L^.Siz , Z );
  76. 69 ELSE
  77. 70 I := Pointer ( B^.Siz );
  78. 71 L^.Nxt := I;
  79. 72 I^.Siz := Z;
  80. 73 I^.Nxt := Nil;
  81. 74 END;
  82. 75 INC ( B^.Siz , Z );
  83. 76 END Increase;
  84. 77
  85. 78
  86. 79 PROCEDURE Allocate ( H: Segment; VAR P: Pointer; Z: Size );
  87. 80 VAR B,F,G,N: POINTER H TO Block;
  88. 81 BEGIN
  89. 82 IF Debug THEN
  90. 83 Test ( H );
  91. 84 END;
  92. 85 Z := ( (Z+Align-1) DIV Align) * Align;
  93. 86 IF Z = 0 THEN
  94. 87 Lib.RunTimeError(CoreSig._FatalErrorPos(), 9CH, 'ShtHeap.Allocate : Size Too Small');
  95. 88 END;
  96. 89 B := Pointer ( 0 );
  97. 90 G := B;
  98. 91 LOOP
  99. 92 F := G^.Nxt;
  100. 93 IF F = Nil THEN
  101. 94 IF Check THEN
  102. 95 Lib.RunTimeError(CoreSig._FatalErrorPos(), 9DH, 'ShtHeap.Allocate : Out Of Memory');
  103. 96 ELSE
  104. 97 P := Nil;
  105. 98 RETURN;
  106. 99 END;
  107. 100 ELSIF F^.Siz >= Z THEN
  108. 101 EXIT;
  109. 102 END;
  110. 103 G := F;
  111. 104 END;
  112. 105 IF F^.Siz = Z THEN
  113. 106 G^.Nxt := F^.Nxt;
  114. 107 ELSE
  115. 108 N := Pointer ( Offset ( F ) + Z );
  116. 109 G^.Nxt := N;
  117. 110 N^.Siz := F^.Siz - Z;
  118. 111 N^.Nxt := F^.Nxt;
  119. 112 END;
  120. 113 IF Clear THEN
  121. 114 Lib.WordFill ( ADR(F^) , Z DIV 2 , 0 );
  122. 115 END;
  123. 116 P := F;
  124. 117 END Allocate;
  125. 118
  126. 119
  127. 120 PROCEDURE Free ( H: Segment; VAR P: Pointer; Z: Size );
  128. 121 VAR B,F,G,Q: POINTER H TO Block;
  129. 122 BEGIN
  130. 123 IF Debug THEN
  131. 124 Test ( H );
  132. 125 END;
  133. 126 Z := ( (Z+Align-1) DIV Align) * Align;
  134. 127 Q := P;
  135. 128 P := Nil;
  136. 129 IF Q = Nil THEN
  137. 130 Lib.RunTimeError(CoreSig._FatalErrorPos(), 9EH, 'ShtHeap.Free : Invalid Argument');
  138. 131 END;
  139. 132 B := Pointer ( 0 );
  140. 133 G := B;
  141. 134 LOOP
  142. 135 F := G^.Nxt;
  143. 136 IF (F = Nil) OR (Offset ( Q ) < Offset ( F )) THEN EXIT; END;
  144. 137 G := F;
  145. 138 END;
  146. 139 IF Offset ( G ) + G^.Siz = Offset ( Q ) THEN
  147. 140 INC ( G^.Siz , Z );
  148. 141 Q := G;
  149. 142 ELSE
  150. 143 G^.Nxt := Q;
  151. 144 Q^.Nxt := F;
  152. 145 Q^.Siz := Z;
  153. 146 END;
  154. 147 IF Offset ( Q ) + Q^.Siz = Offset ( F ) THEN
  155. 148 INC ( Q^.Siz , F^.Siz );
  156. 149 Q^.Nxt := F^.Nxt;
  157. 150 END;
  158. 151 END Free;
  159. 152
  160. 153
  161. 154 PROCEDURE Largest ( H: Segment ): Size;
  162. 155 VAR P: POINTER H TO Block;
  163. 156 Z: Size;
  164. 157 BEGIN
  165. 158 IF Debug THEN
  166. 159 Test ( H );
  167. 160 END;
  168. 161 P := Pointer ( 0 );
  169. 162 P := P^.Nxt;
  170. 163 Z := 0;
  171. 164 WHILE P # Nil DO
  172. 165 IF Z < P^.Siz THEN
  173. 166 Z := P^.Siz;
  174. 167 END;
  175. 168 P := P^.Nxt;
  176. 169 END;
  177. 170 RETURN Z;
  178. 171 END Largest;
  179. 172
  180. 173
  181. 174 PROCEDURE Total ( H: Segment ): Size;
  182. 175 VAR P: POINTER H TO Block;
  183. 176 Z: Size;
  184. 177 BEGIN
  185. 178 IF Debug THEN
  186. 179 Test ( H );
  187. 180 END;
  188. 181 P := Pointer ( 0 );
  189. 182 P := P^.Nxt;
  190. 183 Z := 0;
  191. 184 WHILE P # Nil DO
  192. 185 INC ( Z , P^.Siz );
  193. 186 P := P^.Nxt;
  194. 187 END;
  195. 188 RETURN Z;
  196. 189 END Total;
  197. 190
  198. 191
  199. 192 PROCEDURE Test ( H: Segment );
  200. 193 VAR B,F,G: POINTER H TO Block;
  201. 194 BEGIN
  202. 195 B := Pointer ( 0 );
  203. 196 IF B^.Siz MOD Align # 0 THEN
  204. 197 Lib.RunTimeError(CoreSig._FatalErrorPos(), 9FH, 'ShtHeap.Test : Non-aligned heap size.');
  205. 198 END;
  206. 199 G := B;
  207. 200 LOOP
  208. 201 F := G^.Nxt;
  209. 202 IF F = Nil THEN EXIT; END;
  210. 203 IF Offset ( F ) >= B^.Siz THEN
  211. 204 Lib.RunTimeError(CoreSig._FatalErrorPos(), 9FH, "ShtHeap.Test: Free block out of range" );
  212. 205 ELSIF Offset ( F ) MOD Align # 0 THEN
  213. 206 Lib.RunTimeError(CoreSig._FatalErrorPos(), 9FH, "ShtHeap.Test: Non-aligned free block" );
  214. 207 ELSIF F^.Siz MOD Align # 0 THEN
  215. 208 Lib.RunTimeError(CoreSig._FatalErrorPos(), 9FH, "ShtHeap.Test: Non-aligned free block size" );
  216. 209 ELSIF Offset ( F ) < Offset ( G ) THEN
  217. 210 Lib.RunTimeError(CoreSig._FatalErrorPos(), 9FH, "ShtHeap.Test: Unordered free list" );
  218. 211 ELSIF (G # B) AND (Offset ( G ) + G^.Siz = Offset ( F )) THEN
  219. 212 Lib.RunTimeError(CoreSig._FatalErrorPos(), 9FH, "ShtHeap.Test: Unjoined free list" );
  220. 213 ELSIF (G # B) AND (Offset ( G ) + G^.Siz > Offset ( F )) THEN
  221. 214 Lib.RunTimeError(CoreSig._FatalErrorPos(), 9FH, "ShtHeap.Test: Overlapping free list" );
  222. 215 END;
  223. 216 G := F;
  224. 217 END;
  225. 218 END Test;
  226. 219
  227. 220
  228. 221 BEGIN
  229. 222 IF SIZE ( Block ) > Align THEN
  230. 223 Lib.FatalError ( "ShtHeap: Alignment too small" );
  231. 224 END;
  232. 225 Clear := FALSE;
  233. 226 Check := TRUE;
  234. 227 Debug := FALSE;
  235. 228 END ShtHeap.
  236. 6 errors