Exemplo n.º 1
0
        size_t refill(const Stream::InputStream & is, size_t readPossible)
        {
            if (!canFit(readPossible))
                readPossible = total - available();
            if (readPossible <= 0) return 0;

            // Move the data that was consumed out of buffer
            if (consumed)
            {
                memmove((uint8*)buffer, &((uint8*)buffer)[consumed], fill - consumed);
                fill -= consumed;
            }
            consumed = 0;

            uint64 ret = is.read(&((uint8*)buffer)[fill], readPossible);
            if (ret != (uint64)-1) fill += (size_t)ret;
            return (size_t)ret;
        }
Exemplo n.º 2
0
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;
}