MSTORAGE.MOD 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. (* Release 3.10 *)
  2. (*-------------------------------------------------------------------------*
  3. * *
  4. * MSTORAGE.MOD - Dynamic allocations for mixed M2/C, and overlay model *
  5. * *
  6. * COPYRIGHT (C) 1987..1992 Clarion Software Corporation. *
  7. * All Rights Reserved *
  8. * *
  9. *--------------------------------------------------------------------------*)
  10. (*%F _fdata *)
  11. (*# call(seg_name => null) *)
  12. (*# data(seg_name => null) *)
  13. (*%E *)
  14. (*# module(implementation=>off) *)
  15. (*# check(stack=>off,
  16. index=>off,
  17. range=>off,
  18. overflow=>off,
  19. nil_ptr=>off) *)
  20. IMPLEMENTATION MODULE Storage;
  21. (*
  22. Version of STORAGE.MOD for DOS Overlay, Dynalink and mixed-language
  23. libraries
  24. *)
  25. IMPORT SYSTEM, Lib, CoreMem, CoreSig, CoreMain;
  26. (*%T _mthread *)
  27. IMPORT Process;
  28. (*%E *)
  29. CONST
  30. _DLLOVL = (_DLL OR _OVL) AND NOT _OS2;
  31. CONST
  32. EndMarker = 0FFFFH;
  33. Align = 4;
  34. (* This is DOS ONLY *)
  35. PROCEDURE FarMakeHeap( Source : CARDINAL; (* base segment of heap *)
  36. Size : CARDINAL (* size in paragraphs *)
  37. ) : FarHeapRecPtr;
  38. VAR
  39. storage,first,last : FarHeapRecPtr;
  40. BEGIN
  41. (*%T _mthread *)
  42. Process.Lock;
  43. (*%E *)
  44. storage := [Source:0];
  45. first := [Source+1:0];
  46. last := [Source+Size-1:0];
  47. storage^.next := first;
  48. storage^.size := 0;
  49. first^.next := last;
  50. last^.next := storage;
  51. first^.size := Size-2;
  52. last^.size := EndMarker;
  53. (*%T _mthread *)
  54. Process.Unlock;
  55. (*%E *)
  56. RETURN storage;
  57. END FarMakeHeap;
  58. PROCEDURE FarHeapAllocate(Source : FarHeapRecPtr; (* source heap *)
  59. VAR A : FarADDRESS; (* result *)
  60. Size : CARDINAL); (* request size in paragraphs *)
  61. VAR
  62. res,prev,split : FarHeapRecPtr;
  63. BEGIN
  64. IF Source = MainHeap THEN
  65. A:=CoreMem.halloc(LONGCARD(Size)<<4);
  66. IF A = SYSTEM.FarNIL THEN
  67. IF Check THEN
  68. Lib.RunTimeError(CoreSig._FatalErrorPos(), 90H, 'FarHeapAllocate : Out Of Space');
  69. ELSE
  70. A := FarNIL;
  71. RETURN;
  72. END;
  73. END;
  74. RETURN;
  75. END;
  76. (*%T _mthread *)
  77. Process.Lock;
  78. (*%E *)
  79. IF Size=0 THEN INC(Size) END ;
  80. prev := Source;
  81. WHILE prev^.next^.size < Size DO
  82. prev := prev^.next;
  83. END;
  84. res := prev^.next;
  85. IF res^.size = EndMarker THEN (* heap run out of space *)
  86. SYSTEM.EI ;
  87. IF Check THEN
  88. Lib.RunTimeError(CoreSig._FatalErrorPos(), 90H, 'FarHeapAllocate : Out Of Space');
  89. ELSE
  90. A := FarNIL;
  91. RETURN;
  92. END;
  93. END;
  94. IF res^.size = Size THEN (* block correct size *)
  95. prev^.next := res^.next;
  96. ELSE (* split block, bottom half returned, top half linked to free chain *)
  97. split := [CARDINAL(Seg(res^))+Size:0];
  98. prev^.next := split;
  99. split^.next := res^.next;
  100. split^.size := res^.size - Size;
  101. END;
  102. (*%T _mthread *)
  103. Process.Unlock;
  104. (*%E *)
  105. A := FarADR(res^);
  106. END FarHeapAllocate;
  107. PROCEDURE FarHeapAvail(Source: FarHeapRecPtr) : CARDINAL;
  108. (* returns the largest block size available for allocation in paragraphs *)
  109. VAR
  110. size : CARDINAL;
  111. p : FarHeapRecPtr;
  112. BEGIN
  113. IF Source = MainHeap THEN
  114. size := CARDINAL(CoreMem._fblockavail() DIV 16);
  115. IF size # 0 THEN
  116. DEC(size);
  117. END;
  118. RETURN size;
  119. END;
  120. (*%T _mthread *)
  121. Process.Lock;
  122. (*%E *)
  123. p := Source^.next;
  124. size := 0;
  125. WHILE p^.size <> EndMarker DO
  126. IF p^.size>size THEN size := p^.size END;
  127. p := p^.next;
  128. END;
  129. (*%T _mthread *)
  130. Process.Unlock;
  131. (*%E *)
  132. RETURN size;
  133. END FarHeapAvail;
  134. PROCEDURE FarHeapTotalAvail(Source: FarHeapRecPtr) : CARDINAL;
  135. (* returns the total block size available for allocation in paragraphs *)
  136. VAR
  137. size : CARDINAL;
  138. p : FarHeapRecPtr;
  139. BEGIN
  140. IF Source = MainHeap THEN
  141. RETURN CARDINAL(CoreMem.farcoreleft()>>4);
  142. END;
  143. (*%T _mthread *)
  144. Process.Lock;
  145. (*%E *)
  146. p := Source^.next;
  147. size := 0;
  148. WHILE p^.size <> EndMarker DO
  149. INC(size,p^.size);
  150. p := p^.next;
  151. END;
  152. (*%T _mthread *)
  153. Process.Unlock;
  154. (*%E *)
  155. RETURN size;
  156. END FarHeapTotalAvail;
  157. PROCEDURE FarHeapDeallocate(Source : FarHeapRecPtr; (* source heap *)
  158. VAR A: FarADDRESS;
  159. Size : CARDINAL ); (* size of block
  160. in paragraphs *)
  161. VAR
  162. target,prev,split : FarHeapRecPtr;
  163. tseg : CARDINAL;
  164. BEGIN
  165. IF Source = MainHeap THEN
  166. CoreMem._ffree(A);
  167. RETURN;
  168. END;
  169. IF (CARDINAL(Seg(A^))=0)OR(CARDINAL(Ofs(A^))<>0) THEN
  170. Lib.RunTimeError(CoreSig._FatalErrorPos(), 91H, 'FarHeapDeallocate : Invalid Argument');
  171. END;
  172. (*%T _mthread *)
  173. Process.Lock;
  174. (*%E *)
  175. IF Size=0 THEN INC(Size) END ;
  176. target := A;
  177. prev := Source;
  178. tseg := Seg(target^);
  179. WHILE CARDINAL(Seg(prev^.next^)) < tseg DO
  180. prev := prev^.next;
  181. END;
  182. IF CARDINAL(Seg(prev^))+prev^.size = tseg THEN (* amalgamate with prev *)
  183. prev^.size := prev^.size + Size;
  184. target := prev;
  185. ELSIF CARDINAL(Seg(prev^))+prev^.size > tseg THEN (* Heap corrupt *)
  186. SYSTEM.EI;
  187. Lib.RunTimeError(CoreSig._FatalErrorPos(), 92H, 'FarHeapDeallocate : Heap Corrupt');
  188. ELSE
  189. (* link after prev *)
  190. target^.next := prev^.next;
  191. prev^.next := target;
  192. target^.size := Size;
  193. END;
  194. IF (target^.next^.size <> EndMarker)
  195. AND (CARDINAL(Seg(target^.next^)) = CARDINAL(Seg(target^))+target^.size) THEN
  196. (* amalgamate with next block *)
  197. target^.size := target^.size+target^.next^.size;
  198. target^.next := target^.next^.next;
  199. END;
  200. A := SYSTEM.FarNIL;
  201. (*%T _mthread *)
  202. Process.Unlock;
  203. (*%E *)
  204. END FarHeapDeallocate;
  205. PROCEDURE FarHeapChangeAlloc(Source : FarHeapRecPtr; (* source heap *)
  206. A : FarADDRESS; (* block to change *)
  207. OldSize, (* old size of block *)
  208. NewSize : CARDINAL) (* new size of block *)
  209. (* in paragraphs *)
  210. : BOOLEAN; (* if sucessful *)
  211. (* This procedure attempts to change the size of an allocated block
  212. It returns TRUE if succeeded (only expansion can fail)
  213. *)
  214. VAR
  215. target,prev,
  216. split : FarHeapRecPtr;
  217. tseg : CARDINAL;
  218. result : BOOLEAN;
  219. extendsize : CARDINAL;
  220. Res : FarADDRESS;
  221. BEGIN
  222. IF Source = MainHeap THEN
  223. Res := CoreMem.hrealloc(A, LONGCARD(NewSize)<<4);
  224. IF Res = SYSTEM.FarNIL THEN
  225. RETURN FALSE;
  226. ELSE
  227. A := Res;
  228. RETURN TRUE;
  229. END;
  230. END;
  231. IF (CARDINAL(Seg(A^))=0)OR(CARDINAL(Ofs(A^))<>0) THEN
  232. Lib.RunTimeError(CoreSig._FatalErrorPos(), 93H, 'FarHeapChangeAlloc : Invalid Argument');
  233. END;
  234. IF OldSize = NewSize THEN RETURN TRUE END;
  235. IF OldSize > NewSize THEN
  236. target := [CARDINAL(Seg(A^))+NewSize:0];
  237. FarHeapDeallocate(Source,target,OldSize-NewSize);
  238. RETURN TRUE;
  239. END;
  240. extendsize := NewSize-OldSize;
  241. (*%T _mthread *)
  242. Process.Lock;
  243. (*%E *)
  244. target := A;
  245. prev := Source;
  246. tseg := Seg(target^);
  247. WHILE CARDINAL(Seg(prev^.next^)) < tseg DO
  248. prev := prev^.next;
  249. END;
  250. IF (prev^.next^.size <> EndMarker) AND
  251. (CARDINAL(Seg(prev^.next^)) = CARDINAL(Seg(target^))+OldSize) AND
  252. (extendsize <= prev^.next^.size) THEN
  253. IF (extendsize = prev^.next^.size) THEN
  254. prev^.next := prev^.next^.next
  255. ELSE
  256. split := [CARDINAL(Seg(target^))+NewSize:0];
  257. split^.next := prev^.next^.next;
  258. split^.size := prev^.next^.size - extendsize;
  259. prev^.next := split;
  260. END;
  261. result := TRUE;
  262. ELSE
  263. result := FALSE;
  264. END;
  265. (*%T _mthread *)
  266. Process.Unlock;
  267. (*%E *)
  268. RETURN result;
  269. END FarHeapChangeAlloc;
  270. PROCEDURE FarHeapChangeSize(Source : FarHeapRecPtr; (* source heap *)
  271. VAR A : FarADDRESS; (* block to change *)
  272. OldSize, (* old size of block *)
  273. NewSize : CARDINAL ); (* new size of block
  274. in paragraphs *)
  275. (*
  276. This procedure will change the size of an allocated block
  277. avoiding any copy of data if possible
  278. calls HeapChangeAlloc
  279. *)
  280. VAR
  281. na : FarADDRESS;
  282. BEGIN
  283. IF NOT FarHeapChangeAlloc ( Source, A, OldSize, NewSize ) THEN
  284. FarHeapAllocate(Source,na,NewSize);
  285. IF na # FarNIL THEN
  286. Lib.FarWordMove(A, na, OldSize*8);
  287. FarHeapDeallocate(Source,A,OldSize);
  288. END;
  289. A := na;
  290. END;
  291. END FarHeapChangeSize;
  292. PROCEDURE FarAllocate(VAR a: FarADDRESS; size: CARDINAL);
  293. VAR
  294. Res: FarADDRESS;
  295. BEGIN
  296. IF size = 0 THEN size := 2 END;
  297. IF ClearOnAllocate THEN
  298. Res := CoreMem._fcalloc(1, size);
  299. ELSE
  300. Res := CoreMem._fmalloc(size);
  301. END;
  302. IF Res = FarNIL THEN
  303. IF Check THEN
  304. Lib.RunTimeError(CoreSig._FatalErrorPos(), 94H, 'FarAllocate : Out Of Memory');
  305. END;
  306. END;
  307. a := Res;
  308. END FarAllocate;
  309. PROCEDURE FarDeallocate(VAR a: FarADDRESS; size: CARDINAL);
  310. BEGIN
  311. CoreMem._ffree(a);
  312. a:= SYSTEM.FarNIL;
  313. END FarDeallocate;
  314. PROCEDURE FarAvailable(size: CARDINAL) : BOOLEAN;
  315. VAR
  316. ps, rs: LONGCARD;
  317. BEGIN
  318. (*%T _DLLOVL*)
  319. RETURN TRUE; (* Overlay loader takes resposibility *)
  320. (*%E*)
  321. (*%F _DLLOVL*)
  322. ps := CoreMem._fblockavail();
  323. rs := LONGCARD(size+2);
  324. RETURN ps >= rs;
  325. (*%E*)
  326. END FarAvailable;
  327. PROCEDURE NearMakeHeap(Source: NearADDRESS; Size: CARDINAL): NearHeapRecPtr;
  328. (* ========== *)
  329. VAR Storage, FirstFree: NearHeapRecPtr;
  330. BEGIN
  331. Size := (Size DIV Align) * Align;
  332. IF Size < Align*3 THEN
  333. Lib.RunTimeError(CoreSig._FatalErrorPos(), 95H, 'NearMakeHeap: Size Too Small');
  334. END;
  335. IF Source = SYSTEM.NearNIL THEN
  336. Lib.RunTimeError(CoreSig._FatalErrorPos(), 89H, 'NearMakeHeap: Invalid Argument');
  337. END;
  338. Storage := NearHeapRecPtr(Source);
  339. FirstFree := NearHeapRecPtr(CARDINAL(Source)+CARDINAL(Align));
  340. Storage^.size := Size;
  341. Storage^.next := FirstFree;
  342. FirstFree^.size := Size - Align;
  343. FirstFree^.next := SYSTEM.NearNIL;
  344. RETURN Storage;
  345. END NearMakeHeap;
  346. PROCEDURE NearHeapAllocate(Source: NearHeapRecPtr; VAR A: NearADDRESS; Size: CARDINAL);
  347. (* ======== *)
  348. VAR Base, Free, New: NearHeapRecPtr;
  349. BEGIN
  350. IF Source = SYSTEM.NearNIL THEN
  351. Lib.RunTimeError(CoreSig._FatalErrorPos(), 8AH, 'NearHeapAllocate: Invalid Argument');
  352. END;
  353. IF Source = NearHeap THEN
  354. NearAllocate(A, Size);
  355. RETURN;
  356. END;
  357. IF Size < Align THEN
  358. Size := Align;
  359. ELSE
  360. Size := ( (Size+Align-1) DIV Align) * Align;
  361. IF Size = 0 THEN
  362. Size:=MAX(CARDINAL);
  363. END;
  364. END;
  365. Base := Source;
  366. LOOP
  367. Free := Base^.next;
  368. IF Free = SYSTEM.NearNIL THEN
  369. IF Check THEN
  370. Lib.RunTimeError(CoreSig._FatalErrorPos(), 96H, 'NearHeapAllocate: Out Of Memory');
  371. END;
  372. A := SYSTEM.NearNIL;
  373. RETURN;
  374. ELSIF Free^.size >= Size THEN
  375. EXIT;
  376. END;
  377. Base := Free;
  378. END;
  379. IF Free^.size = Size THEN
  380. Base^.next := Free^.next;
  381. ELSE
  382. New := NearHeapRecPtr(CARDINAL(Free)+Size);
  383. Base^.next := New;
  384. New^.size := Free^.size - Size;
  385. New^.next := Free^.next;
  386. END;
  387. IF ClearOnAllocate THEN
  388. Lib.WordFill ( ADR(Free^) , Size DIV 2 , 0 );
  389. END;
  390. A := NearADDRESS(Free);
  391. END NearHeapAllocate;
  392. PROCEDURE NearHeapDeallocate(Source: NearHeapRecPtr; VAR A: NearADDRESS; Size: CARDINAL );
  393. VAR
  394. Curr, Base, Free: NearHeapRecPtr;
  395. BEGIN
  396. IF (Source = SYSTEM.NearNIL) OR (A = SYSTEM.NearNIL) THEN
  397. Lib.RunTimeError(CoreSig._FatalErrorPos(), 8BH, 'NearHeapDeallocate: Invalid Argument');
  398. END;
  399. IF Source = NearHeap THEN
  400. NearDeallocate(A, Size);
  401. RETURN;
  402. END;
  403. IF Size < Align THEN
  404. Size := Align;
  405. ELSE
  406. Size := ( (Size+Align-1) DIV Align) * Align;
  407. IF Size = 0 THEN
  408. Size:=MAX(CARDINAL);
  409. END;
  410. END;
  411. Curr := NearHeapRecPtr(A);
  412. A := SYSTEM.NearNIL;
  413. Base:=Source;
  414. LOOP
  415. Free := Base^.next;
  416. IF (Free = SYSTEM.NearNIL) OR (CARDINAL(Curr) < CARDINAL(Free)) THEN EXIT; END;
  417. Base := Free;
  418. END;
  419. IF CARDINAL(Base) + Base^.size = CARDINAL(Curr) THEN
  420. INC ( Base^.size , Size );
  421. Curr := Base;
  422. ELSE
  423. Base^.next := Curr;
  424. Curr^.next := Free;
  425. Curr^.size := Size;
  426. END;
  427. IF (Free # SYSTEM.NearNIL) AND (CARDINAL(Curr) + Curr^.size = CARDINAL(Free)) THEN
  428. INC ( Curr^.size, Free^.size);
  429. Curr^.next := Free^.next;
  430. END;
  431. END NearHeapDeallocate;
  432. PROCEDURE NearHeapAvail(Source: NearHeapRecPtr): CARDINAL;
  433. VAR
  434. Curr: NearHeapRecPtr;
  435. Size, av: CARDINAL;
  436. BEGIN
  437. IF Source = SYSTEM.NearNIL THEN
  438. Lib.RunTimeError(CoreSig._FatalErrorPos(), 8CH, 'NearHeapAvail: Invalid Argument');
  439. END;
  440. IF Source = NearHeap THEN
  441. av := CoreMem._memmax();
  442. IF av <= 4 THEN
  443. av := 0;
  444. ELSE
  445. DEC(av, 4);
  446. END;
  447. RETURN av;
  448. END;
  449. Curr := Source^.next;
  450. Size := 0;
  451. WHILE Curr # SYSTEM.NearNIL DO
  452. IF Size < Curr^.size THEN
  453. Size := Curr^.size;
  454. END;
  455. Curr := Curr^.next;
  456. END;
  457. RETURN Size;
  458. END NearHeapAvail;
  459. PROCEDURE NearHeapTotalAvail(Source: NearHeapRecPtr): CARDINAL;
  460. VAR
  461. Curr: NearHeapRecPtr;
  462. Size: CARDINAL;
  463. BEGIN
  464. IF Source = SYSTEM.NearNIL THEN
  465. Lib.RunTimeError(CoreSig._FatalErrorPos(), 8DH, 'NearHeapTotalAvail: Invalid Argument');
  466. END;
  467. IF Source = NearHeap THEN
  468. RETURN CoreMem.nearcoreleft();
  469. END;
  470. Curr := Source^.next;
  471. Size := 0;
  472. WHILE Curr # SYSTEM.NearNIL DO
  473. INC ( Size , Curr^.size );
  474. Curr := Curr^.next;
  475. END;
  476. RETURN Size;
  477. END NearHeapTotalAvail;
  478. PROCEDURE Merge(LowRec, HighRec: NearHeapRecPtr);
  479. BEGIN
  480. IF (LowRec = SYSTEM.NearNIL) AND (HighRec = SYSTEM.NearNIL) AND
  481. (NearHeapRecPtr(CARDINAL(LowRec)+LowRec^.size) = HighRec) THEN
  482. LowRec^.next:=HighRec^.next;
  483. INC(LowRec^.size, HighRec^.size);
  484. END;
  485. END Merge;
  486. PROCEDURE NearHeapChangeSize(Source: NearHeapRecPtr; VAR A: NearADDRESS;
  487. OldSize, NewSize : CARDINAL);
  488. VAR
  489. OldA: NearADDRESS;
  490. BEGIN
  491. IF (Source = SYSTEM.NearNIL) OR (A = SYSTEM.NearNIL) THEN
  492. Lib.RunTimeError(CoreSig._FatalErrorPos(), 8EH, 'NearHeapChangeSize: Invalid Argument');
  493. END;
  494. IF NearHeapChangeAlloc(Source, A, OldSize, NewSize) THEN
  495. RETURN;
  496. END;
  497. OldA := A;
  498. NearHeapAllocate(Source, A, NewSize);
  499. IF A # NearNIL THEN
  500. Lib.WordMove(ADR(OldA^), ADR(A^), OldSize DIV 2);
  501. NearHeapDeallocate(Source, OldA, OldSize);
  502. END;
  503. END NearHeapChangeSize;
  504. PROCEDURE NearHeapChangeAlloc(Source: NearHeapRecPtr; A: NearADDRESS;
  505. OldSize, NewSize : CARDINAL): BOOLEAN;
  506. VAR
  507. Curr, SplitRec, NextRec, PrevRec, NewRec: NearHeapRecPtr;
  508. Temp: NearHeapRec;
  509. SplitSize: CARDINAL;
  510. T: NearADDRESS;
  511. BEGIN
  512. IF (Source = SYSTEM.NearNIL) OR (A = SYSTEM.NearNIL) THEN
  513. Lib.RunTimeError(CoreSig._FatalErrorPos(), 8FH, 'NearHeapChangeAlloc: Invalid Argument');
  514. END;
  515. IF Source = NearHeap THEN
  516. T := CoreMem._nexpand(A, NewSize);
  517. IF T # NearNIL THEN
  518. A := T;
  519. RETURN TRUE;
  520. ELSE
  521. RETURN FALSE;
  522. END;
  523. END;
  524. IF NewSize < Align THEN
  525. NewSize := Align;
  526. ELSE
  527. NewSize := ( (NewSize+Align-1) DIV Align) * Align;
  528. IF NewSize = 0 THEN
  529. NewSize:=MAX(CARDINAL);
  530. END;
  531. END;
  532. IF OldSize < Align THEN
  533. OldSize := Align;
  534. ELSE
  535. OldSize := ( (OldSize+Align-1) DIV Align) * Align;
  536. IF OldSize = 0 THEN
  537. OldSize:=MAX(CARDINAL);
  538. END;
  539. END;
  540. IF OldSize = NewSize THEN RETURN TRUE END;
  541. Curr:=NearHeapRecPtr(A);
  542. NextRec:=Source;
  543. LOOP
  544. PrevRec:=NextRec;
  545. NextRec:=NextRec^.next;
  546. IF (NextRec = SYSTEM.NearNIL) OR (CARDINAL(NextRec) > CARDINAL(Curr)) THEN EXIT END;
  547. END;
  548. IF OldSize > NewSize THEN
  549. SplitSize:=OldSize-NewSize;
  550. SplitRec:=NearHeapRecPtr(CARDINAL(Curr)+NewSize);
  551. SplitRec^.size:=SplitSize;
  552. SplitRec^.next:=NextRec;
  553. PrevRec^.next:=SplitRec;
  554. Merge(SplitRec, NextRec);
  555. RETURN TRUE;
  556. END;
  557. IF (NextRec # SYSTEM.NearNIL) AND (NearHeapRecPtr(CARDINAL(Curr)+OldSize) = NextRec) THEN (* Next Block is free *)
  558. Temp.size := OldSize+NextRec^.size;
  559. Temp.next := NextRec^.next;
  560. IF Temp.size = NewSize THEN
  561. PrevRec^.next := Temp.next;
  562. ELSE
  563. NewRec := NearHeapRecPtr(CARDINAL(Curr)+NewSize);
  564. PrevRec^.next := NewRec;
  565. NewRec^.size := Temp.size-NewSize;
  566. NewRec^.next := Temp.next;
  567. END;
  568. RETURN TRUE;
  569. ELSE
  570. RETURN FALSE;
  571. END;
  572. END NearHeapChangeAlloc;
  573. (*%F _DLL *)
  574. PROCEDURE NearDeallocate(VAR a: NearADDRESS; size: CARDINAL);
  575. BEGIN
  576. CoreMem._nfree(a);
  577. a:= NearADDRESS(NIL);
  578. END NearDeallocate;
  579. PROCEDURE NearAllocate(VAR a: NearADDRESS; size: CARDINAL);
  580. VAR
  581. Res: NearADDRESS;
  582. BEGIN
  583. IF size = 0 THEN size := 2 END;
  584. IF ClearOnAllocate THEN
  585. Res := CoreMem._ncalloc(1, size);
  586. ELSE
  587. Res := CoreMem._nmalloc(size);
  588. END;
  589. IF Res = NearNIL THEN
  590. IF Check THEN
  591. Lib.RunTimeError(CoreSig._FatalErrorPos(), 98H, 'NearAllocate: Out Of Memory');
  592. END;
  593. END;
  594. a := Res;
  595. END NearAllocate;
  596. PROCEDURE NearAvailable(size: CARDINAL) : BOOLEAN;
  597. VAR
  598. ps : CARDINAL;
  599. BEGIN
  600. ps := CoreMem._memmax();
  601. RETURN ps >= (size+4);
  602. END NearAvailable;
  603. (*%E *)
  604. (*%T _DLL *)
  605. PROCEDURE NearAllocate(VAR a: NearADDRESS; size: CARDINAL);
  606. BEGIN
  607. a := NearNIL;
  608. END NearAllocate;
  609. PROCEDURE NearDeallocate(VAR a: NearADDRESS; size: CARDINAL);
  610. BEGIN
  611. END NearDeallocate;
  612. PROCEDURE NearAvailable(size: CARDINAL) : BOOLEAN;
  613. BEGIN
  614. RETURN FALSE;
  615. END NearAvailable;
  616. (*%E *)
  617. PROCEDURE SegAllocate(Size: CARDINAL): CARDINAL;
  618. BEGIN
  619. RETURN Seg(CoreMem.halloc(LONGCARD(Size))^);
  620. END SegAllocate;
  621. PROCEDURE SegDeallocate(Sel: CARDINAL; Size: CARDINAL);
  622. VAR
  623. S: FarADDRESS;
  624. BEGIN
  625. S := [Sel: 0];
  626. CoreMem.hfree(S);
  627. END SegDeallocate;
  628. BEGIN
  629. NearHeap := NearHeapRecPtr(0FFFFH);
  630. MainHeap := FarHeapRecPtr(CoreMain._getheapbase());
  631. Check := TRUE;
  632. ClearOnAllocate := FALSE;
  633. END Storage.
  634.