From cee53f6d74bb3acd93974fe2f70afa5f469f6942 Mon Sep 17 00:00:00 2001
From: Kevin Bracey <kbracey@gitlab.riscosopen.org>
Date: Wed, 14 May 1997 12:40:00 +0000
Subject: [PATCH] Taught AMBControl about shrinkable dynamic areas

---
 s/AMBControl/growp | 52 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 51 insertions(+), 1 deletion(-)

diff --git a/s/AMBControl/growp b/s/AMBControl/growp
index 0453acd2..88126db7 100644
--- a/s/AMBControl/growp
+++ b/s/AMBControl/growp
@@ -24,7 +24,7 @@
 ;
 ; exit: -
 
-growpages
+growpages ROUT
         Push    "R0-R7,LR"
 
         MOV     R6,R1                      ;save entry R1
@@ -42,6 +42,9 @@ growpages
         LDR     R4,[R1,#DANode_Size]
         MOV     R4,R4,LSR #Log2PageSize    ;no. of pages in FreePool
         CMP     R3,R4
+  [ ShrinkableDAs
+        BLGT    growp_TryToShrinkShrinkables
+  ]
         MOVGT   R3,R4                      ;R3 := no. of pages we will move
         CMP     R3,#0
         BEQ     %FT02                      ;done if can't move any pages
@@ -81,4 +84,51 @@ growpages
         STRVS   R0,[SP]
         Pull    "R0-R7,PC"
 
+  [ ShrinkableDAs
+;
+; growp_TryToShrinkShrinkables - try to shrink shrinkable DAs, to grow free pool
+;
+; entry:
+;   R1 -> FreePool DANode
+;   R3 = no. of pages required in FreePool
+;   R4 = no. of pages in FreePool (must be less than R3)
+;
+; exit:
+;   R4 = new no. of pages in FreePool
+;   condition code GT is true if still less than required (ie. R3 > R4 on exit)
+;
+growp_TryToShrinkShrinkables ROUT
+        Push    "R0-R2,R11,R12,LR"
+
+        MOV     R11,R1                          ; -> FreePool DANode
+        MOV     R1,R3,LSL #Log2PageSize         ;amount we need in FreePool
+        MOV     R2,R4,LSL #Log2PageSize         ;amount we have in FreePool
+        MOV     R10,#DAList
+        ASSERT  DANode_Link = 0                 ;because DAList has only link
+10
+        LDR     R10,[R10,#DANode_Link]          ;and load next
+        CMP     R10,#1                          ;any more nodes?
+        BCC     %FT99
+        LDR     LR,[R10,#DANode_Flags]          ;check area is shrinkable
+        TST     LR,#DynAreaFlags_Shrinkable
+        BEQ     %BT10                           ;if not, try next area
+
+        SUBS    R1,R1,R2                        ;amount we still need
+        LDR     LR,[R10,#DANode_Size]           ;available size of this area
+        CMP     LR,R1
+        MOVCC   R1,LR                           ;min(amount we need, size of this area)
+        RSB     R1,R1,#0                        ;make negative - it's a shrink
+        LDR     R0,[R10,#DANode_Number]
+        SWI     XOS_ChangeDynamicArea           ;should not be currently threaded during AMBControl
+        MOV     R1,R3,LSL #Log2PageSize         ;original amount we need again
+        LDR     R2,[R11,#DANode_Size]           ;get new size of FreePool
+        CMP     R2,R1
+        BCC     %BT10                           ;if still too small, loop
+99
+        MOV     R4,R2,LSR #Log2PageSize         ;no. of pages now in FreePool
+        CMP     R3,R4
+        Pull    "R0-R2,R11,R12,PC"
+
+  ] ;ShrinkableDAs
+
     END
-- 
GitLab