|
|
|
@ -1,4 +1,5 @@ |
|
|
|
#include "src/kernel/pipe.h" |
|
|
|
#include "src/kernel/pipe.h" |
|
|
|
|
|
|
|
#include "src/kernel/process.h" |
|
|
|
#include "src/kernel/stream.h" |
|
|
|
#include "src/kernel/stream.h" |
|
|
|
#include "src/lib/memory.h" |
|
|
|
#include "src/lib/memory.h" |
|
|
|
|
|
|
|
|
|
|
|
@ -35,16 +36,17 @@ static uint64_t null_write(__attribute__((unused)) const stream_t *self, __attri |
|
|
|
static uint64_t pipe_read(const stream_t *self, uint64_t max, char *to) { |
|
|
|
static uint64_t pipe_read(const stream_t *self, uint64_t max, char *to) { |
|
|
|
pipe_t *pipe = ((pipe_read_stream_t *)self)->pipe; |
|
|
|
pipe_t *pipe = ((pipe_read_stream_t *)self)->pipe; |
|
|
|
|
|
|
|
|
|
|
|
uint64_t available = (pipe->end + PIPE_BUFFER_SIZE - pipe->begin) % PIPE_BUFFER_SIZE; |
|
|
|
while (pipe->begin == pipe->end) { |
|
|
|
uint64_t to_read = available < max ? available : max; |
|
|
|
if (pipe->write_closed) { |
|
|
|
|
|
|
|
return 0; |
|
|
|
if (pipe->write_closed && !to_read) { |
|
|
|
} |
|
|
|
return (uint64_t)-1; |
|
|
|
__asm__ volatile("sti"); |
|
|
|
|
|
|
|
process_next(); |
|
|
|
|
|
|
|
__asm__ volatile("cli"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!to_read) { |
|
|
|
uint64_t available = (pipe->end + PIPE_BUFFER_SIZE - pipe->begin) % PIPE_BUFFER_SIZE; |
|
|
|
return 0; |
|
|
|
uint64_t to_read = available < max ? available : max; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (pipe->begin + to_read <= PIPE_BUFFER_SIZE) { |
|
|
|
if (pipe->begin + to_read <= PIPE_BUFFER_SIZE) { |
|
|
|
memory_copy(pipe->buffer + pipe->begin, to_read, to); |
|
|
|
memory_copy(pipe->buffer + pipe->begin, to_read, to); |
|
|
|
@ -61,27 +63,33 @@ static uint64_t pipe_read(const stream_t *self, uint64_t max, char *to) { |
|
|
|
static uint64_t pipe_write(const stream_t *self, const char *from, uint64_t bytes) { |
|
|
|
static uint64_t pipe_write(const stream_t *self, const char *from, uint64_t bytes) { |
|
|
|
pipe_t *pipe = ((pipe_read_stream_t *)self)->pipe; |
|
|
|
pipe_t *pipe = ((pipe_read_stream_t *)self)->pipe; |
|
|
|
|
|
|
|
|
|
|
|
if (pipe->read_closed) { |
|
|
|
uint64_t written = 0; |
|
|
|
return (uint64_t)-1; |
|
|
|
while (written < bytes) { |
|
|
|
} |
|
|
|
while (((pipe->end + 1) % PIPE_BUFFER_SIZE) == pipe->begin) { |
|
|
|
|
|
|
|
if (pipe->read_closed) { |
|
|
|
uint64_t available = PIPE_BUFFER_SIZE - (pipe->end + PIPE_BUFFER_SIZE - pipe->begin) % PIPE_BUFFER_SIZE; |
|
|
|
return written; |
|
|
|
uint64_t to_write = available < bytes ? available : bytes; |
|
|
|
} |
|
|
|
|
|
|
|
__asm__ volatile("sti"); |
|
|
|
if (to_write == 0) { |
|
|
|
process_next(); |
|
|
|
return 0; |
|
|
|
__asm__ volatile("cli"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (pipe->end + to_write <= PIPE_BUFFER_SIZE) { |
|
|
|
uint64_t available = PIPE_BUFFER_SIZE - (pipe->end + PIPE_BUFFER_SIZE - pipe->begin) % PIPE_BUFFER_SIZE - 1; |
|
|
|
memory_copy(from, to_write, pipe->buffer + pipe->end); |
|
|
|
uint64_t to_write = available < bytes - written ? available : bytes - written; |
|
|
|
} else { |
|
|
|
|
|
|
|
uint64_t chunk = PIPE_BUFFER_SIZE - pipe->end; |
|
|
|
if (pipe->end + to_write <= PIPE_BUFFER_SIZE) { |
|
|
|
memory_copy(from, chunk, pipe->buffer + pipe->end); |
|
|
|
memory_copy(from, to_write, pipe->buffer + pipe->end); |
|
|
|
memory_copy(from + chunk, to_write - chunk, pipe->buffer); |
|
|
|
} else { |
|
|
|
|
|
|
|
uint64_t chunk = PIPE_BUFFER_SIZE - pipe->end; |
|
|
|
|
|
|
|
memory_copy(from, chunk, pipe->buffer + pipe->end); |
|
|
|
|
|
|
|
memory_copy(from + chunk, to_write - chunk, pipe->buffer); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pipe->end = (pipe->end + to_write) % PIPE_BUFFER_SIZE; |
|
|
|
|
|
|
|
written += to_write; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pipe->end = (pipe->end + to_write) % PIPE_BUFFER_SIZE; |
|
|
|
return written; |
|
|
|
return to_write; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void read_close(stream_t *self) { |
|
|
|
static void read_close(stream_t *self) { |
|
|
|
|