Why the keyboard input is written back to IO bus in xv6? - unix

I do not understand why the input got from keyboard interrupt is written back to the io bus again:
This is the keyboard interrupt handler:
void consoleintr(int (*getc)(void)) {
// I skipped some code for simplicity
default:
if(c != 0 && input.e-input.r < INPUT_BUF){
c = (c == '\r') ? '\n' : c;
input.buf[input.e++ % INPUT_BUF] = c;
-----> consputc(c);
if(c == '\n' || c == C('D') || input.e == input.r+INPUT_BUF){
input.w = input.e;
wakeup(&input.r);
}
}
break;
}
}
The input c is taken from getc function and written to input.buf ring buffer and right after that it is passed to consputc function.
consputc function calls uartputc which calls outb(COM1+0, c).
The uartgetc function also registered as a input for consoleintr function:
static int uartgetc(void) {
if (!uart) {
return -1;
}
if (!(inb(COM1 + 5) & 0x01)) {
return -1;
}
return inb(COM1+0);
}
void uartintr(void) {
consoleintr(uartgetc);
}
Links to the code:
consoleintr: https://github.com/mit-pdos/xv6-public/blob/master/console.c#L192
consputc: https://github.com/mit-pdos/xv6-public/blob/master/console.c#L166
uartputc: https://github.com/mit-pdos/xv6-public/blob/master/uart.c#L52

The key pressed from keyboard is not resent to be processed again, but is send to output:
The uart is some kind of serial line, it is used in two ways: input and output.
The keyboard in only an input device.
When you press a key, the key pressed will be sent to serial out.
A small schematics may explain better:
+-------------+
| | +--------------+
| Keyboard +-----+ +---->+ Screen (term)|
| | | | +--------------+
+-------------+ | +------------+ |
| | | | +----------------+
+--->| Char to +-----+----->+ Input (process)|----> ....
| | process | | +----------------+
+--------------+ | +------------+ | +--------------+
| | | +---->+ Serial: out |
| Serial: in +----+ | outb(...) |
| inb(...) | +--------------+
+--------------+

Related

Rust - Collecting slices of a Vec in a recursive function

I am currently trying to build a huffman encoding program and am struggling with a problem I have while traversing my generated huffman tree to create a lookup table. I decided to implement said traversal with a recursive function. In the actual implementation I use the bitvec crate to save bitsequences, but for simplicitly I will use Vec<bool> in this post.
The idea I had was to save a collection of all codewords in the Vec codewords and then only save a slice out of that vector for the actual lookup table, for which I used a HashMap.
The issue is how exactly I would solve adding a 0 or a 1 for both the left and right traversal. My idea here was to save a clone of a slice of the current sequence, append a 0 to codewords, then append that clone to the end of codewords after traversing to the left so that I can push a 1 and traverse to the right. The function I came up with looks like this:
use std::collections::HashMap;
// ignore everything being public, I use getters in the real code
pub struct HufTreeNode {
pub val: u8,
pub freq: usize,
pub left: i16,
pub right: i16,
}
fn traverse_tree<'a>(
cur_index: usize,
height: i16,
codewords: &'a mut Vec<bool>,
lookup_table: &mut HashMap<u8, &'a [bool]>,
huffman_tree: &[HufTreeNode],
) {
let cur_node = &huffman_tree[cur_index];
// if the left child is -1, we reached a leaf
if cur_node.left == -1 {
// the last `height` bits in codewords
let cur_sequence = &codewords[(codewords.len() - 1 - height as usize)..];
lookup_table.insert(cur_node.val, cur_sequence);
return;
}
// save the current sequence so we can traverse to the right afterwards
let mut cur_sequence = codewords[(codewords.len() - 1 - height as usize)..].to_vec();
codewords.push(false);
traverse_tree(
cur_node.left as usize,
height + 1,
codewords, // mutable borrow - argument requires that `*codewords` is borrowed for `'a`
lookup_table,
huffman_tree,
);
// append the previously saved current sequence
codewords.append(&mut cur_sequence); // second mutable borrow occurs here
codewords.push(true); // third mutable borrow occurs here
traverse_tree(
cur_node.right as usize,
height + 1,
codewords, // fourth mutable borrow occurs here
lookup_table,
huffman_tree,
);
}
fn main() {
// ...
}
Apparently there is an issue with lifetimes and borrowing in that snippet of code, and I kind of get what the problem is. From what I understand, when I give codewords as a parameter in the recursive call, it has to borrow the vector for as long as I save the slice in lookup_table which is obviously not possible, causing the error. How do I solve this?
This is what cargo check gives me:
error[E0499]: cannot borrow `*codewords` as mutable more than once at a time
--> untitled.rs:43:5
|
14 | fn traverse_tree<'a>(
| -- lifetime `'a` defined here
...
34 | / traverse_tree(
35 | | cur_node.left as usize,
36 | | height + 1,
37 | | codewords, // mutable borrow - argument requires that `*codewords` is borrowed for `'a`
| | --------- first mutable borrow occurs here
38 | | lookup_table,
39 | | huffman_tree,
40 | | );
| |_____- argument requires that `*codewords` is borrowed for `'a`
...
43 | codewords.append(&mut cur_sequence); // second mutable borrow occurs here
| ^^^^^^^^^ second mutable borrow occurs here
error[E0499]: cannot borrow `*codewords` as mutable more than once at a time
--> untitled.rs:44:5
|
14 | fn traverse_tree<'a>(
| -- lifetime `'a` defined here
...
34 | / traverse_tree(
35 | | cur_node.left as usize,
36 | | height + 1,
37 | | codewords, // mutable borrow - argument requires that `*codewords` is borrowed for `'a`
| | --------- first mutable borrow occurs here
38 | | lookup_table,
39 | | huffman_tree,
40 | | );
| |_____- argument requires that `*codewords` is borrowed for `'a`
...
44 | codewords.push(true); // third mutable borrow occurs here
| ^^^^^^^^^ second mutable borrow occurs here
error[E0499]: cannot borrow `*codewords` as mutable more than once at a time
--> untitled.rs:48:9
|
14 | fn traverse_tree<'a>(
| -- lifetime `'a` defined here
...
34 | / traverse_tree(
35 | | cur_node.left as usize,
36 | | height + 1,
37 | | codewords, // mutable borrow - argument requires that `*codewords` is borrowed for `'a`
| | --------- first mutable borrow occurs here
38 | | lookup_table,
39 | | huffman_tree,
40 | | );
| |_____- argument requires that `*codewords` is borrowed for `'a`
...
48 | codewords, // fourth mutable borrow occurs here
| ^^^^^^^^^ second mutable borrow occurs here
What am I missing here? Is there some magical function in the vector API that I'm missing, and why exactly does this create lifetime issues in the first place? From what I can tell, all my lifetimes are correct because codewords always lives for long enough for lookup_table to save all those slices and I never mutably borrow something twice at the same time. If there was something wrong with my lifetimes, the compiler would complain inside the if cur_node.left == -1 block, and the cur_sequence I take after it is an owned Vec, so there can't be any borrowing issues with that. So the issue really is with the core idea of having a recursive function with a mutable reference as a parameter.
Is there any way for me to solve this? I tried making codewords owned and returning it, but then the compiler cannot ensure that the bitsequence I'm saving inside lookup_table lives for long enough. The only idea I still have is to save owned vectors inside lookup_table, but at that point the codewords vector is obselete in the first place and I can simply implement this by having a cur_sequence vector as parameter which I clone in every call, but I chose my approach for a better cache performance in the actual encoding process right after, which I would then lose.
The problem is that when you create a slice cur_sequence from codewords like you did in let cur_sequence = &codewords[(codewords.len() - 1 - height as usize)..];, the compiler extends the lifetime of the reference to codewords to at least the same as cur_sequence (why: The compiler wants to ensure that the slice cur_sequence is always valid, but if you change codewords (say, clear it) then it's possible that cur_sequence is invalid. By keeping an immutable reference to codewords, then borrow rules will forbid modification of codewords when the slice is still alive). And unfortunately you save cur_sequence in lookup_table, thus keeping the reference to codewords alive all over the function, so you cannot mutably borrow codewords anymore.
The solution is to maintain the indexes of the slice by yourself: create a struct:
struct Range {
start: usize,
end: usize
}
impl Range {
fn new(start: usize, end: usize) -> Self {
Range{ start, end}
}
}
then use it instead of the slices:
let cur_range = Range::new(
codewords.len() - 1 - height as usize,
codewords.len() - 1
);
lookup_table.insert(cur_node.val, cur_range);
In this way, the responsibility to keep the ranges valid is yours.
complete code:
use std::collections::HashMap;
// ignore everything being public, I use getters in the real code
pub struct HufTreeNode {
pub val: u8,
pub freq: usize,
pub left: i16,
pub right: i16,
}
struct Range {
start: usize,
end: usize
}
impl Range {
fn new(start: usize, end: usize) -> Self {
Range{ start, end}
}
}
fn traverse_tree(
cur_index: usize,
height: i16,
codewords: &mut Vec<bool>,
lookup_table: &mut HashMap<u8, Range>,
huffman_tree: &[HufTreeNode],
) {
let cur_node = &huffman_tree[cur_index];
// if the left child is -1, we reached a leaf
if cur_node.left == -1 {
// the last `height` bits in codewords
// let cur_sequence = &codewords[(codewords.len() - 1 - height as usize)..];
let cur_range = Range::new(
codewords.len() - 1 - height as usize,
codewords.len() - 1
);
lookup_table.insert(cur_node.val, cur_range);
return;
}
// save the current sequence so we can traverse to the right afterwards
let mut cur_sequence = codewords[(codewords.len() - 1 - height as usize)..].to_vec();
codewords.push(false);
traverse_tree(
cur_node.left as usize,
height + 1,
codewords, // mutable borrow - argument requires that `*codewords` is borrowed for `'a`
lookup_table,
huffman_tree,
);
// append the previously saved current sequence
codewords.append(&mut cur_sequence); // second mutable borrow occurs here
codewords.push(true); // third mutable borrow occurs here
traverse_tree(
cur_node.right as usize,
height + 1,
codewords, // fourth mutable borrow occurs here
lookup_table,
huffman_tree,
);
}
fn main() {
// ...
}

what does this code mean in xv6 entrypgdir?

I'm currently delving into the xv6 operating system. I have a question for the below code snippet. I know entrypgdir is an array of pde_t type with size of NPDENTRIES. But what does "[0] = (0) | PTE_P | PTE_W | PTE_PS" mean?
Thanks in advance
__attribute__((__aligned__(PGSIZE)))
pde_t entrypgdir[NPDENTRIES] = {
// Map VA's [0, 4MB) to PA's [0, 4MB)
[0] = (0) | PTE_P | PTE_W | PTE_PS,
// Map VA's [KERNBASE, KERNBASE+4MB) to PA's [0, 4MB)
[KERNBASE>>PDXSHIFT] = (0) | PTE_P | PTE_W | PTE_PS,
};
The code is initializing the contents of the page directory. (See designated array initialization in C).
Consider this image of the contents of a page directory entry from OSDev Wiki:
Then consider this line of code:
[0] = (0) | PTE_P | PTE_W | PTE_PS
The code sets the value of the first page directory entry (index 0) to 0 | PTE_P | PTE_W | PTE_PS. This is a bitwise OR to set the various fields:
0 - clear all bits
PTE_P - set the present bit
PTE_W - set the read\write bit
PTE_PS - set the 4MiB page size bit
The next line does a similar thing. Except it sets the contents of the 513th entry (index 512 (0x80000000 >> 22)):
[KERNBASE >> PDXSHIFT] = (0) | PTE_P | PTE_W | PTE_PS
.
Aside:
The bit position of the flags of interest to xv6 is the same for page directory entries (PDE) and page table entries (PTE). Instead of creating separate constants for the PDE flags, the authors opted to share the constants... In my opinion, this shortcut makes the code slightly less clear in intent.
// Page table/directory entry flags.
#define PTE_P 0x001 // Present
#define PTE_W 0x002 // Writeable
#define PTE_U 0x004 // User
#define PTE_PS 0x080 // Page Size

How to properly handle a PATCH request with Go

I have a "Settings" table in my postgresql database with following data :
id | price | duration | start_mn | end_mn | step | days_ranges
----+-------+----------+----------+--------+------+--------------------------------------------------
1 | 50 | 40 | 540 | 1140 | 30 | [{"weekday":3,"ranges":{"from":599, "to":1079}}]
I want to handle a patch request that would edit a single field such as duration for instance.
Atm I have an http request with this body : {duration: 20}
I'd like to know how to properly patch. On my GO backend these structs are set :
type Settings struct {
Price int
Duration int
StartMn int
EndMn int
Step int
DaysRanges DaysRanges
}
type DaysRanges []struct {
WeekDay int
Ranges struct {
From int
To int
}
}
Now the function that handles it for now :
func PatchSettings(w http.ResponseWriter, r *http.Request) {
var settings Settings
err := json.NewDecoder(r.Body).Decode(&settings)
if err != nil {
panic(err)
}
}
So far I got an object Settings with many fields empty (since only the duration is passed in the body). I can then check each field and if it is not empty process an sql update on that specific field with its value.
But I have a feeling it's quite poor understanding of the PATCH request and the way to deal with it.
I'm looking for a better approach.

Non-blocking communication buffer manipulation before test or wait

The MPI standard states that once a buffer has been given to a non-blocking communication function, the application is not allowed to use it until the operation has completed (i.e., until after a successful TEST or WAIT function).
Is this also applied to the situation below:
I have a buffer and every part of that will go to different processors, e.g part of it will be copied from data available on the processor itself.
Am I allowed on every processor to MPI_Irecv different parts of the buffer from other processors, copy the part available in the processor then MPI_Isend the data that should go to others, do my other computations, and MPI_Waitall so my send and receive get completed?
n=0;
for (i = 0; i < size; i++) {
if (i != rank) {
MPI_Irecv(&recvdata[i*100], 100, MPI_INT, i, i, comm, &requests[n]);
n++;
}
}
process(&recvdata[rank*100], 100);
for (i = 0; i < size; i++) {
if (i != rank) {
MPI_Isend(&senddata[i*100], 100, MPI_INT, i, rank, comm, &requests[n]);
n++;
}
}
MPI_Waitall(n, requests, statuses);
I'm not 100% sure I understand what you're asking, so I'll restate the question first:
If I have a large array of data, can I create nonblocking calls to receive data from subsets of the array and then send the data back out to other processes?
The answer to that is yes, as long as you synchronize between the receives and sends. Remember that the data from the MPI_IRECV won't have arrived until you've completed the call with MPI_WAIT, so you can't send it to another process until that's happened. Otherwise, the sends will be sending out whatever garbage happens to be in the buffer at the time.
So your code can look like this and be safe:
for (i = 0; i < size; i++)
MPI_Irecv(&data[i*100], 100, MPI_INT, i, 0, comm, &requests[i]);
/* No touching data in here */
MPI_Waitall(i, requests, statuses);
/* You can touch data here */
for (i = 0; i < size; i++)
MPI_Isend(&data[i*100], 100, MPI_INT, i+1, 0, comm); /* i+1 is wherever you want to send the data */
/* No touching data in here either */
MPI_Waitall(i, requests, statuses);
Throughout the MPI standard the term locations is used and not the term variables in order to prevent such confusion. The MPI library does not care where the memory comes from as long outstanding MPI operations are operating on disjoint sets of memory locations. Different memory locations could be different variables or different elements of a big array. In fact, the whole process memory could be thought as one big anonymous array of bytes.
In many cases, it is possible to achieve the same memory layout given different set of variable declarations. For example, with most x86/x64 C/C++ compilers the following two sets of local variable declarations will result in the same stack layout:
int a, b; int d[3];
int c;
| .... | | .... | |
+--------------+ +--------------+ |
| a | | d[2] | |
+--------------+ +--------------+ | lower addresses
| b | | d[1] | |
+--------------+ +--------------+ |
| c | | d[0] | \|/
+--------------+ +--------------+ V
In that case:
int a, b;
int c;
MPI_Irecv(&a, 1, MPI_INT, ..., &req[0]);
MPI_Irecv(&c, 1, MPI_INT, ..., &req[1]);
MPI_Waitall(2, &req, MPI_STATUSES_IGNORE);
is equivalent to:
int d[3];
MPI_Irecv(&d[2], 1, MPI_INT, ..., &req[0]);
MPI_Irecv(&d[0], 1, MPI_INT, ..., &req[1]);
MPI_Waitall(2, &req, MPI_STATUSES_IGNORE);
In the second case, though d[0] and d[2] belong to the same variable, &d[0] and &d[2] specify different and - in combination with ..., 1, MPI_INT, ... - disjoint memory locations.
In any case, make sure that you are not simultaneously reading from and writing into the same memory location.
A somehow more complex version of the example given by Wesley Bland follows. It overlaps send and receive operations by using MPI_Waitsome instead:
MPI_Request rreqs[size], sreqs[size];
for (i = 0; i < size; i++)
MPI_Irecv(&data[i*100], 100, MPI_INT, i, 0, comm, &rreqs[i]);
while (1)
{
int done_idx[size], numdone;
MPI_Waitsome(size, rreqs, &numdone, done_idx, MPI_STATUSES_IGNORE);
if (numdone == MPI_UNDEFINED)
break;
for (i = 0; i < numdone; i++)
{
int id = done_idx[i];
process(&data[id*100], 100);
MPI_Isend(&data[id*100], 100, MPI_INT, id, 0, comm, &sreqs[id]);
}
}
MPI_Waitall(size, sreqs, MPI_STATUSES_IGNORE);
In that particular case, using size separate arrays could result in somehow more readable code.

Atmega 2560 USART not giving correct value on terminal

I am working on the serial communication of my MultiWii Pro board, which is based on a atmega2560. I am using avr-gcc to compile and avrdude to program.
Here is my problem. I am trying to get atmega2560 to send something (hex value) to the terminal. However, regardless of the value assigned to UDR2 and regardless the value I assigned to UBRR2L and UBRR2H, the terminal output is always 0xff if I set the terminal baud-rate at 9600, and 0xff if I set the terminal baud-rate at 115200.
Here is my code
#define F_CPU 8000000UL
#define BAUDRATE 19200 //The baudrate to use
#define BAUD_PRESCALLER ((F_CPU / (BAUDRATE * 16UL))-1)
static void InitializeUART()
{
UBRR2L = (uint8_t)(BAUD_PRESCALLER);
UBRR2H = (uint8_t)(BAUD_PRESCALLER>>8);
UCSR2B |= (1<<RXEN2) | (1<<TXEN2); //RX TX Enable
UCSR2C |= (1<<USBS2)|(1<<UCSZ21)|(1<<UCSZ20);
}
And my sending function
void USART2Write(char data)
{
while( !(UCSR2A & (1<<UDRE2)));
UCSR2B &= ~(1<<TXB82); //in the case if there are more than 8 bits of data
if(data & 0x100)
{
UCSR2B |= (1 << TXB82);
}
UDR2 = data;
}
In my case, the baudrate of my code is 19200. The terminal baudrate is also 19200. No matter what I assigned to UDR2, the output will always be 0x15.
Here is my fuse setting
Low High Extended
0xFF 0xD8 0xFD
UCSR2C |= (1<<USBS2)|(1<<UCSZ21)|(1<<UCSZ20);
USBS2 sets 2 stop bits. Is this intentional?
void USART2Write(char data){
while( !(UCSR2A & (1<<UDRE2)));
UCSR2B &= ~(1<<TXB82); //in the case if there are more than 8 bits of data
if(data & 0x100) {
UCSR2B |= (1 << TXB82);
}
UDR2 = data;
}
If you really want to use 9 data bits, UCSZ22, UCSZ21 and UCSZ20 have to be set. YOu only set UCSZ21 and UCSZ20
UCSR2C |= (1<<USBS2) | (1<<UCSZ21) | (1<<UCSZ20);
so I guess that USBS2 is indeed not what you want here. Maybe you were confused because the flag UCSZ22 is in the UCSR2B register.
So assuming you want 9 data bits and one stop bit use something like this:
static void InitializeUART() {
UBRR2L = (uint8_t)(BAUD_PRESCALLER);
UBRR2H = (uint8_t)(BAUD_PRESCALLER>>8);
UCSR2B |= (1 << RXEN2) | (1 << TXEN2) | (1 << UCSZ22);
UCSR2C |= (1 << UCSZ21) | (1 << UCSZ20);
}
Another thing: Your variable data is of type char and char is normally 8 bit wide. So the condition if(data & 0x100) is never satisfied.

Resources