void main() { struct priorityQueueContainer jobQueue; initializePQueue(&jobQueue); PQUEUE test1 = returnPQueueElement(); PQUEUE test2 = returnPQueueElement(); PQUEUE test3 = returnPQueueElement(); PQUEUE test4 = returnPQueueElement(); PQUEUE test5 = returnPQueueElement(); PQUEUE test6 = returnPQueueElement(); PQUEUE test7 = returnPQueueElement(); initQueue(test1,0,ROUND_ROBIN); initQueue(test2,2,ROUND_ROBIN); initQueue(test3,0,ROUND_ROBIN); initQueue(test4,0,ROUND_ROBIN); initQueue(test5,1,ROUND_ROBIN); initQueue(test6,2,ROUND_ROBIN); initQueue(test7,3,ROUND_ROBIN); pEnqueue(&jobQueue,test1); pEnqueue(&jobQueue,test2); pEnqueue(&jobQueue,test3); pEnqueue(&jobQueue,test4); pEnqueue(&jobQueue,test5); pEnqueue(&jobQueue,test6); pEnqueue(&jobQueue,test7); heartBeatProcess(&jobQueue); heartBeatProcess(&jobQueue); heartBeatProcess(&jobQueue); //this is where dequeue happens pDequeue(&jobQueue); pDequeue(&jobQueue); pDequeue(&jobQueue); pDequeue(&jobQueue); pDequeue(&jobQueue); pDequeue(&jobQueue); pDequeue(&jobQueue); pDequeue(&jobQueue); }
int main() { struct master_table mastertable; //mark all of the entries in the master table as free for (int i = 0; i < 100; i++) { mastertable.mem[i].free = 1; mastertable.mem[i].base = i * 10; } srand(time(NULL)); //initialize our semaphores to 1 and create their queues for (int i = 0; i < 10; i++) { SEM[i].count = 1; SEM[i].sem_queue = pQueueNew(); } //initialize space for n pcbs struct pbrain_pcb *pcbMem = (struct pbrain_pcb *)malloc(NUM_PROCESSES * sizeof(struct pbrain_pcb)); //as well as memory for the entire system (1000 words) memBase = (char *)malloc(NUM_PROCESSES * sizeof(char[100][6])); mainmem = (char *)malloc(1000 * sizeof(char[100][6])); //"zero" out all of the memory we allocated memset(memBase, '0', NUM_PROCESSES * sizeof(char[100][6])); memset(mainmem, '0', 1000 * sizeof(char[100][6])); //assign each process a unique PID for (int i = 0; i < NUM_PROCESSES; i++) { pcbMem[i].memory = (char (*)[100][6])memBase; //set each process's PID to i pcbMem[i].pid = i; //give the process a random timeslice between 1 and 10 pcbMem[i].timeSlice = (rand() % 10) + 1; pcbMem[i].remaining_quantum = pcbMem[i].timeSlice; //load the program into pcb storage loadProgramToMem(i, memBase, i); //set the BAR to 100 * i char temp[5]; sprintf(temp, "%04d", 100 * i); memcpy(pcbMem[i].BAR, temp, 4); //set the PC to 2 to skip the two parameters pcbMem[i].PC = 2; pcbMem[i].N = charToInt(pcbMem[i].memory[0][pcbBaseAddress(&pcbMem[i])], 6); pcbMem[i].memSize = charToInt(pcbMem[i].memory[0][pcbBaseAddress(&pcbMem[i]) + 1], 6); printf("Process %d: N = %d, size = %d\n", i, pcbMem[i].N, pcbMem[i].memSize); pcbMem[i].table = (struct page_table *)malloc(sizeof(struct page_table)); pt_init(pcbMem[i].table); for (int j = 0; j < 10; j++) { pcbMem[i].table->entries[j].valid = 1; } } struct pqueue *readyQueue = pQueueNew(); struct pqueue *waitQueue = pQueueNew(); //load processes into memory until we can't fit any more int currentLoaded = 0; while (currentLoaded != NUM_PROCESSES && canFit(&pcbMem[currentLoaded], &mastertable)) { printf("Process %d can fit (free pages: %d)\n", currentLoaded, freeCount(&mastertable)); //set up the process's page table for (int i = 0; i < getPageSize(&pcbMem[currentLoaded]); i++) { struct master_entry *freeEntry = getFree(&mastertable); pcbMem[currentLoaded].table->entries[i].baseAddress = freeEntry->base; printf("Process %d: table entry %d base set to %d\n", pcbMem[currentLoaded].pid, i, freeEntry->base); freeEntry->free = 0; } for (int i = getPageSize(&pcbMem[currentLoaded]); i < 10; i++) { pcbMem[currentLoaded].table->entries[i].valid = 0; printf("Process %d: table entry %d set to invalid\n", pcbMem[currentLoaded].pid, i); } currentLoaded++; } //load all processes that were placed into memory in the ready queue for (int i = 0; i < currentLoaded; i++) { printf("Process %d is loaded into memory and placed on the ready queue\n", pcbMem[i].pid); pEnqueue(readyQueue, &pcbMem[i]); } while (currentLoaded != NUM_PROCESSES) { pEnqueue(waitQueue, &pcbMem[currentLoaded]); printf("Process %d couldn't fit in memory; placed in queue\n", pcbMem[currentLoaded].pid); currentLoaded++; } int numFinished = 0; struct pbrain_pcb *current = pDequeue(readyQueue); while (numFinished != NUM_PROCESSES) { //execute a step if (!current->halted) { updateEffectiveAddress(current); interpretStep(current); current->remaining_quantum--; } //if it made a system call if (current->trap) { current->trap = false; //the cases have braces around them because otherwise we'd have cases in protected scope switch (current->syscall) { case 0: {//getpid printf("Process %d called getpid\n", current->pid); current->R0 = current->pid; break; } case 1: { //wait int index = current->R0; if (index < 0 || index > 9) { current->halted = true; printf("Process %d: attempt to wait on invalid semaphore at index %d\n", current->pid, index); break; } SEM[index].count--; if (SEM[index].count < 0) { pEnqueue(SEM[index].sem_queue, current); printf("Process %d: wait on semaphore %d\n", current->pid, index); current->queueRemoved = true; break; } else { printf("Process %d: wait on semaphore %d; continues\n", current->pid, index); break; } break; } case 2: { //signal int index = current->R0; if (index < 0 || index > 9) { current->halted = true; printf("Process %d: attempt to signal invalid semaphore at index %d\n", current->pid, index); continue; } SEM[index].count++; if (SEM[index].count <= 0) { printf("Process %d calls SIGNAL on semaphore %d; ", current->pid, index); struct pbrain_pcb *blocked = pDequeue(SEM[index].sem_queue); pEnqueue(readyQueue, blocked); printf("; process %d was waiting for semaphore %d and moves to the ready queue\n", blocked->pid, index); continue; } else { printf("Process %d calls SIGNAL to release semaphore %d. No processes were waiting.\n", current->pid, index); continue; } } } //end switch/case } //end if(current->trap) if (current->queueRemoved) { printf("Process %d is waiting and removed from ready queue\n", current->pid); current->queueRemoved = false; current = pDequeue(readyQueue); if (current == NULL) { printf("\nProcesses are deadlocked\n"); exit(0); break; } printf("Process %d is now executing\n", current->pid); current->remaining_quantum = current->timeSlice; } //if it finished if (current->halted) { printf("Process %d halted\n", current->pid); numFinished++; //free the table entries used by that process freeEntries(current, &mastertable); //see if we can put another process in struct pbrain_pcb *potential = pDequeue(waitQueue); if (potential != NULL) { if (canFit(potential, &mastertable)) { for (int i = 0; i < getPageSize(potential); i++) { struct master_entry *freeEntry = getFree(&mastertable); potential->table->entries[i].baseAddress = freeEntry->base; printf("Process %d: table entry %d base set to %d\n", potential->pid, i, freeEntry->base); freeEntry->free = 0; } for (int i = getPageSize(potential); i < 10; i++) { potential->table->entries[i].valid = 0; printf("Process %d: table entry %d set to invalid\n", potential->pid, i); } printf("Loaded process %d into memory and placed on ready queue\n", potential->pid); pEnqueue(readyQueue, potential); } else { pEnqueue(waitQueue, potential); } } struct pbrain_pcb *next = pDequeue(readyQueue); if (next != NULL) { current = next; current->remaining_quantum = current->timeSlice; } } if (current == NULL) { break; //there are no more processes if we reach this point and this is true } if (current->remaining_quantum == 0) { pEnqueue(readyQueue, current); current = pDequeue(readyQueue); if (current != NULL) { current->remaining_quantum = current->timeSlice; continue; } else { numFinished = NUM_PROCESSES; } } } writeMain(pcbMem); /* for (int i = 0; i < NUM_PROCESSES; i++) { writeCPU(&pcbMem[i]); writeMem(&pcbMem[i]); } */ return 0; }