From e282a861d5868868940b449681f2ee5da3e439e8 Mon Sep 17 00:00:00 2001 From: Ben Burwell Date: Wed, 1 Apr 2015 20:26:26 -0400 Subject: as of 2013-10-29 --- comhan.c | 422 +++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 329 insertions(+), 93 deletions(-) (limited to 'comhan.c') diff --git a/comhan.c b/comhan.c index 21a3448..7d02799 100644 --- a/comhan.c +++ b/comhan.c @@ -8,32 +8,48 @@ #include #include #include +#include #include "mpx.h" #define BUF_SIZE 80 /* Size of the command line buffer. */ -#define VERSION 0 -#define DATE 1 -#define DIRECTORY 2 -#define STOP 3 -#define HELP 4 -#define PROMPT 5 -#define ALIAS 6 -#define SHOW 7 -#define ALLOCATE 8 -#define CMD_FREE 9 +#define VERSION 0 +#define DATE 1 +#define DIRECTORY 2 +#define STOP 3 +#define HELP 4 +#define PROMPT 5 +#define ALIAS 6 +#define SHOW 7 +#define ALLOCATE 8 +#define CMD_FREE 9 +#define CMD_LOAD 10 +#define CMD_RESUME 11 +#define CMD_RUN 12 +#define CMD_SUSPEND 13 +#define CMD_TERMINATE 14 +#define CMD_SETPRI 15 +#define CMD_DISPATCH 16 + +#define NUM_CMDS 17 int length; /* Length of the command line. */ +unsigned sp_save; /* A stack save for mod 4 dispatch. */ char prompt[20] = "mpx>"; const char version[] = "MPX OS - Version 1.0\n"; char date[] = "01/09/1991"; -char *cmds[] = {"version", "date", "directory","stop","help", - "prompt", "alias", "show", "allocate", "free", NULL}; +char *cmds[] = { "version", "date", "directory", "stop", + "help", "prompt", "alias", "show", + "allocate", "free", "load", "resume", + "run", "suspend", "terminate", "setpriority", + "dispatch", NULL}; char *aliases[] = {" ", " ", " ", " ", " ", " ", " ", " ", - " ", " ", NULL}; + " ", " ", " ", " ", + " ", " ", " ", " ", + " ", NULL}; /* * comhan() This is the command handler for the MPX OS. @@ -47,8 +63,6 @@ char *aliases[] = {" ", " ", " ", " ", void comhan() { static char *args[7]; //one more than expected number of arguments - int argc; - int cmd_num; static char buffer[BUF_SIZE]; int do_stop = 0; @@ -57,19 +71,26 @@ void comhan() { length = BUF_SIZE; /* Reset length of buffer. */ sys_req(CON,READ,buffer,&length); /* Request CON input */ - argc = set_args(buffer, args); + set_args(buffer, args); - switch (cmd_num = get_cmd(args[0])) { + switch (get_cmd(args[0])) { case VERSION: cmd_version(); break; - case DATE: cmd_date(args); break; - case DIRECTORY: cmd_directory(); break; - case STOP: do_stop = cmd_stop(); break; - case HELP: cmd_help(args); break; - case PROMPT: cmd_prompt(args); break; - case ALIAS: cmd_alias(args); break; - case SHOW: cmd_show(args); break; - case ALLOCATE: cmd_allocate(args); break; - case CMD_FREE: cmd_free(args); break; + case DATE: cmd_date(args); break; + case DIRECTORY: cmd_directory(); break; + case STOP: do_stop = cmd_stop(); break; + case HELP: cmd_help(args); break; + case PROMPT: cmd_prompt(args); break; + case ALIAS: cmd_alias(args); break; + case SHOW: cmd_show(args); break; + case ALLOCATE: cmd_allocate(args); break; + case CMD_FREE: cmd_free(args); break; + case CMD_LOAD: cmd_load(args); break; + case CMD_RESUME: cmd_resume(args); break; + case CMD_RUN: cmd_run(args); break; + case CMD_SUSPEND: cmd_suspend(args); break; + case CMD_TERMINATE: cmd_terminate(args); break; + case CMD_SETPRI: cmd_setpri(args); break; + case CMD_DISPATCH: cmd_dispatch(); break; default: printf("Can't recognize.\n"); break; @@ -136,7 +157,6 @@ void cmd_date(char *args[]){ if (m > 0 && m < 13 && d > 0 && d < 32) { sprintf(date, "%d/%d/%d", m, d, y); - printf("Date set to %s \n", date); } else { printf("Invalid date. \n"); } @@ -156,7 +176,7 @@ void cmd_directory(){ if (no_proc > 0) { printf("Size Name \n"); - printf("===================================== \n"); + printf("========= =========================== \n"); } for (i = 0; i < no_proc; i++) { @@ -170,12 +190,20 @@ void cmd_directory(){ int cmd_stop(){ char buffer[2]; int length = 2; + pcb *p = pcb_list; printf("Are you sure you want to exit? [y/n]: "); sys_req(CON,READ,buffer,&length); if (strcmp(buffer, "y") == 0 || strcmp(buffer, "Y") == 0) { - printf("**COMHAN execution complete **\n"); + do { + if(p->type != FREE) { + freemem(p->loadaddr); + free_pcb(pcb_list, p); + } + p = p->chain; + } while(p != NULL); + printf("** COMHAN execution complete **\n"); return 1; } else { return 0; @@ -187,44 +215,41 @@ int cmd_stop(){ * Will print all commands or just information specific to the * argument if given. */ -void cmd_help(char *args[]){ - char ver[] = "version Display version number \n"; - char hlp[] = "help Provide information about commands \n"; - char dir[] = "directory List .mpx files \n"; - char dat[] = "date [mm/dd/yyyy] Display or set the system date \n"; - char stp[] = "stop Terminate execution of COMHAN \n"; - char prmpt[] = "prompt string Change the prompt for commands \n"; - char als[] = "alias command=string Create an alias for a command \n"; - char shw[] = "show Prints PCB information \n"; - char alloc[] = "allocate Builds PCB with specified options \n"; - char free[] = "free name Frees the PCB called name \n"; - - switch(get_cmd(args[1])){ - case VERSION: printf(ver); break; - case DATE: printf(dat); break; - case DIRECTORY: printf(dir); break; - case STOP: printf(stp); break; - case HELP: printf(hlp); break; - case PROMPT: printf(prmpt); break; - case ALIAS: printf(als); break; - case SHOW: printf(shw); break; - case ALLOCATE: printf(alloc); break; - case CMD_FREE: printf(free); break; - default: - printf("**\tCommand Summary\t**\n"); - printf("Name Use\n"); - printf("======================================\n"); - printf(ver); - printf(dat); - printf(dir); - printf(stp); - printf(hlp); - printf(prmpt); - printf(als); - printf(shw); - printf(alloc); - printf(free); - } +void cmd_help(char *args[]) { + int i; + char *help[NUM_CMDS]; + + help[VERSION] = "version Display version number"; + help[HELP] = "help Provide information about commands"; + help[DIRECTORY] = "directory List .mpx files"; + help[DATE] = "date [mm/dd/yyyy] Display or set the system date"; + help[STOP] = "stop Terminate execution of COMHAN"; + help[PROMPT] = "prompt string Change the prompt for commands"; + help[ALIAS] = "alias command=string Create an alias for a command"; + help[SHOW] = "show Prints PCB information"; + help[ALLOCATE] = "allocate Builds PCB with specified options"; + help[CMD_FREE] = "free name Frees the PCB called name"; + help[CMD_LOAD] = "load name[=ppp] Creates a process called name with priority ppp"; + help[CMD_RESUME] = "resume name Resumes the process called name"; + help[CMD_RUN] = "run name[=ppp] Runs a process called name with priority ppp"; + help[CMD_SUSPEND] = "suspend name Suspends the process called name"; + help[CMD_TERMINATE] = "terminate name Terminates the process called name"; + help[CMD_SETPRI] = "setpriority name=ppp Sets the priority of process name"; + help[CMD_DISPATCH] = "dispatch Runs each process once"; + + // print header + printf( " Name Use \n"); + printf( " ==================== ================================================= \n"); + + if (args[1] != NULL) { + // print help for specific command + printf(" %s \n", help[ get_cmd(args[1]) ] ); + } else { + // list all help + for (i = 0; i < NUM_CMDS; i++) { + printf(" %s \n", help[i]); + } + } } /** @@ -336,16 +361,14 @@ void cmd_allocate(char *args[]) { pcb * exists; if (!args[1] || !args[2] || !args[3] || !args[4] || !args[5]) { - printf("***Error*** \n"); - printf("Please use the correct number of arguments. \n"); + printf("Error: Please use the correct number of arguments. \n"); return; } if (strcmp(args[2], "f") != 0 && strcmp(args[2], "a") != 0 && strcmp(args[2], "s") != 0) { - printf("***Error*** \n"); - printf("PCB type must be f(ree), a(pplication) or s(ystem). \n"); + printf("Error: PCB type must be f(ree), a(pplication) or s(ystem). \n"); printf("You said: %s \n", args[2]); return; } @@ -353,16 +376,14 @@ void cmd_allocate(char *args[]) { if (strcmp(args[3], "r") != 0 && strcmp(args[3], "o") != 0 && strcmp(args[3], "b") != 0) { - printf("***Error*** \n"); - printf("PCB state must be r(eady), o(running), or b(locked). \n"); + printf("Error: PCB state must be r(eady), o(running), or b(locked). \n"); printf("You said: %s \n", args[3]); return; } if (strcmp(args[4], "y") != 0 && strcmp(args[4], "n") != 0) { - printf("***Error*** \n"); - printf("PCB suspended flag must be y(es) or n(o). \n"); + printf("Error: PCB suspended flag must be y(es) or n(o). \n"); printf("You said: %s \n", args[4]); return; } @@ -372,8 +393,7 @@ void cmd_allocate(char *args[]) { exists = search_pcb(pcb_list, args[1]); if(exists != NULL){ - printf("***Error*** \n"); - printf("A pcb with that name already esists. \n"); + printf("Error: A pcb with that name already esists. \n"); return; } @@ -399,15 +419,13 @@ void cmd_allocate(char *args[]) { } if (type == APP_PROCESS && (priority < -126 || priority > 126)) { - printf("***Error*** \n"); - printf("The priority for an application process must be \n"); + printf("Error: The priority for an application process must be \n"); printf("between -126 and 126, inclusive. \n"); return; } if (type == SYS_PROCESS && (priority < -128 || priority > 127)) { - printf("***Error*** \n"); - printf("The priority for a system process must be \n"); + printf("Error: The priority for a system process must be \n"); printf("between -128 and 127, inclusive. \n"); return; } @@ -418,20 +436,16 @@ void cmd_allocate(char *args[]) { switch (result) { case 1: break; - case -1: printf("***Error*** \n"); - printf("There was no space for another pcb. \n"); + case -1: printf("Error: There was no space for another pcb. \n"); break; - case -2: printf("***Error*** \n"); - printf("Invalid type \n"); + case -2: printf("Error: Invalid type \n"); break; - case -3: printf("***Error*** \n"); - printf("Invalid state \n"); + case -3: printf("Error: Invalid state \n"); break; - case -4: printf("***Error*** \n"); - printf("Invalid suspend \n"); + case -4: printf("Error: Invalid suspend \n"); break; } @@ -457,8 +471,230 @@ void cmd_free(char *args[]) { result = free_pcb(pcb_list, to_free); switch (result) { - case 1: printf("PCB freed\n"); break; - case -1: printf("Couldn't find PCB\n"); break; - case -2: printf("PCB already free\n"); break; + case -1: printf("Error: Couldn't find PCB\n"); break; + case -2: printf("Error: PCB already free\n"); break; + } +} + +/** + * Load + */ +void cmd_load(char *args[]) { + int i, ret, priority = 0; + unsigned segp; + pcb *p; + int paragraphs; + char* name = args[1]; + // figure out how many directory entries + int num = directory(direct, DIR_SIZE); + + // search in the directory for the specified program + i = 0; + while (stricmp(direct[i].dirnam, name) != 0) { + i++; + if (i == num) { + // no program found + printf("Error: No program found with that name. \n"); + return; + } + } + + // figure out how much memory we need + paragraphs = (unsigned) ceil(direct[i].dirsiz / 16); + + // try to allocate the needed memory + if (allocmem(paragraphs, &segp) != -1) { + // insufficient memory + printf("Error: Insufficient memory. \n"); + return; } -} \ No newline at end of file + + // read the file into memory + if (load((unsigned *)segp, direct[i].dirnam) != 0) { + // load error + printf("Error: Could not load program into memory. \n"); + return; + } + + // if a valid priority was specified, replace the default + if (args[2] != NULL) { + if (atoi(args[2]) >= -126 && atoi(args[2]) <= 126) { + priority = atoi(args[2]); + } else { + printf("Warning: invalid priority specified, using default. \n"); + } + } + + // now we can put the proc into a PCB + p = get_pcb(pcb_list); + + if (p == NULL) { + printf("Error: No free PCBs. \n"); + return; + } + + if (build_pcb(p, args[1], APP_PROCESS, READY, SUSPENDED, + priority, segp, 0 /* ip */, 0 /* ds */, 0x200) != 1) { + printf("Error: Unable to build PCB. \n"); + return; + } + + insert_pcb(&ready_queue, p, 0); + return; +} + +/** + * Resume + */ +void cmd_resume(char *args[]) { + + pcb *p = pcb_list; + + if (args[1] != NULL) { + if (strcmp(args[1], "*") == 0) { + // resume all processes + // set suspended to NOT_SUSPENDED for all application PCBs + do { + if (p->type == APP_PROCESS) { + p->suspend = NOT_SUSPENDED; + } + p = p->chain; + } while (p != NULL); + } else { + // search for the correct PCB and set suspended to NOT_SUSPENDED + p = search_pcb(pcb_list, args[1]); + if (p != NULL) { + p->suspend = NOT_SUSPENDED; + } else { + printf("No process named %s. \n", args[1]); + } + } + } else { + printf("No process specified. Please run resume proc \n"); + printf("for process proc. To resume all processes, \n"); + printf("type resume * \n"); + } +} + +/** + * Run + */ +void cmd_run(char *args[]) { + pcb *p; + // load the process ... + cmd_load(args); + + // ... then set it to be not suspended + p = search_pcb(pcb_list, args[1]); + if (p != NULL){ + p->suspend = NOT_SUSPENDED; + } else { + printf("Error: process did not load correctly. \n"); + } +} + +/** + * Suspend + */ +void cmd_suspend(char *args[]) { + pcb *p; + + // Get the pcb... + p = search_pcb(pcb_list, args[1]); + + if (p != NULL) { + // ... and suspend it + p->suspend = SUSPENDED; + } else { + printf("No process with the specified name. \n"); + } +} + +/** + * Terminate + */ +void cmd_terminate(char *args[]) { + pcb *p; + + // the "terminate *" case + if (strcmp(args[1], "*") == 0) { + p = pcb_list; + do { + if (p->type == APP_PROCESS) { + // remove from queue as needed + if (p->state == READY) { + remove_pcb(&ready_queue, p); + } else if (p->state == BLOCKED) { + remove_pcb(&io_init_queue, p); + } + + // free it + freemem(p->loadaddr); + free_pcb(pcb_list, p); + } + p = p -> chain; + } while (p != NULL); + } else { + // the "terminate proc" case + p = search_pcb(pcb_list, args[1]); + + if (p != NULL && p->type == APP_PROCESS) { + + // remove from queue as needed + if (p->state == READY) { + remove_pcb(&ready_queue, p); + } else if (p->state == BLOCKED) { + remove_pcb(&io_init_queue, p); + } + + // free it + freemem(p->loadaddr); + free_pcb(pcb_list, p); + } else { + printf("No process with the specified name. \n"); + } + } + return; +} + +/** + * Set Priority + */ +void cmd_setpri(char *args[]) { + pcb *p; + int new_priority; + + // Get the pcb + p = search_pcb(pcb_list, args[1]); + new_priority = atoi(args[2]); + + if (p != NULL) { + // Check the priority is valid + if (p->type == APP_PROCESS && new_priority >= -128 && new_priority <= 127) { + remove_pcb(&ready_queue, p); // Take pcb out of ready queue + p->priority = new_priority; // Change priority + insert_pcb(&ready_queue, p, 0); // Re-insert pcb in ready queue + } else { + printf("Error: invalid priority. \n"); + } + } else { + printf("Error: invalid process name. \n"); + } +} + +/** + * Dispatch + */ +void cmd_dispatch() { + // set up a pointer to the ready queue + pcb dummy; + cop = &dummy; + cop -> next = ready_queue; + + // save the stack pointer so we can return here + sp_save = _SP - 24; + + // call sys_sppt's dispatch + dispatch(); + return; +} -- cgit v1.2.3