/*
    Change priority of a selected memory block
    By Barry McConnell, bmccnnll@unix1.tcd.ie
    Public Domain - do what you like with it!
*/

#include <stdio.h>
#include <proto/exec.h>
#include <exec/execbase.h>
#include <exec/nodes.h>
#include <exec/memory.h>

extern struct ExecBase *SysBase;
struct MemHeader *chunk;
int count, block, pri;

int main(int argc, char *argv[])
{
printf("MemPri by Barry McConnell\n\nBlock     Address   Size      Free      Priority  Name\n");

for (chunk = (struct MemHeader *)(SysBase -> MemList.lh_Head), count = 0;  /* walk through memory list */
        chunk -> mh_Node.ln_Succ; chunk = (struct MemHeader *)(chunk -> mh_Node.ln_Succ), count++)
    printf("%-10d$%-9x%-10d%-10d%3d       %s\n", count, (int)(chunk -> mh_Lower) - sizeof(struct MemHeader),
            ((int)(chunk -> mh_Upper) - (int)(chunk -> mh_Lower) + sizeof(struct MemHeader)) / 1024,
            chunk -> mh_Free / 1024, chunk -> mh_Node.ln_Pri, chunk -> mh_Node.ln_Name);

if (argc == 3)  /* correct number of arguments */
    {
    block = pri = -999;  /* scanf won't change these if the user enters garbage */
    sscanf(argv[1], "%d", &block);  /* get first argument */
    sscanf(argv[2], "%d", &pri);  /* second argument */
    if ((block == -999) || (pri == -999))  /* both valid? */
        printf("\nIllegal argument\n");
    else
        if ((block < 0) || (block >= count) || (pri < -128) || (pri > 127))  /* too big or small? */
            printf("\nArgument out of range\n");
    else
        {
        Disable();  /* because we're going to do some really nasty stuff */
        for (chunk = (struct MemHeader *)(SysBase -> MemList.lh_Head), count = block; count;
                chunk = (struct MemHeader *)(chunk -> mh_Node.ln_Succ), count--)  /* find selected chunk */
            ;
        Remove((struct Node *)chunk);  /* temporarily remove it from the memory list */
        chunk -> mh_Node.ln_Pri = pri;  /* change its priority */
        Enqueue(&(SysBase -> MemList), (struct Node *)chunk);  /* put back in correct position */
        Enable();
        printf("\nChanged block %d to priority %d\n", block, pri);
        }
    }
else
    if (argc > 1)  /* user probably knows what he wants if he gave no arguments */
        printf("\nUsage: MemPri <block number> <new priority>\n");

return 0;
}
