-1

I currently have this program that I have working. It works when I input values from the keyboard, but now I am trying to make it work by reading data from the file and make it execute depending on the data from the file. Here is the data from the file...

1
65536
1027
16
1
65536
1024
4096
1
65536
1024
16
3
65535
14
2
65535
3
65534
512
2
1023
4

Here is where I scan the file and store the inputs.

//Declare and initialize variables.
int  option = 0;
int  mainMemSize = 65536;
int  cacheSize = 1024;
int  blockSize = 16;
int  tags = mainMemSize / cacheSize;
int  *mainMemPtr = NULL;
line *cachePtr = NULL;
FILE *filePtr;

//Initialize the memory.
mainMemPtr = initMainMemory(mainMemSize);
cachePtr = initCache(cacheSize);

filePtr = fopen("prog2_test_data.txt", "r");

printf("*** Starting to read data from file: prog2_data_test.txt");
fscanf(filePtr, "%d", &option);

do
{
    showMenu();

    switch (option)
    {
        case 1:
            freeCache(&cachePtr, tags);
            free(mainMemPtr);
            setParameters(mainMemSize, cacheSize, blockSize);
            tags = mainMemSize / cacheSize;
            mainMemPtr = initMainMemory(mainMemSize);
            cachePtr = initCache(cacheSize);
            break;

        case 2:
            readCache(mainMemPtr, cachePtr, mainMemSize, blockSize, cacheSize);
            break;

        case 3:
            writeCache(mainMemPtr, cachePtr, mainMemSize, blockSize, cacheSize);
            break;

        case 4:
            break;
    }

}while (option != 4);

if (cachePtr != NULL)
    freeCache(&cachePtr, tags);

if (mainMemPtr != NULL)
    free(mainMemPtr);

fclose(filePtr);
printf("***Memory Freed Up - Program Terminated");
getchar();
}
void setParameters(int mainMemSize, int cacheSize, int blockSize)
{
if (blockSize > cacheSize) 
{
    printf("*** Error – Block size is larger than cache size\n");
}
else if ((cacheSize % blockSize) != 0) 
{
    printf("*** Error – Cache size is not a power of 2\n");
}
else if ((blockSize % 2 == 0) && (cacheSize % 2 == 0)) 
{
    printf("***Data Accepted \n");
}
}

void showMenu()
{
printf("\nMain memory to Cache memory mapping: \n");
printf("------------------------------------ \n");
printf("1) Enter Configuration Parameters\n");
printf("2) Read from cache\n");
printf("3) Write to cache\n");
printf("4) End\n");
}

int* initMainMemory(int size)
{

int j;

//initialize main memory.
int* ptr = (int*)malloc(size * sizeof(int));

for (j = 0; j < size; ++j)
    *(ptr + j) = size - j;

return ptr;
}

line* initCache(int tags)
{
int j;
line* ptr = (line*)malloc(tags * sizeof(line));


for (j = 0; j < tags; ++j)
{
    ptr[j].tag = -1;
    ptr[j].block = NULL;
}

return ptr;
} 

void freeCache(line **ptr, int size)
{
int j = 0;

for (; j < size; ++j)
{
    if ((*ptr)[j].block != NULL)
        free((*ptr)[j].block);
}
free(*ptr);
}

void readCache(int* mainMemPtr, line* cachePtr, int mmSize, int blockSize, 
int cacheSize)
{

//Declare and initialize variables.
int address = 0;
int value = 0;
int tag;
int myBlock;
int word;
int j;
int baseOffset;
int alreadyMissed = 0;

address = mmSize;

//Compute.
baseOffset = (address / blockSize) * blockSize;
tag = address / cacheSize;
word = address % blockSize;
myBlock = (address % cacheSize) / blockSize;

//Check if tag does not match or not.
if (cachePtr[myBlock].tag != tag)
{

    //Display this.
    printf("***Cache hit\n");
    alreadyMissed = 1;
    cachePtr[myBlock].tag = tag;
}

//Check if cache block memory is equal to NULL or not.
if (cachePtr[myBlock].block == NULL)
{

    //Condition check.
    if (alreadyMissed == 0)
        printf("***Cache hit\n");

    //Block Allocation.
    cachePtr[myBlock].block = (int*)malloc(blockSize * sizeof(int));
}

//Read from the main memory
for (j = 0; j < blockSize; ++j)
{
    cachePtr[myBlock].block[j] = mainMemPtr[baseOffset + j];
}

printf("Word %d of block %d with tag %d have %d\n", word, myBlock, tag, 
cachePtr[myBlock].block[word]);
}

void writeCache(int* mainMemPtr, line* cachePtr, int mmSize, int 
blockSize, int cacheSize)
{

//Declare and initialize variables.
int address = 0;
int value = 0;
int tag;
int myBlock;
int word;
int j;
int baseOffset;
int alreadyMissed = 0;


address = mmSize;

//Compute.
baseOffset = (address / blockSize) * blockSize;
tag = address / cacheSize;
word = address % blockSize;
myBlock = (address % cacheSize) / blockSize;

//Assign new value.
mainMemPtr[address] = value;

//Check if tag does not match or not.
if (cachePtr[myBlock].tag != tag)
{
    printf("***Write miss - First Load block from memory\n");
    alreadyMissed = 1;
    cachePtr[myBlock].tag = tag;
}

//Check if cache block memory is equal to NULL or not.
if (cachePtr[myBlock].block == NULL)
{
    if (alreadyMissed == 0)
        printf("Write miss!\n");

    //Block Allocation.
    cachePtr[myBlock].block = (int*)malloc(blockSize * sizeof(int));
}

//Transfer from the main memory to the cache.
for (j = 0; j < blockSize; ++j)
    cachePtr[myBlock].block[j] = mainMemPtr[baseOffset + j];


printf("***Word %d of block %d with tag %d have %d\n", word, myBlock, tag, 
cachePtr[myBlock].block[word]);
}

This should be the desire output after the program starts debugging.

*** Starting to Read Data from the input file: prg2_data.txt


*** Error - Cache Size is not a Power of 2! Returning to Main Menu


*** Error - Block Size is Larger than Cache Size! Returning to Main Menu


*** All Input Parameters Accepted. Starting to Process Write/Read Requests


* Write Miss... First load Block from Memory! * Word 15 of Cache Line 63 with Tag 63 contains Value 14


* Cache Hit * Word 15 of Cache Line 63 with Tag 63 contains Value 14


* Cache Hit * Word 14 of Cache Line 63 with Tag 63 contains Value 512


* Read Miss... Load Block from Memory! * Word 15 of Cache Line 63 with Tag 0 contains Value 64513


*** Memory Freed Up - Program Terminated Normally

What happens instead is an infinite loop. I can't seem to spot the problem.Can someone please help me out.

Cœur
  • 37,241
  • 25
  • 195
  • 267
S1ayer
  • 1
  • 1
  • 4
    [Why is “while ( !feof (file) )” always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong/26557243) –  Oct 28 '18 at 03:38
  • 1
    Please post a minimal, **complete**, and verifiable example (i.e., enough of your code that we can actually compile and run it without having to add things). – Joseph Sible-Reinstate Monica Oct 28 '18 at 03:39
  • while(!eof(file)) is another piece of code I saw online to get data line by line from a file. – S1ayer Oct 28 '18 at 03:45
  • Well, if I add all my code then stackOverflow will complain that I only provide the minimal code, but if you suggest to post more code so you can compile it and test it yourself then ok. – S1ayer Oct 28 '18 at 03:45
  • 1
    @S1ayer "code I saw online" You should never use others code without understanding what it does. [Cargo cult programming](https://en.wikipedia.org/wiki/Cargo_cult_programming). –  Oct 28 '18 at 03:48
  • Another good tip. Write your code in small sections you can validate and then incorporate the validated parts into your code. Don't complicate troubleshooting by including the program interface, repetitive menus, etc.. For example, just write the 10 or so lines required to read from your file and verify it is working properly before adding it to your full program. You get the idea. – David C. Rankin Oct 28 '18 at 04:35
  • So, I decided to remove all my fscanf() and instead of a switch statement I used an if else statements. I put a breakpoint and walked through the debugger and finally say how and where I should put my fscanf(). Thank you all for the advice. – S1ayer Oct 28 '18 at 18:11

1 Answers1

0
while (!eof(filePtr))
    fscanf(filePtr, "%d %d %d %d", &option, &mainMemSize, &cacheSize, &blockSize);

There are two things wrong here:

  1. The eof function doesn't predict the future. You can't use it to predict that a future read will fail and thereby avoid that read. Instead, check if the read actually succeeded or failed and, if it failed, stop.

  2. This repeats the fscanf operation over and over, each time overwriting the previous results. You don't want to call fscanf again after it returns, so the loop should not be here.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • So, I decided to remove all my fscanf() and instead of a switch statement I used an if else statements. I put a breakpoint and walked through the debugger and finally say how and where I should put my fscanf(). Thank you for the advice. – S1ayer Oct 28 '18 at 18:12