#include #include #include // starter file for 308 assignment 6 // this code written by fredm // **************** variables for parsing command line **************** int pool; // size of pool char *policy; // "first", "best", or "buddy" char *fname; // name of command file to open FILE *f; // command file // **************** variables for parsing command file **************** int reqnum; // serial number of request int op; // operation type #define ALLOC 1 #define ALLOCSTR "alloc" #define FREE 2 #define FREESTR "free" int size; // alloc amount or free's request number // **************** allocation data structs **************** typedef struct memmgr_node MM_NODE; struct memmgr_node { int reqnum; // serial number of request for later free op's int addr; // assigned address int size; // size of assigned block MM_NODE *next; }; MM_NODE *master; // master list of allocated blocks int main(int argc, char **argv[]) { master = NULL; // init it to null parse_args(argc, argv); // read command line args parse_command_file(); // do the work! } int parse_args(int argc, char **argv[]) { if (argc != 4) { printf("Usage: memmgr \n"); printf(" policy must be 'first', 'best', or 'buddy'\n"); printf(" poolsize is a positive integer (e.g., 1000000)\n"); printf(" request-file is name of file that has alloc/free info\n"); exit(1); } policy = (char *)argv[1]; if (!(!strcmp(policy, "buddy") || !strcmp(policy, "first") | !strcmp(policy, "best"))) { printf("policy '%s' is not supported; bye.\n", policy); exit(1); } printf("using policy %s\n", policy); sscanf((char *)argv[2], "%d", &pool); printf("pool size will be %d\n", pool); // now have to open file fname = (char *)argv[3]; if ((f = fopen(fname, "r")) == NULL) { printf("Whoopsie, can't open '%s' for reading; bye.\n", fname); exit(1); } else { printf("Opened command file '%s'.\n", fname); } } int parse_command_file() { char line[100]; // hope that there are 99 chars or fewer per line char command[6]; // should be only 'alloc' or 'free' while (fgets(line, 100, f) != NULL) { printf("%s", line); sscanf(line, "%d%s%d", &reqnum, command, &size); if (!strcmp(command, ALLOCSTR)) op = ALLOC; else if (!strcmp(command, FREESTR)) op = FREE; else { printf("Don't understand request '%s'; bye!\n", command); exit(1); } // OKAY! // now you can fulfill request, stored in global vars // reqnum, op, and size ! // also, don't forget you have to implement 3 different policies! // if it's an alloc, then reqnum should be stored, and size // has amount of memory needed if (op == ALLOC) printf("got ALLOC request with reqnum %d and size %d\n", reqnum, size); // if it's a free, then size has the index to the prev reqnum if (op == FREE) printf("got FREE request on previous request numbered %d\n", size); if (!strcmp(policy, "first")) malloc_using_first(); else if (!strcmp(policy, "best")) malloc_using_best(); else if (!strcmp(policy, "buddy")) malloc_using_buddy(); else { printf("Whoa horsies! Unsupported policy '%s' got thru command line check! Buh-bye!\n", policy); exit(1); } } } int malloc_using_first() { MM_NODE *node, *pnode; int found; if (op == ALLOC) { // do allocate operation // create new node to maintain allocate data node = malloc(sizeof (MM_NODE)); node->reqnum = reqnum; node->size = size; // now figure out where it's going in list if (master == NULL) { // make sure this single alloc isn't bigger than our pool. if (size > pool) { printf("*** ALLOCATE ERROR: out of memory! reqnum=%d size=%d\n", reqnum, size); exit(1); } // memory map is empty; allocate at address 0. node->addr = 0; // install at beginng/end of list (it's the only item) node->next = NULL; master = node; } else { // now we have to walk thru the list and find the first fit. } printf("reqnum %d for size %d allocated at addr %d.\n", reqnum, size, node->addr); } else if (op == FREE) { // do free operation // walk thru alloc list, look for the alloc req that matches, // and unlink it. if (master == NULL) { printf("FATAL ERROR: can't free when no memory has been allocated.\n"); printf("serialnum=%d reqnum=%d\n", reqnum, size); exit(1); } node = master; pnode = NULL; found = 0; while (node != NULL) { if (node->reqnum == size) { found = 1; // remove this node. break; } pnode = node; node = node->next; } if (found == 0) { printf("FATAL ERROR: request %d not previously allocated.\n", size); exit(1); } // remove node. // suppose it's the first in the list, then pnode == NULL. if (pnode == NULL) { // remove first node by making master pointer point at its next node. master = node->next; } else { // unlink by making pnode point to node's next. // still works if node is the last one. pnode->next = node->next; } printf("freed up request %d for %d bytes!\n", size, node->size); free(node); } else { printf("error in malloc_using_first; bye.\n"); exit(1); } } int malloc_using_best() { printf("first: reqnum=%d\n", reqnum); } int malloc_using_buddy() { printf("first: reqnum=%d\n", reqnum); }