aboutsummaryrefslogtreecommitdiff
path: root/comhan.c
diff options
context:
space:
mode:
Diffstat (limited to 'comhan.c')
-rw-r--r--comhan.c422
1 files changed, 329 insertions, 93 deletions
diff --git a/comhan.c b/comhan.c
index 21a3448..7d02799 100644
--- a/comhan.c
+++ b/comhan.c
@@ -8,32 +8,48 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <math.h>
#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;
+}