#include <stdio.h> #include <stdlib.h> #include <time.h> #include <windows.h> #include "pcb.h" #include "funCode.h" pList pReadyList = new readyList; pList pFreeList = new freeList; pPCB runPCB; bool firstTime = true; applyQueue* queue = new applyQueue; HANDLE hSchedule = NULL; bool schIsActive = false; CRITICAL_SECTION cs_ReadyList; CRITICAL_SECTION cs_SaveSection; //CRITICAL_SECTION cs_RunPCB; extern FILE* log; extern PC; extern FUN functions[FUN_NUM]; void initialPCB(pPCB p) { p->id = 0; strcpy(p->name, ""); p->status = WAIT; p->ax = 0; p->bx = 0; p->cx = 0; p->dx = 0; p->pc = 0; p->psw = 0; p->next = NULL; p->hThis = NULL; p->threadID = 0; p->count = 0; } pPCB getPcbFromFreeList() { pPCB freePCB = NULL; if (pFreeList->head != NULL && pFreeList->pcbNum > 0) { freePCB = pFreeList->head; pFreeList->head = pFreeList->head->next; pFreeList->pcbNum--; } return freePCB; } void returnPcbToFreeList(pPCB p) { initialPCB(p); if (pFreeList->head == NULL) { pFreeList->head = p; pFreeList->tail = p; pFreeList->pcbNum++; } else { pFreeList->tail->next = p; pFreeList->tail = p; pFreeList->pcbNum++; } } DWORD WINAPI processThread(LPVOID lpParameter) { pPCB currentPcb = (pPCB)lpParameter; MSG msg; while (true) { Sleep(500); fprintf(log, "process %d:%s is running.../n", currentPcb->id, currentPcb->name); currentPcb->pc++; fflush(log); EnterCriticalSection(&cs_SaveSection); if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)) { if (msg.message == WM_USER) { //printf("Process %d:%s recieve a message. It's to be suspended./n", // currentPcb->id, currentPcb->name); } } LeaveCriticalSection(&cs_SaveSection); } /* while (true) { PC = currentPcb->pc; for (int i = 0; i < TIME_SLOT; i++) { (*functions[PC%FUN_NUM].pc)(); PC++; } currentPcb->pc = PC; SuspendThread(currentPcb->hThis); }*/ return 0; } DWORD WINAPI scheduleThread(LPVOID lpParameter) { pList readyList = (pList)lpParameter; while (true) { scheduleProcess(); if (readyList->pcbNum <= 0 && schIsActive) { schIsActive = false; SuspendThread(hSchedule); } else if (readyList->pcbNum >0 && !schIsActive) { schIsActive = true; ResumeThread(hSchedule); } } return 0; } void init() { //////////////////////////////////////////////////////////////// if (firstTime) { pReadyList->head = NULL; pReadyList->tail = NULL; pReadyList->pcbNum = 0; pFreeList->head = NULL; pFreeList->tail = NULL; pFreeList->pcbNum = 0; for (int i = 0; i < PCB_LIMIT; i++) { pPCB pTempPCB = new PCB; initialPCB(pTempPCB); pTempPCB->id = i; if (pFreeList->head == NULL) { pFreeList->head = pTempPCB; pFreeList->tail = pTempPCB; pFreeList->pcbNum++; } else { pFreeList->tail->next = pTempPCB; pFreeList->tail = pTempPCB; pFreeList->pcbNum++; } } hSchedule = CreateThread(NULL, NULL, scheduleThread, pReadyList, CREATE_SUSPENDED, 0); InitializeCriticalSection(&cs_ReadyList); InitializeCriticalSection(&cs_SaveSection); //InitializeCriticalSection(&cs_RunPCB); firstTime = false; } ////////////////////////////////////////////////////////////////////// } void createProcess(char* name, int count/*, int pc*/) { // EnterCriticalSection(&cs_ReadyList); // if (pFreeList->pcbNum > 0) { pPCB newPcb = getPcbFromFreeList(); newPcb->status = READY; strcpy(newPcb->name, name); newPcb->count = count; //newPcb->pc = 0; newPcb->next = NULL; srand( (unsigned)time( NULL ) ); newPcb->ax = rand() % 20; newPcb->bx = rand() % 20; newPcb->cx = rand() % 20; newPcb->dx = rand() % 20; newPcb->pc = rand() % 20; newPcb->psw = rand() % 20; if (pReadyList->pcbNum == 0) { pReadyList->head = newPcb; pReadyList->tail = newPcb; pReadyList->pcbNum++; } else { pReadyList->tail->next = newPcb; pReadyList->tail = newPcb; pReadyList->pcbNum++; } fprintf(log, "New Process Created. /nProcess ID: %d Process Name: %s Process Length: %d/n", newPcb->id, newPcb->name, newPcb->count); fprintf(log, "AX: %d/tBX: %d/tCX: %d/tDX: %d/tPC: %d/tPSW: %d/n/n", newPcb->ax, newPcb->bx, newPcb->cx, newPcb->dx, newPcb->pc, newPcb->psw); fprintf(log, "Current ReadyList is:/n"); fprintReadyList(); newPcb->hThis = CreateThread(NULL, NULL, processThread, newPcb, CREATE_SUSPENDED, &(newPcb->threadID)); } else { printf("PCB used out/n"); fprintf(log, "New process intend to append. But PCB has been used out!/n/n"); } // LeaveCriticalSection(&cs_ReadyList); // } void scheduleProcess() { //// //EnterCriticalSection(&cs_RunPCB); //// // EnterCriticalSection(&cs_ReadyList); // if (pReadyList->pcbNum > 0) { runPCB = pReadyList->head; pReadyList->head = pReadyList->head->next; if (pReadyList->head == NULL) { pReadyList->tail = NULL; } pReadyList->pcbNum--; runPCB->count--; fprintf(log, "Process %d:%s is to be scheduled./n" "Process %d:%s Information:/tAX: %d/tBX: %d/tCX: %d/tDX: %d/tPC: %d/tPSW: %d/n/n", runPCB->id, runPCB->name, runPCB->id, runPCB->name, runPCB->ax, runPCB->bx, runPCB->cx, runPCB->dx, runPCB->pc, runPCB->psw); ResumeThread(runPCB->hThis); runPCB->status = RUN; Sleep(1000); fprintf(log, "/nOne time slot used out!/n/n"); runPCB->status = READY; PostThreadMessage(runPCB->threadID, WM_USER, 0, 0); // EnterCriticalSection(&cs_SaveSection); // SuspendThread(runPCB->hThis); // LeaveCriticalSection(&cs_SaveSection); // if (runPCB->count <= 0 && runPCB != NULL) { printf("/nProcess %d:%s has finished./n", runPCB->id, runPCB->name); printf("COMMAND>"); fprintf(log, "Process %d:%s has finished./n/n", runPCB->id, runPCB->name); fprintf(log, "Current ReadyList is:/n"); fprintReadyList(); fflush(log); TerminateThread(runPCB->hThis, 0); returnPcbToFreeList(runPCB); runPCB = NULL; } if (runPCB != NULL) { if (pReadyList->pcbNum == 0) { pReadyList->head = runPCB; pReadyList->tail = runPCB; } else { pReadyList->tail->next = runPCB; pReadyList->tail = runPCB; } runPCB->next = NULL; runPCB = NULL; pReadyList->pcbNum++; } } else if (pReadyList != NULL) { pReadyList->head = NULL; pReadyList->tail = NULL; pReadyList->pcbNum = 0; } // LeaveCriticalSection(&cs_ReadyList); // //// //LeaveCriticalSection(&cs_RunPCB); //// } void addApplyProcess(char* name, int time) { applyProcess* newApply = new applyProcess; strcpy(newApply->name, name); newApply->time = time; newApply->next = NULL; if (queue->applyNum <= 0) { queue->head = newApply; queue->tail = newApply; queue->applyNum = 1; } else { queue->tail->next = newApply; queue->tail = newApply; queue->applyNum++; } createIfAnyApply(); } void createIfAnyApply() { if (queue != NULL && queue->applyNum >= 1) { applyProcess* temp = queue->head; createProcess(temp->name, temp->time); if (queue->applyNum <= 1) { queue->head = NULL; queue->tail = NULL; } else { queue->head = queue->head->next; } queue->applyNum--; delete temp; } if (!schIsActive) { schIsActive = true; ResumeThread(hSchedule); } } void removeProcess(char* name) { pPCB removeTarget = NULL; pPCB preTemp = NULL; // EnterCriticalSection(&cs_ReadyList); // if (runPCB != NULL && strcmp(name, runPCB->name) == 0) { removeTarget = runPCB; printf("Process %d:%s has been removed./n", removeTarget->id, removeTarget->name); fprintf(log, "/nProcess %d:%s has been removed./n", removeTarget->id, removeTarget->name); TerminateThread(removeTarget->hThis, 0); returnPcbToFreeList(removeTarget); runPCB = NULL; fprintf(log, "Current ReadyList is:/n"); fprintReadyList(); fflush(log); // LeaveCriticalSection(&cs_ReadyList); // return; } else if (pReadyList->head != NULL) { for (removeTarget = pReadyList->head, preTemp = pReadyList->head; removeTarget != NULL; removeTarget = removeTarget->next) { if (removeTarget == pReadyList->head && strcmp(name, removeTarget->name) == 0) { pReadyList->head = pReadyList->head->next; if (pReadyList->head == NULL) { pReadyList->tail = NULL; } printf("Process %d:%s has been removed./n", removeTarget->id, removeTarget->name); fprintf(log, "/nProcess %d:%s has been removed./n", removeTarget->id, removeTarget->name); TerminateThread(removeTarget->hThis, 0); returnPcbToFreeList(removeTarget); pReadyList->pcbNum--; fprintf(log, "Current ReadyList is:/n"); fprintReadyList(); fflush(log); // LeaveCriticalSection(&cs_ReadyList); // return; } else if (removeTarget != pReadyList->head && strcmp(name, removeTarget->name) == 0) { preTemp->next = removeTarget->next; if (removeTarget == pReadyList->tail) { pReadyList->tail = preTemp; } printf("Process %d:%s has been removed./n", removeTarget->id, removeTarget->name); fprintf(log, "/nProcess %d:%s has been removed./n", removeTarget->id, removeTarget->name); TerminateThread(removeTarget->hThis, 0); returnPcbToFreeList(removeTarget); pReadyList->pcbNum--; fprintf(log, "Current ReadyList is:/n"); fprintReadyList(); fflush(log); // LeaveCriticalSection(&cs_ReadyList); // return; } else if (removeTarget != pReadyList->head) { preTemp = preTemp->next; } } } printf("Sorry, there's no process named %s/n", name); // LeaveCriticalSection(&cs_ReadyList); // return; } void fprintReadyList() { pPCB tmp = NULL; tmp = pReadyList->head; if (tmp != NULL) { for (int i = 0; i < pReadyList->pcbNum; i++) { fprintf(log, "--%d:%s--", tmp->id, tmp->name); tmp = tmp->next; } } else { fprintf(log, "NULL"); } fprintf(log, "/n/n"); } void printReadyList() { pPCB tmp = NULL; tmp = pReadyList->head; if (tmp != NULL) { for (int i = 0; i < pReadyList->pcbNum; i++) { printf("--%d:%s--", tmp->id, tmp->name); tmp = tmp->next; } } else { printf("NULL"); } printf("/n/n"); } void printCurrent() { if (runPCB != NULL) { printf("Process %s is running.../n", runPCB->name); } else { printf("No process is running./n"); } printf("Current readyList is:/n"); printReadyList(); } |