Search code examples
cmemorymemory-managementmkfifo

Trying to display a "map" of allocated memory in a simulated OS memory manager


Multiple clients are sending the name of their job and their memory request to the server. The server is acting as a memory manager and allocating memory for as many clients as possible using paging as its memory allocation scheme. I am using FIFO's for client-server communication.

The problem I am having is after all clients have been processed, I would like to display a map of the allocated memory on the server-side. In other words, I would like to show what frames have been allocated to what client.

Below is part of my server application. I have also attached some output that may help understand the problem. Everything works as expected until the end of the program (where it prints out the frames assigned to each client; the last for loop on server.c). The clientsAllocation array is the array that holds each client's private FIFO name. I was trying to assign the index of the allocated frame (in allocatedFrames array) to be the client's privateFIFOName. I'm not sure why this isn't working. Thank you in advance for any help.

Any answer should be portable. I have to be able to run this code on a UNIX machine using the cygwin-gcc compiler. I am testing the code on Windows because it is my primary machine. I connect to a UNIX machine at my University using PuTTY every couple of code changes and make sure the code runs on there too.

server.c

...//include statements

#define FRAMESIZE 256
#define MAX_LENGTH_FIFO_NAME 16
#define MAX_LENGTH_JOB_NAME 32
#define MAX_LENGTH_MESSAGE 256

int main(void)
{
    int numOfClients = 0; //total number of clients this server will process
    int totalNumOfFrames = 0; //total number of frames in memory
    int frames = 0; //copy of numOfFrames used to allocate frames for client

    //Struct to recieve from client
    struct
    {
        char jobName[MAX_LENGTH_JOB_NAME];
        char privateFIFOName[MAX_LENGTH_FIFO_NAME];
        int memoryRequest;
    }input;

    //Struct to send to client containing the calculated frames and the fragmentation
    struct
    {
        char message[MAX_LENGTH_MESSAGE];
        int fragmentation;
        int totalNumOfFrames;
        int frameNumbers[totalNumOfFrames];
    }output;

    ... //getting input from user and doing error checking

    int allocatedFrames[totalNumOfFrames]; //an array of "flags" that will keep track whether a frame is allocated or not
    char* clientsAllocation[totalNumOfFrames]; //an array to keep track of what frames are allocated to what client

    memset(allocatedFrames, 0, sizeof(allocatedFrames)); //make sure all values in the array are set to 0 to prevent random values
    memset(clientsAllocation, 0, sizeof(clientsAllocation));

    int i = 0;
    int j = 0;

    for (i; i < numOfClients; i++)
    {
        if (input.memoryRequest >= FRAMESIZE && input.memoryRequest <= memoryLeft)
        {
            ...
            frames = 0;

            if (framesLeft >= numOfFrames)
            {
                j = 0;
                while (frames < numOfFrames)
                {
                    for (j; j < totalNumOfFrames; j++)
                    {
                        if (allocatedFrames[j] == 0) //if the value at j is 0, then this is an empty frame and can be allocated
                        {
                            allocatedFrames[j] = 1; //switch the value to 1 in both arrays
                            output.frameNumbers[j] = 1;
                            clientsAllocation[j] = input.privateFIFOName; //keep track of what frames this client was allocated
                            printf("%d: %s\n", j, clientsAllocation[j]);
                            printf("SERVER:> Frame Allocated: %d\n", j);
                            break; //breaks out of this 'for' loop which should only be run as many times as there are frames to be allocated
                        }
                    }
                    frames++; //increment the temporary frames variable to keep track of how many times to run the for loop
                }

                ... //calculations on framesLeft and memoryLeft
            }
            //if it is not a valid request, (i.e. requesting more frames than are available)
            else
            {
                ... //some error printing
            }
        }
        else if (...)... //range checking but the code is very similar to above
    }

    i = 0;
    for (i; i < totalNumOfFrames; i++)
    {
        printf("%d: %s\n", i, clientsAllocation[i]);
    }
    printf("\n\n");

    return 0;
}

Output


Solution

  • You are always assigning the same buffers address to the currently used entry of your array of client names.

    clientsAllocation[j] = input.privateFIFOName;
    

    You do so by giving the name/identifier of the array of char in your input struct.
    It is treated as a pointer to char and assigned to all used entries inside clientsAllocation.

    So at the end, when printing, all the pointers refer to the same array of char
    and you get a list of identical names, being the last one written to the buffer.

    To avoid that, you could malloc() some memory for each name and fill it with the current name via string copying.

    Of course, you should free those allocated memories at some point.
    For the simple demo program, freeing after printing seems appropriate.