English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. System (https://eab.abime.net/forumdisplay.php?f=113)
-   -   Temporary turning FAST memory off (https://eab.abime.net/showthread.php?t=93980)

dissident 29 August 2018 18:48

Temporary turning FAST memory off
 
Hi,

is there a way to turn off FAST memory so the system can't allocate it any more apart from this very common technique?

Code:

  CNOP 0,4
rd_turn_off_FAST_memory
  move.l  #MEMF_FAST+MEMF_LARGEST,d1 ;Get largest FAST-memory block
  jsr    -216(a6)                  ;AvailMem()
  tst.l  d0                        ;Still FAST memory ?
  beq.s  rd_no_more_FAST_memory    ;No -> skip
  move.l  #MEMF_FAST+MEMF_LARGEST,d1 ;Get largest FAST-memory block
  jsr    -198(a6)                  ;AllocMem()
  bra.s  rd_turn_off_FAST_memory    ;Loop
  CNOP 0,4
rd_no_more_FAST_memory
  rts

If I do it this way, it's a one-way street. The FAST memory is irreversible lost. I want a solution like NoFastMem of the WB 1.2/1.3 does. Switching FAST memory off and on again.

Does anyone know a smarter way in assembler?

alkis 29 August 2018 19:21

Start with an empty list
If list empty get all memory and store memory pointers to list
if list not empty, walk list & free all list memory pointers

Toni Wilen 29 August 2018 19:34

Even easier: store all address/size pairs in first (largest) allocated block.

dissident 29 August 2018 19:58

Quote:

Originally Posted by alkis (Post 1265150)
Start with an empty list
If list empty get all memory and store memory pointers to list
if list not empty, walk list & free all list memory pointers

Quote:

Originally Posted by Toni Wilen (Post 1265154)
Even easier: store all address/size pairs in first (largest) allocated block.

Thanks alkis&Toni. :) I will try this. I hope that the first largest memory block is large enough to save all address/size pairs.

PeterK 29 August 2018 21:32

Why not patching AllocMem() and AvailMem() and let them simply return zero to all FastMem requests?

Toni Wilen 29 August 2018 21:42

Quote:

Originally Posted by PeterK (Post 1265186)
Why not patching AllocMem() and AvailMem() and let them simply return zero to all FastMem requests?

OS internal memory allocations may bypass LVO calls and call internal functions directly and AllocMem() is not the only memory allocation function.

IMHO LVO patching should be only used if there is no other cleaner solution.

PeterK 29 August 2018 23:14

Ok, it depends on what you want to keep off from getting FastMem. And yes, of course, there are also Allocate(), AllocPooled(), AllocAbs() and AllocVec(). The latter calls AllocMem(). Don't know what the other functions are doing, whether they are based on AllocMem() too or not.

But I just had a short look into the disassembler listing of NoFastMem, which could be easily integrated into other programs. NoFastMem patches AvailMem() and AllocMem(), maybe in a little bit different way, but it's going into the same direction.

On the other side, when you are trying to allocate all available FastMem blocks you are never finished with that task, because at any time other programs may set their used blocks of FastMem free again, and then you will get into a race condition with those which want to allocate these new FastMem blocks.

meynaf 30 August 2018 09:28

Why not using NoFastMem itself ?
From within a program it should be easy to call Execute() or a similar function.
If it doesn't work on pre 2.0 then it can probably be adapted.

dissident 30 August 2018 09:29

Quote:

Originally Posted by PeterK (Post 1265227)
On the other side, when you are trying to allocate all available FastMem blocks you are never finished with that task, because at any time other programs may set their used blocks of FastMem free again, and then you will get into a race condition with those which want to allocate these new FastMem blocks.

Hi PeterK, the code below works fine. The loop allocates all FAST memory:

Code:

CNOP 0,4
turn_off_FAST_memory
  move.l  $4.w,a6                  ;Get Exec-Base
  move.l  #$20004,d1                ;Request: MEMF_FAST+MEMF_LARGEST
  move.l  d1,d2                    ;Save request
  jsr    -216(a6)                  ;AvailMem(): Get first largest FAST-memory block
  move.l  d0,-(a7)                  ;Save size
  move.l  d2,d1                    ;Request: MEMF_FAST+MEMF_LARGEST
  jsr    -198(a6)                  ;AllocMem(): Allocate first largest FAST-memory block
  move.l  d0,-(a7)                  ;Save pointer 2x
  move.l  d0,a2
turn_off_FAST_memory_loop
  move.l  d2,d1                    ;Request: MEMF_FAST+MEMF_LARGEST
  jsr    -216(a6)                  ;AvailMem(): Get largest FAST-memory block
  move.l  d0,(a2)+                  ;Save size
  beq.s  no_more_FAST_memory      ;If NULL -> skip
  move.l  d2,d1                    ;Request: MEMF_FAST+MEMF_LARGEST
  jsr    -198(a6)                  ;AllocMem(): Allocate largest FAST-memory block
  move.l  d0,(a2)+                  ;Save pointer
  bra.s  turn_off_FAST_memory_loop ;Loop
  CNOP 0,4
no_more_FAST_memory
  rts

...

  CNOP 0,4
turn_on_FAST_memory
  move.l  (a7)+,a2                  ;Get pointer to first largest block
  move.l  a2,a3                    ;Save it
turn_on_FAST_memory_loop
  move.l  (a2)+,d0                  ;Get size
  beq.s  free_first_block          ;If NULL -> skip
  move.l  (a2)+,a1                  ;Get pointer
  jsr      -210(a6)                ;FreeMem()
  bra.s  turn_on_FAST_memory_loop  ;Loop
  CNOP 0,4
free_first_block
  move.l  a3,a1                    ;Get pointer of first largest block
  move.l  (a7)+,d0                  ;Get size of first largest block
  jmp    -210(a6)                  ;FreeMem()

But you are right, there's one disadvantage regarding the multitasking environment. If a program was opened before my routine allocated all FAST-memory and is quit before I release my allocated FAST-memory, there will be available FAST memory again. Turing off the multitasking via Forbid() and Permit() maybe useful only in very special cases.

My idea is to patch the memory-list at the pointer Exec-Base->MemList. Just removing the node of FAST memory out of the memory list with Remove() and inserting it again with Insert(). But this could be dangerous, because it's a private structure and could mess everything up.

Toni Wilen 30 August 2018 09:37

Quote:

Originally Posted by PeterK (Post 1265227)
On the other side, when you are trying to allocate all available FastMem blocks you are never finished with that task, because at any time other programs may set their used blocks of FastMem free again, and then you will get into a race condition with those which want to allocate these new FastMem blocks.

Right, I forgot that problem.. There does not seem to be any nice and simple solutions.

Quote:

My idea is to patch the memory-list at the pointer Exec-Base->MemList. Just removing the node of FAST memory out of the memory list with Remove() and inserting it again with Insert(). But this could be dangerous, because it's a private structure and could mess everything up.
It should work until someone tries to free memory that was allocated from removed node.

dissident 30 August 2018 09:37

Quote:

Originally Posted by meynaf (Post 1265286)
Why not using NoFastMem itself ?
From within a program it should be easy to call Execute() or a similar function.
If it doesn't work on pre 2.0 then it can probably be adapted.

Hi meynaf, I've tested it on a WinUAE-68060 config. NoFastMem also works with KS 3.1.

Yes, using it via Execute() could be a solution, but then my program would require the pre OS2.0 NoFastMem in a OS 2.0+ environment.

dissident 30 August 2018 09:41

Quote:

Originally Posted by Toni Wilen (Post 1265289)
It should work until someone tries to free memory that was allocated from removed node.

Yes, I really had the same idea, so this can't be the solution. It's too complex and dangerous messing up this list.

Tomislav 30 August 2018 12:36

I think that some bootblocks can do that. Turn off memory and floppy drives. And some could switch PAL/NTSC.

meynaf 30 August 2018 14:43

Quote:

Originally Posted by dissident (Post 1265287)
My idea is to patch the memory-list at the pointer Exec-Base->MemList. Just removing the node of FAST memory out of the memory list with Remove() and inserting it again with Insert(). But this could be dangerous, because it's a private structure and could mess everything up.

Less dangerous than removing the entry, would be to set priority so that chipmem is allocated first. Then, no fast mem unless the system runs out of chip.
(But don't ask me how to do that, i've tried to change priority of the mem nodes and it didn't work :D).


Quote:

Originally Posted by dissident (Post 1265290)
Hi meynaf, I've tested it on a WinUAE-68060 config. NoFastMem also works with KS 3.1.

Yes, using it via Execute() could be a solution, but then my program would require the pre OS2.0 NoFastMem in a OS 2.0+ environment.

Normally in a 2.0+ environment, NoFastMem should be available somewhere, like sys:system/NoFastMem.

Then again, it all depends why you want to remove fastmem from the system.
What does your program do ? What is the final goal ?
Perhaps better solutions exist than just removing the fastmem.

Don_Adan 30 August 2018 14:57

Quote:

Originally Posted by meynaf (Post 1265366)
Less dangerous than removing the entry, would be to set priority so that chipmem is allocated first. Then, no fast mem unless the system runs out of chip.
(But don't ask me how to do that, i've tried to change priority of the mem nodes and it didn't work :D).



Normally in a 2.0+ environment, NoFastMem should be available somewhere, like sys:system/NoFastMem.

Then again, it all depends why you want to remove fastmem from the system.
What does your program do ? What is the final goal ?
Perhaps better solutions exist than just removing the fastmem.

Right, dependent what he want to do. If he want to load exe files to chip ram, he can modify hunks to load into chip ram. If he want to disable Alloc fast mem, he can alloc full Fast at begining and nothing will be loaded/allocated to fast mem.

alkis 30 August 2018 18:56

Quote:

Originally Posted by PeterK (Post 1265227)
But I just had a short look into the disassembler listing of NoFastMem, which could be easily integrated into other programs. NoFastMem patches AvailMem() and AllocMem(), maybe in a little bit different way, but it's going into the same direction.

This.

It patches AvailMem to never report the fast mem (which stays unallocated), and patches AllocMem to clear the bit of FAST_MEMORY and always return CHIP_MEMORY.

dissident 31 August 2018 08:13

Quote:

Originally Posted by Tomislav (Post 1265333)
I think that some bootblocks can do that. Turn off memory and floppy drives. And some could switch PAL/NTSC.

Yes, I know such bootblocks. Often you have a menu there to select PAL/NTSC mode or turn off FAST memory. I didn't check such a bootcode yet, but I guess FAST memory is turned off like the first code I posted. As this routine is called before any CLI window is opened and the bootroutine is a main routine, there can't be much other routines releasing their allocated FAST memory after FAST memory was turned off.

meynaf 31 August 2018 08:26

I fail to see any good use for that in a bootblock. :confused

If you're running your own code, it's a magnitude simpler to just pass the correct flags to allocmem calls in order to get chipmem.
And if it's not your own code that runs after, patching it shouldn't be that hard either.

dissident 31 August 2018 08:46

Quote:

Originally Posted by meynaf (Post 1265366)
Less dangerous than removing the entry, would be to set priority so that chipmem is allocated first. Then, no fast mem unless the system runs out of chip.
(But don't ask me how to do that, i've tried to change priority of the mem nodes and it didn't work :D).

Yes, I already had the same idea, changing the priority of the node. This could be done this way by the old tool SlowMemLast of WB 1.2. Or they also patched the AllocMem() function.


Quote:

Originally Posted by meynaf (Post 1265366)
Normally in a 2.0+ environment, NoFastMem should be available somewhere, like sys:system/NoFastMem.

Then again, it all depends why you want to remove fastmem from the system.
What does your program do ? What is the final goal ?
Perhaps better solutions exist than just removing the fastmem.

I've checked it. On the WB 3.0 disc NoFastMem is still in the system drawer. Funnily I didn't expect this and though didn't check it. :D

Sorry, that I didn't mention it. What I intended to do is loading executable files with LoadSeg(). These files should not be loaded into FAST memory, because it is most likely, they were coded on a machine without extra memory and the coder didn't expect there will be such like in old intros/demos. So FAST memory must be turned off before. After some system modifications, the code of the file is executed. But if any error occurs during my modifications or the file can't be loaded, I have to free the allocated FAST memory and exit my program.
To my mind, I already have a solution that is not too complicated with the second code I have posted.

dissident 31 August 2018 08:57

Quote:

Originally Posted by Don_Adan (Post 1265370)
Right, dependent what he want to do. If he want to load exe files to chip ram, he can modify hunks to load into chip ram.

Yes, modifying the hunks could be a solution, but fails, if the exe file itself allocates memory not correctly and doesn't request CHIP memory in particular. To be honest, modifying hunks is not something I've done yet. :confused

Quote:

Originally Posted by Don_Adan (Post 1265370)
If he want to disable Alloc fast mem, he can alloc full Fast at begining and nothing will be loaded/allocated to fast mem.

Yes, you got it. That's exactly what I will do.


All times are GMT +2. The time now is 02:22.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.05294 seconds with 11 queries