Ejemplo n.º 1
0
void TrapTtyTransmit(UserContext *user_context) {
    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, ">>> TrapTtyTransmit(%p)\n", user_context);
    int tty_id = user_context->code;
    Tty term = ttys[tty_id];
    assert(!ListEmpty(term.waiting_to_transmit));

    // Get the currently transmitting proc (always at the front of the list)
    PCB *waiting_proc = (PCB *) ListPeak(term.waiting_to_transmit);
    if (waiting_proc->tty_transmit_len > TERMINAL_MAX_LINE) { 
        // not completely transmitted, so handle pointer stuff and leave in
        // front of the queue
        waiting_proc->tty_transmit_pointer += TERMINAL_MAX_LINE;
        waiting_proc->tty_transmit_len -= TERMINAL_MAX_LINE;

        // transmit min(MAX_LINE, len)
        if (TERMINAL_MAX_LINE > waiting_proc->tty_transmit_len) {
            TtyTransmit(tty_id, waiting_proc->tty_transmit_pointer,
                waiting_proc->tty_transmit_len);
        } else {
            TtyTransmit(tty_id, waiting_proc->tty_transmit_pointer,
                TERMINAL_MAX_LINE);
        }

        return;
    }

    // transmission complete
    // since done, take off transmitting list
    ListRemoveById(term.waiting_to_transmit, waiting_proc->pid);
    ListAppend(ready_queue, waiting_proc, waiting_proc->pid);
    free(waiting_proc->tty_transmit_buffer);

    if (ListEmpty(term.waiting_to_transmit)) {
        return; // no other procs waiting on this term
    }

    // Get the next proc waiting to submit
    PCB *next_to_transmit = (PCB *) ListPeak(term.waiting_to_transmit);
    // transmit min(MAX_LINE, len)
    if (TERMINAL_MAX_LINE > next_to_transmit->tty_transmit_len) {
        TtyTransmit(tty_id, next_to_transmit->tty_transmit_pointer,
            next_to_transmit->tty_transmit_len);
    } else {
        TtyTransmit(tty_id, next_to_transmit->tty_transmit_pointer,
            TERMINAL_MAX_LINE);
    }

    TracePrintf(TRACE_LEVEL_FUNCTION_INFO, "<<< TrapTtyTransmit(%p)\n", user_context);
}
Ejemplo n.º 2
0
int Y_TtyWrite(int tty_id, void *buf, int len, UserContext *user_context)
{
    int commit_len;
    char *commit_buf;
    int result = 0;
    dnode_t *node = NULL;

    //log_info("tty_id = %d, buf = %p, len = %d, pid = %d", tty_id, buf, len, running_proc->pid);

    commit_buf = (void *)calloc(1, TERMINAL_MAX_LINE);
    if (commit_buf == NULL) {
            log_err("allocate buffer for tty transferring failed!\n");
            log_info("result = %d, pid = %d", result, running_proc->pid);
            return _FAILURE;
    }
    //log_info("calloc commit_buf done");

    len = min(len, strlen(buf));
    while (len) {
        commit_len = min(len, TERMINAL_MAX_LINE);
        memcpy(commit_buf, buf + result, commit_len);
        //log_info("memcpy from buff done");
            
        len -= commit_len;
        //log_info("TTY Enqueue PID(%d) DONE", running_proc->pid);
        while (is_write_busy(tty_id)) {
            tty_write_enqueue(running_proc, tty_id);
            pcb_t *print_proc = peek_tty_write_queue(tty_id);
            //log_info("PID(%d) is waiting for printing PID(%d)", running_proc->pid, tty_writing_procs[tty_id]->pid);
            next_schedule(user_context);
        }
        set_write_proc(running_proc, tty_id);
        //log_info("PID(%d) Right before tty transmit", running_proc->pid);
        TtyTransmit(tty_id, commit_buf, commit_len);
        //log_info("Right after tty transmit");
        next_schedule(user_context);
        //log_info("Back from tty block");
        result += commit_len;
    }

    free(commit_buf);

    log_info("Len of printed chars = %d, pid = %d", result, running_proc->pid);

    return result;
}