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); }
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; }