Merge branch 'strawberry-dev' of https://github.com/graphitemaster/toaruos into graphitemaster-strawberry-dev

This commit is contained in:
Kevin Lange 2015-05-21 14:33:22 -07:00
commit 25807666f9
40 changed files with 1131 additions and 739 deletions

View File

@ -164,8 +164,7 @@ test: system
toolchain:
@cd toolchain; ./toolchain-build.sh
# boot.omust be first
KERNEL_ASMOBJS += $(filter-out kernel/symbols.o,$(patsubst %.S,%.o,$(wildcard kernel/*.S)))
KERNEL_ASMOBJS = $(filter-out kernel/symbols.o,$(patsubst %.S,%.o,$(wildcard kernel/*.S)))
################
# Kernel #

View File

@ -41,8 +41,11 @@ stack_top:
start:
/* Setup our stack */
mov $stack_top, %esp
pushl %esp
/* Make sure our stack is 16-byte aligned */
and $-16, %esp
pushl %esp
pushl %eax /* Multiboot header magic */
pushl %ebx /* Multiboot header pointer */

View File

@ -74,7 +74,7 @@ void gdt_install(void) {
}
static void write_tss(int32_t num, uint16_t ss0, uint32_t esp0) {
tss_entry_t *tss = &gdt.tss;
tss_entry_t * tss = &gdt.tss;
uintptr_t base = (uintptr_t)tss;
uintptr_t limit = base + sizeof *tss;

View File

@ -44,7 +44,7 @@ void idt_set_gate(uint8_t num, idt_gate_t base, uint16_t sel, uint8_t flags) {
}
void idt_install(void) {
idt_pointer_t *idtp = &idt.pointer;
idt_pointer_t * idtp = &idt.pointer;
idtp->limit = sizeof idt.entries - 1;
idtp->base = (uintptr_t)&ENTRY(0);
memset(&ENTRY(0), 0, sizeof idt.entries);

View File

@ -9,35 +9,81 @@
*/
#include <system.h>
#include <logging.h>
#include <module.h>
#include <printf.h>
extern void _irq0(void);
extern void _irq1(void);
extern void _irq2(void);
extern void _irq3(void);
extern void _irq4(void);
extern void _irq5(void);
extern void _irq6(void);
extern void _irq7(void);
extern void _irq8(void);
extern void _irq9(void);
extern void _irq10(void);
extern void _irq11(void);
extern void _irq12(void);
extern void _irq13(void);
extern void _irq14(void);
extern void _irq15(void);
/* Programmable interrupt controller */
#define PIC1 0x20
#define PIC1_COMMAND PIC1
#define PIC1_OFFSET 0x20
#define PIC1_DATA (PIC1+1)
static void (*irqs[])(void) = {
_irq0, _irq1, _irq2, _irq3, _irq4, _irq5, _irq6, _irq7,
_irq8, _irq9, _irq10, _irq11, _irq12, _irq13, _irq14, _irq15
};
#define PIC2 0xA0
#define PIC2_COMMAND PIC2
#define PIC2_OFFSET 0x28
#define PIC2_DATA (PIC2+1)
#define IRQ_CHAIN_SIZE (sizeof(irqs)/sizeof(*irqs))
#define IRQ_CHAIN_DEPTH 4
#define PIC_EOI 0x20
#define ICW1_ICW4 0x01
#define ICW1_INIT 0x10
#define PIC_WAIT() \
do { \
/* May be fragile */ \
asm volatile("jmp 1f\n\t" \
"1:\n\t" \
" jmp 2f\n\t" \
"2:"); \
} while (0)
/* Interrupts */
static volatile int sync_depth = 0;
#define SYNC_CLI() asm volatile("cli")
#define SYNC_STI() asm volatile("sti")
void int_disable(void) {
/* Check if interrupts are enabled */
uint32_t flags;
asm volatile("pushf\n\t"
"pop %%eax\n\t"
"movl %%eax, %0\n\t"
: "=r"(flags)
:
: "%eax");
/* Disable interrupts */
SYNC_CLI();
/* If interrupts were enabled, then this is the first call depth */
if (flags & (1 << 9)) {
sync_depth = 1;
} else {
/* Otherwise there is now an additional call depth */
sync_depth++;
}
}
void int_resume(void) {
/* If there is one or no call depths, reenable interrupts */
if (sync_depth == 0 || sync_depth == 1) {
SYNC_STI();
} else {
sync_depth--;
}
}
void int_enable(void) {
sync_depth = 0;
SYNC_STI();
}
/* Interrupt Requests */
#define IRQ_CHAIN_SIZE 16
#define IRQ_CHAIN_DEPTH 4
static void (*irqs[IRQ_CHAIN_SIZE])(void);
static irq_handler_chain_t irq_routines[IRQ_CHAIN_SIZE * IRQ_CHAIN_DEPTH] = { NULL };
void irq_install_handler(size_t irq, irq_handler_chain_t handler) {
@ -52,7 +98,6 @@ void irq_install_handler(size_t irq, irq_handler_chain_t handler) {
SYNC_STI();
}
void irq_uninstall_handler(size_t irq) {
/* Disable interrupts when changing handlers */
SYNC_CLI();
@ -61,83 +106,59 @@ void irq_uninstall_handler(size_t irq) {
SYNC_STI();
}
static void irq_remap(void) {
/* Cascade initialization */
outportb(PIC1_COMMAND, ICW1_INIT|ICW1_ICW4); PIC_WAIT();
outportb(PIC2_COMMAND, ICW1_INIT|ICW1_ICW4); PIC_WAIT();
void irq_remap(void) {
outportb(0x20, 0x11);
outportb(0xA0, 0x11);
outportb(0x21, 0x20);
outportb(0xA1, 0x28);
outportb(0x21, 0x04);
outportb(0xA1, 0x02);
outportb(0x21, 0x01);
outportb(0xA1, 0x01);
outportb(0x21, 0x0);
outportb(0xA1, 0x0);
/* Remap */
outportb(PIC1_DATA, PIC1_OFFSET); PIC_WAIT();
outportb(PIC2_DATA, PIC2_OFFSET); PIC_WAIT();
/* Cascade identity with slave PIC at IRQ2 */
outportb(PIC1_DATA, 0x04); PIC_WAIT();
outportb(PIC2_DATA, 0x02); PIC_WAIT();
/* Request 8086 mode on each PIC */
outportb(PIC1_DATA, 0x01); PIC_WAIT();
outportb(PIC2_DATA, 0x01); PIC_WAIT();
}
static void irq_setup_gates(void) {
for (size_t i = 0; i < IRQ_CHAIN_SIZE; i++)
for (size_t i = 0; i < IRQ_CHAIN_SIZE; i++) {
idt_set_gate(32 + i, irqs[i], 0x08, 0x8E);
}
}
void irq_install(void) {
char buffer[16];
for (int i = 0; i < IRQ_CHAIN_SIZE; i++) {
sprintf(buffer, "_irq%d", i);
irqs[i] = symbol_find(buffer);
}
irq_remap();
irq_setup_gates();
}
/* TODO: Clean up everything below */
void irq_ack(size_t irq_no) {
if (irq_no >= 8) {
outportb(0xA0, 0x20);
outportb(PIC2_COMMAND, PIC_EOI);
}
outportb(0x20, 0x20);
outportb(PIC1_COMMAND, PIC_EOI);
}
void irq_handler(struct regs *r) {
IRQ_OFF;
if (r->int_no > 47 || r->int_no < 32) {
IRQ_RES;
return;
}
for (size_t i = 0; i < IRQ_CHAIN_DEPTH; i++) {
irq_handler_chain_t handler = irq_routines[i * IRQ_CHAIN_SIZE + (r->int_no - 32)];
if (handler && handler(r)) {
goto _done;
/* Disable interrupts when handling */
int_disable();
if (r->int_no <= 47 && r->int_no >= 32) {
for (size_t i = 0; i < IRQ_CHAIN_DEPTH; i++) {
irq_handler_chain_t handler = irq_routines[i * IRQ_CHAIN_SIZE + (r->int_no - 32)];
if (handler && handler(r)) {
goto done;
}
}
irq_ack(r->int_no - 32);
}
irq_ack(r->int_no - 32);
_done:
IRQ_RES;
}
static int _irq_sem = 0;
void irq_off(void) {
uint32_t eflags;
asm volatile(
"pushf\n"
"pop %0\n"
"cli"
: "=r" (eflags));
if (eflags & (1 << 9)) {
_irq_sem = 1;
} else {
_irq_sem++;
}
}
void irq_res(void) {
if (_irq_sem == 0) {
asm volatile ("sti");
return;
}
_irq_sem--;
if (_irq_sem == 0) {
asm volatile ("sti");
}
}
void irq_on(void) {
_irq_sem = 0;
asm volatile ("sti");
done:
int_resume();
}

94
kernel/cpu/isr.c Normal file
View File

@ -0,0 +1,94 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2011-2014 Kevin Lange
* Copyright (C) 2015 Dale Weiler
*
* Interrupt Service Requests
*/
#include <system.h>
#include <logging.h>
#include <module.h>
#include <printf.h>
/* The count is treated as is when setting up IDT gates. However there is an
* additional ISR for the system call vector which is handled explicitly since
* it's mapped at a different address.
*/
#define ISR_COUNT 32
static struct {
size_t index;
void (*stub)(void);
} isrs[32 + 1] __attribute__((used));
static irq_handler_t isr_routines[256] = { 0 };
void isrs_install_handler(size_t isrs, irq_handler_t handler) {
isr_routines[isrs] = handler;
}
void isrs_uninstall_handler(size_t isrs) {
isr_routines[isrs] = 0;
}
void isrs_install(void) {
char buffer[16];
for (int i = 0; i < ISR_COUNT; i++) {
sprintf(buffer, "_isr%d", i);
isrs[i].index = i;
isrs[i].stub = symbol_find(buffer);
}
isrs[ISR_COUNT].index = SYSCALL_VECTOR;
isrs[ISR_COUNT].stub = symbol_find("_isr127");
for (int i = 0; i < ISR_COUNT + 1; i++) {
idt_set_gate(isrs[i].index, isrs[i].stub, 0x08, 0x8E);
}
}
static const char *exception_messages[32] = {
"Division by zero",
"Debug",
"Non-maskable interrupt",
"Breakpoint",
"Detected overflow",
"Out-of-bounds",
"Invalid opcode",
"No coprocessor",
"Double fault",
"Coprocessor segment overrun",
"Bad TSS",
"Segment not present",
"Stack fault",
"General protection fault",
"Page fault",
"Unknown interrupt",
"Coprocessor fault",
"Alignment check",
"Machine check",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved"
};
void fault_handler(struct regs * r) {
irq_handler_t handler = isr_routines[r->int_no];
if (handler) {
handler(r);
} else {
debug_print(CRITICAL, "Unhandled exception: [%d] %s", r->int_no, exception_messages[r->int_no]);
HALT_AND_CATCH_FIRE("Process caused an unhandled exception", r);
STOP;
}
}

View File

@ -1,22 +0,0 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2011-2014 Kevin Lange
*
* Interrupt Services Requests
*/
#include <system.h>
#include <logging.h>
extern irq_handler_t isrs_routines[256];
extern void fault_error(struct regs *r);
void fault_handler(struct regs *r) {
irq_handler_t handler;
handler = isrs_routines[r->int_no];
if (handler) {
handler(r);
} else {
fault_error(r);
}
}

View File

@ -1,134 +0,0 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2013-2014 Kevin Lange
*/
#include <system.h>
#include <logging.h>
/*
* Exception Handlers
*/
extern void _isr0 (void);
extern void _isr1 (void);
extern void _isr2 (void);
extern void _isr3 (void);
extern void _isr4 (void);
extern void _isr5 (void);
extern void _isr6 (void);
extern void _isr7 (void);
extern void _isr8 (void);
extern void _isr9 (void);
extern void _isr10(void);
extern void _isr11(void);
extern void _isr12(void);
extern void _isr13(void);
extern void _isr14(void);
extern void _isr15(void);
extern void _isr16(void);
extern void _isr17(void);
extern void _isr18(void);
extern void _isr19(void);
extern void _isr20(void);
extern void _isr21(void);
extern void _isr22(void);
extern void _isr23(void);
extern void _isr24(void);
extern void _isr25(void);
extern void _isr26(void);
extern void _isr27(void);
extern void _isr28(void);
extern void _isr29(void);
extern void _isr30(void);
extern void _isr31(void);
extern void _isr127(void);
irq_handler_t isrs_routines[256] = { NULL };
void isrs_install_handler(size_t isrs, irq_handler_t handler) {
isrs_routines[isrs] = handler;
}
void isrs_uninstall_handler(size_t isrs) {
isrs_routines[isrs] = 0;
}
void isrs_install(void) {
/* Exception Handlers */
memset(isrs_routines, 0x00, sizeof(isrs_routines));
idt_set_gate(0, _isr0, 0x08, 0x8E);
idt_set_gate(1, _isr1, 0x08, 0x8E);
idt_set_gate(2, _isr2, 0x08, 0x8E);
idt_set_gate(3, _isr3, 0x08, 0x8E);
idt_set_gate(4, _isr4, 0x08, 0x8E);
idt_set_gate(5, _isr5, 0x08, 0x8E);
idt_set_gate(6, _isr6, 0x08, 0x8E);
idt_set_gate(7, _isr7, 0x08, 0x8E);
idt_set_gate(8, _isr8, 0x08, 0x8E);
idt_set_gate(9, _isr9, 0x08, 0x8E);
idt_set_gate(10, _isr10, 0x08, 0x8E);
idt_set_gate(11, _isr11, 0x08, 0x8E);
idt_set_gate(12, _isr12, 0x08, 0x8E);
idt_set_gate(13, _isr13, 0x08, 0x8E);
idt_set_gate(14, _isr14, 0x08, 0x8E);
idt_set_gate(15, _isr15, 0x08, 0x8E);
idt_set_gate(16, _isr16, 0x08, 0x8E);
idt_set_gate(17, _isr17, 0x08, 0x8E);
idt_set_gate(18, _isr18, 0x08, 0x8E);
idt_set_gate(19, _isr19, 0x08, 0x8E);
idt_set_gate(20, _isr20, 0x08, 0x8E);
idt_set_gate(21, _isr21, 0x08, 0x8E);
idt_set_gate(22, _isr22, 0x08, 0x8E);
idt_set_gate(23, _isr23, 0x08, 0x8E);
idt_set_gate(24, _isr24, 0x08, 0x8E);
idt_set_gate(25, _isr25, 0x08, 0x8E);
idt_set_gate(26, _isr26, 0x08, 0x8E);
idt_set_gate(27, _isr27, 0x08, 0x8E);
idt_set_gate(28, _isr28, 0x08, 0x8E);
idt_set_gate(29, _isr29, 0x08, 0x8E);
idt_set_gate(30, _isr30, 0x08, 0x8E);
idt_set_gate(31, _isr31, 0x08, 0x8E);
idt_set_gate(SYSCALL_VECTOR, _isr127, 0x08, 0x8E);
}
static const char *exception_messages[32] = {
"Division by zero", /* 0 */
"Debug",
"Non-maskable interrupt",
"Breakpoint",
"Detected overflow",
"Out-of-bounds", /* 5 */
"Invalid opcode",
"No coprocessor",
"Double fault",
"Coprocessor segment overrun",
"Bad TSS", /* 10 */
"Segment not present",
"Stack fault",
"General protection fault",
"Page fault",
"Unknown interrupt", /* 15 */
"Coprocessor fault",
"Alignment check",
"Machine check",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved"
};
void fault_error(struct regs *r) {
debug_print(CRITICAL, "Unhandled exception: [%d] %s", r->int_no, exception_messages[r->int_no]);
HALT_AND_CATCH_FIRE("Process caused an unhandled exception", r);
STOP;
}

64
kernel/ds/bitset.c Normal file
View File

@ -0,0 +1,64 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2015 Dale Weiler
*/
#include "bitset.h"
#define CEIL(NUMBER, BASE) \
(((NUMBER) + (BASE) - 1) & ~((BASE) - 1))
void bitset_init(bitset_t *set, size_t size) {
set->size = CEIL(size, 8);
set->data = malloc(set->size);
}
void bitset_free(bitset_t *set) {
free(set->data);
}
static void bitset_resize(bitset_t *set, size_t size) {
if (set->size >= size) {
return;
}
unsigned char *temp = malloc(size);
memcpy(temp, set->data, set->size);
free(set->data);
set->data = temp;
set->size = size;
}
void bitset_set(bitset_t *set, size_t bit) {
size_t index = bit >> 3;
if (set->size <= index) {
bitset_resize(set, set->size << 1);
}
size_t offset = index & 7;
size_t mask = 1 << offset;
set->data[index] |= mask;
}
int bitset_ffub(bitset_t *set) {
for (size_t i = 0; i < set->size * 8; i++) {
if (bitset_test(set, i)) {
continue;
}
return (int)i;
}
return -1;
}
void bitset_clear(bitset_t *set, size_t bit) {
size_t index = bit >> 3;
size_t offset = index & 7;
size_t mask = 1 << offset;
set->data[index] &= ~mask;
}
int bitset_test(bitset_t *set, size_t bit) {
size_t index = bit >> 3;
size_t offset = index & 7;
size_t mask = 1 << offset;
return mask & set->data[index];
}

View File

@ -51,13 +51,13 @@ static inline void ring_buffer_increment_write(ring_buffer_t * ring_buffer) {
size_t ring_buffer_read(ring_buffer_t * ring_buffer, size_t size, uint8_t * buffer) {
size_t collected = 0;
while (collected == 0) {
spin_lock(&ring_buffer->lock);
spin_lock(ring_buffer->lock);
while (ring_buffer_unread(ring_buffer) > 0 && collected < size) {
buffer[collected] = ring_buffer->buffer[ring_buffer->read_ptr];
ring_buffer_increment_read(ring_buffer);
collected++;
}
spin_unlock(&ring_buffer->lock);
spin_unlock(ring_buffer->lock);
wakeup_queue(ring_buffer->wait_queue_writers);
if (collected == 0) {
if (sleep_on(ring_buffer->wait_queue_readers) && ring_buffer->internal_stop) {
@ -73,7 +73,7 @@ size_t ring_buffer_read(ring_buffer_t * ring_buffer, size_t size, uint8_t * buff
size_t ring_buffer_write(ring_buffer_t * ring_buffer, size_t size, uint8_t * buffer) {
size_t written = 0;
while (written < size) {
spin_lock(&ring_buffer->lock);
spin_lock(ring_buffer->lock);
while (ring_buffer_available(ring_buffer) > 0 && written < size) {
ring_buffer->buffer[ring_buffer->write_ptr] = buffer[written];
@ -81,7 +81,7 @@ size_t ring_buffer_write(ring_buffer_t * ring_buffer, size_t size, uint8_t * buf
written++;
}
spin_unlock(&ring_buffer->lock);
spin_unlock(ring_buffer->lock);
wakeup_queue(ring_buffer->wait_queue_readers);
if (written < size) {
if (sleep_on(ring_buffer->wait_queue_writers) && ring_buffer->internal_stop) {
@ -101,9 +101,10 @@ ring_buffer_t * ring_buffer_create(size_t size) {
out->buffer = malloc(size);
out->write_ptr = 0;
out->read_ptr = 0;
out->lock = 0;
out->size = size;
spin_init(out->lock);
out->internal_stop = 0;
out->wait_queue_readers = list_create();

View File

@ -97,13 +97,13 @@ uint32_t read_pipe(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buf
size_t collected = 0;
while (collected == 0) {
spin_lock(&pipe->lock_read);
spin_lock(pipe->lock_read);
while (pipe_unread(pipe) > 0 && collected < size) {
buffer[collected] = pipe->buffer[pipe->read_ptr];
pipe_increment_read(pipe);
collected++;
}
spin_unlock(&pipe->lock_read);
spin_unlock(pipe->lock_read);
wakeup_queue(pipe->wait_queue_writers);
/* Deschedule and switch */
if (collected == 0) {
@ -141,7 +141,7 @@ uint32_t write_pipe(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *bu
size_t written = 0;
while (written < size) {
spin_lock(&pipe->lock_write);
spin_lock(pipe->lock_write);
#if 0
size_t available = 0;
@ -164,7 +164,7 @@ uint32_t write_pipe(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *bu
}
#endif
spin_unlock(&pipe->lock_write);
spin_unlock(pipe->lock_write);
wakeup_queue(pipe->wait_queue_readers);
if (written < size) {
sleep_on(pipe->wait_queue_writers);
@ -242,10 +242,11 @@ fs_node_t * make_pipe(size_t size) {
pipe->read_ptr = 0;
pipe->size = size;
pipe->refcount = 0;
pipe->lock_read = 0;
pipe->lock_write= 0;
pipe->dead = 0;
spin_init(pipe->lock_read);
spin_init(pipe->lock_write);
pipe->wait_queue_writers = list_create();
pipe->wait_queue_readers = list_create();

View File

@ -202,8 +202,6 @@ int pty_ioctl(pty_t * pty, int request, void * argp) {
}
}
#define MIN(a,b) ((a) < (b) ? (a) : (b))
uint32_t read_pty_master(fs_node_t * node, uint32_t offset, uint32_t size, uint8_t *buffer) {
pty_t * pty = (pty_t *)node->device;

View File

@ -48,7 +48,8 @@ static struct dirent * readdir_mapper(fs_node_t *node, uint32_t index) {
struct vfs_entry * n = (struct vfs_entry *)tchild->value;
struct dirent * dir = malloc(sizeof(struct dirent));
memcpy(&dir->name, n->name, min(256, strlen(n->name)+1));
size_t len = strlen(n->name) + 1;
memcpy(&dir->name, n->name, MIN(256, len));
dir->ino = i;
return dir;
}
@ -108,12 +109,13 @@ uint32_t write_fs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buff
}
}
volatile uint8_t tmp_refcount_lock = 0;
//volatile uint8_t tmp_refcount_lock = 0;
static spin_lock_t tmp_refcount_lock = { 0 };
void vfs_lock(fs_node_t * node) {
spin_lock(&tmp_refcount_lock);
spin_lock(tmp_refcount_lock);
node->refcount = -1;
spin_unlock(&tmp_refcount_lock);
spin_unlock(tmp_refcount_lock);
}
/**
@ -127,9 +129,9 @@ void open_fs(fs_node_t *node, unsigned int flags) {
if (!node) return;
if (node->refcount >= 0) {
spin_lock(&tmp_refcount_lock);
spin_lock(tmp_refcount_lock);
node->refcount++;
spin_unlock(&tmp_refcount_lock);
spin_unlock(tmp_refcount_lock);
}
if (node->open) {
@ -152,7 +154,7 @@ void close_fs(fs_node_t *node) {
if (node->refcount == -1) return;
spin_lock(&tmp_refcount_lock);
spin_lock(tmp_refcount_lock);
node->refcount--;
if (node->refcount == 0) {
debug_print(NOTICE, "Node refcount [%s] is now 0: %d", node->name, node->refcount);
@ -163,7 +165,7 @@ void close_fs(fs_node_t *node) {
free(node);
}
spin_unlock(&tmp_refcount_lock);
spin_unlock(tmp_refcount_lock);
}
/**
@ -355,9 +357,9 @@ fs_node_t *clone_fs(fs_node_t *source) {
if (!source) return NULL;
if (source->refcount >= 0) {
spin_lock(&tmp_refcount_lock);
spin_lock(tmp_refcount_lock);
source->refcount++;
spin_unlock(&tmp_refcount_lock);
spin_unlock(tmp_refcount_lock);
}
return source;
@ -520,7 +522,8 @@ int vfs_mount_type(char * type, char * arg, char * mountpoint) {
return 0;
}
volatile uint8_t tmp_vfs_lock = 0;
//volatile uint8_t tmp_vfs_lock = 0;
static spin_lock_t tmp_vfs_lock = { 0 };
/**
* vfs_mount - Mount a file system to the specified path.
*
@ -542,7 +545,7 @@ void * vfs_mount(char * path, fs_node_t * local_root) {
return NULL;
}
spin_lock(&tmp_vfs_lock);
spin_lock(tmp_vfs_lock);
local_root->refcount = -1;
@ -614,7 +617,7 @@ void * vfs_mount(char * path, fs_node_t * local_root) {
}
free(p);
spin_unlock(&tmp_vfs_lock);
spin_unlock(tmp_vfs_lock);
return ret_val;
}

20
kernel/include/bitset.h Normal file
View File

@ -0,0 +1,20 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
*/
#ifndef BITSET_H
#define BITSET_H
#include <system.h>
typedef struct {
unsigned char *data;
size_t size;
} bitset_t;
void bitset_init(bitset_t *set, size_t size);
void bitset_free(bitset_t *set);
void bitset_set(bitset_t *set, size_t bit);
void bitset_clear(bitset_t *set, size_t bit);
int bitset_test(bitset_t *set, size_t bit);
/* Find first unset bit */
int bitset_ffub(bitset_t *set);
#endif

38
kernel/include/libc.h Normal file
View File

@ -0,0 +1,38 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
*/
#ifndef __LIBC_H
#define __LIBC_H
#include <stddef.h>
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#define MAX(A, B) ((A) > (B) ? (A) : (B))
extern void * memcpy(void * restrict dest, const void * restrict src, size_t n);
extern void * memset(void * dest, int c, size_t n);
extern void * memchr(const void * src, int c, size_t n);
extern void * memrchr(const void * m, int c, size_t n);
extern void * memmove(void *dest, const void *src, size_t n);
extern int memcmp(const void *vl, const void *vr, size_t n);
extern char * strdup(const char * s);
extern char * stpcpy(char * restrict d, const char * restrict s);
extern char * strcpy(char * restrict dest, const char * restrict src);
extern char * strchrnul(const char * s, int c);
extern char * strchr(const char * s, int c);
extern char * strrchr(const char * s, int c);
extern char * strpbrk(const char * s, const char * b);
extern char * strstr(const char * h, const char * n);
extern int strcmp(const char * l, const char * r);
extern size_t strcspn(const char * s, const char * c);
extern size_t strspn(const char * s, const char * c);
extern size_t strlen(const char * s);
extern int atoi(const char * s);
/* Non-standard broken strtok_r */
extern char * strtok_r(char * str, const char * delim, char ** saveptr);
#endif

View File

@ -3,7 +3,6 @@
#include <fs.h>
fs_node_t * tmpfs_create(char * name);
uint8_t volatile tmpfs_lock;
struct tmpfs_file {
char * name;

View File

@ -19,6 +19,8 @@ typedef struct {
char * deps;
} module_data_t;
void (* symbol_find(const char * name))(void);
extern int module_quickcheck(void * blob);
extern void * module_load_direct(void * blob, size_t size);
extern void * module_load(char * filename);

View File

@ -14,8 +14,8 @@ typedef struct _pipe_device {
size_t read_ptr;
size_t size;
size_t refcount;
uint8_t volatile lock_read;
uint8_t volatile lock_write;
volatile int lock_read[2];
volatile int lock_write[2];
list_t * wait_queue_readers;
list_t * wait_queue_writers;
int dead;

View File

@ -48,7 +48,7 @@ typedef struct image {
uintptr_t user_stack; /* User stack */
uintptr_t start;
uintptr_t shm_heap;
volatile uint8_t lock;
volatile int lock[2];
} image_t;
/* Resizable descriptor table */

View File

@ -6,7 +6,7 @@ typedef struct {
size_t write_ptr;
size_t read_ptr;
size_t size;
uint8_t volatile lock;
volatile int lock[2];
list_t * wait_queue_readers;
list_t * wait_queue_writers;
int internal_stop;

View File

@ -8,6 +8,7 @@
#include <list.h>
#include <task.h>
#include <process.h>
#include <libc.h>
#define STR(x) #x
#define STRSTR(x) STR(x)
@ -15,15 +16,13 @@
#define asm __asm__
#define volatile __volatile__
extern unsigned int __irq_sem;
void int_disable(void);
void int_resume(void);
void int_enable(void);
void irq_off(void);
void irq_res(void);
void irq_on(void);
#define IRQ_OFF irq_off()
#define IRQ_RES irq_res()
#define IRQ_ON irq_on()
#define IRQ_OFF int_disable()
#define IRQ_RES int_resume()
#define IRQ_ON int_enable()
#define PAUSE { asm volatile ("hlt"); }
#define STOP while (1) { PAUSE; }
@ -40,24 +39,17 @@ extern char * boot_arg_extra; /* Extra data to pass to init */
extern void *sbrk(uintptr_t increment);
extern void spin_lock(uint8_t volatile * lock);
extern void spin_unlock(uint8_t volatile * lock);
/* spin.c */
typedef volatile int spin_lock_t[2];
extern void spin_init(spin_lock_t lock);
extern void spin_lock(spin_lock_t lock);
extern void spin_unlock(spin_lock_t lock);
extern void return_to_userspace(void);
/* Kernel Main */
extern int max(int,int);
extern int min(int,int);
extern int abs(int);
extern void swap(int *, int *);
extern void *memcpy(void *restrict dest, const void *restrict src, size_t count);
extern void *memmove(void *restrict dest, const void *restrict src, size_t count);
extern void *memset(void *dest, int val, size_t count);
extern unsigned short *memsetw(unsigned short *dest, unsigned short val, int count);
extern uint32_t strlen(const char *str);
extern char * strdup(const char *str);
extern char * strcpy(char * dest, const char * src);
extern int atoi(const char *str);
extern unsigned char inportb(unsigned short _port);
extern void outportb(unsigned short _port, unsigned char _data);
extern unsigned short inports(unsigned short _port);
@ -66,14 +58,13 @@ extern unsigned int inportl(unsigned short _port);
extern void outportl(unsigned short _port, unsigned int _data);
extern void outportsm(unsigned short port, unsigned char * data, unsigned long size);
extern void inportsm(unsigned short port, unsigned char * data, unsigned long size);
extern int strcmp(const char *a, const char *b);
extern char * strtok_r(char * str, const char * delim, char ** saveptr);
extern size_t lfind(const char * str, const char accept);
extern size_t rfind(const char * str, const char accept);
extern size_t strspn(const char * str, const char * accept);
extern char * strpbrk(const char * str, const char * accept);
extern uint32_t krand(void);
extern char * strstr(const char * haystack, const char * needle);
extern uint8_t startswith(const char * str, const char * accept);
/* GDT */

View File

@ -3,7 +3,6 @@
#include <types.h>
typedef struct page {
unsigned int present:1;
unsigned int rw:1;

View File

@ -48,11 +48,9 @@ irq_common:
mov %ax, %gs
/* Call interrupt handler */
mov %esp, %eax
push %eax
mov $irq_handler, %eax
call *%eax
pop %eax
push %esp
call irq_handler
add $4, %esp
/* Restore segment registers */
pop %gs

View File

@ -72,11 +72,9 @@ isr_common:
mov %ax, %gs
/* Call fault handler */
mov %esp, %eax
push %eax
mov $fault_handler, %eax
call *%eax
pop %eax
push %esp
call fault_handler
add $4, %esp
/* Restore segment registers */
pop %gs

455
kernel/libc.c Normal file
View File

@ -0,0 +1,455 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2015 Dale Weiler
*
* Standard C library for kernel
*
*/
#include <system.h>
#include <limits.h>
#define ALIGN (sizeof(size_t))
#define ONES ((size_t)-1/UCHAR_MAX)
#define HIGHS (ONES * (UCHAR_MAX/2+1))
#define HASZERO(X) (((X)-ONES) & ~(X) & HIGHS)
#define BITOP(A, B, OP) \
((A)[(size_t)(B)/(8*sizeof *(A))] OP (size_t)1<<((size_t)(B)%(8*sizeof *(A))))
void * memcpy(void * restrict dest, const void * restrict src, size_t n) {
asm volatile("cld; rep movsb"
:
: "D"(dest), "S"(src), "c"(n)
: "cc", "memory");
return dest;
}
void * memset(void * dest, int c, size_t n) {
asm volatile("cld; rep stosb"
:
: "D"(dest), "a"(c), "c"(n)
: "cc", "memory");
return dest;
}
int memcmp(const void * vl, const void * vr, size_t n) {
const unsigned char *l = vl;
const unsigned char *r = vr;
for (; n && *l == *r; n--, l++, r++);
return n ? *l-*r : 0;
}
void * memchr(const void * src, int c, size_t n) {
const unsigned char * s = src;
c = (unsigned char)c;
for (; ((uintptr_t)s & (ALIGN - 1)) && n && *s != c; s++, n--);
if (n && *s != c) {
const size_t * w;
size_t k = ONES * c;
for (w = (const void *)s; n >= sizeof(size_t) && !HASZERO(*w^k); w++, n -= sizeof(size_t));
for (s = (const void *)w; n && *s != c; s++, n--);
}
return n ? (void *)s : 0;
}
void * memrchr(const void * m, int c, size_t n) {
const unsigned char * s = m;
c = (unsigned char)c;
while (n--) {
if (s[n] == c) {
return (void*)(s+n);
}
}
return 0;
}
void * memmove(void * dest, const void * src, size_t n) {
char * d = dest;
const char * s = src;
if (d==s) {
return d;
}
if (s+n <= d || d+n <= s) {
return memcpy(d, s, n);
}
if (d<s) {
if ((uintptr_t)s % sizeof(size_t) == (uintptr_t)d % sizeof(size_t)) {
while ((uintptr_t)d % sizeof(size_t)) {
if (!n--) {
return dest;
}
*d++ = *s++;
}
for (; n >= sizeof(size_t); n -= sizeof(size_t), d += sizeof(size_t), s += sizeof(size_t)) {
*(size_t *)d = *(size_t *)s;
}
}
for (; n; n--) {
*d++ = *s++;
}
} else {
if ((uintptr_t)s % sizeof(size_t) == (uintptr_t)d % sizeof(size_t)) {
while ((uintptr_t)(d+n) % sizeof(size_t)) {
if (!n--) {
return dest;
}
d[n] = s[n];
}
while (n >= sizeof(size_t)) {
n -= sizeof(size_t);
*(size_t *)(d+n) = *(size_t *)(s+n);
}
}
while (n) {
n--;
d[n] = s[n];
}
}
return dest;
}
int strcmp(const char * l, const char * r) {
for (; *l == *r && *l; l++, r++);
return *(unsigned char *)l - *(unsigned char *)r;
}
size_t strlen(const char * s) {
const char * a = s;
const size_t * w;
for (; (uintptr_t)s % ALIGN; s++) {
if (!*s) {
return s-a;
}
}
for (w = (const void *)s; !HASZERO(*w); w++);
for (s = (const void *)w; *s; s++);
return s-a;
}
char * strdup(const char * s) {
size_t l = strlen(s);
return memcpy(malloc(l+1), s, l+1);
}
char * stpcpy(char * restrict d, const char * restrict s) {
size_t * wd;
const size_t * ws;
if ((uintptr_t)s % ALIGN == (uintptr_t)d % ALIGN) {
for (; (uintptr_t)s % ALIGN; s++, d++) {
if (!(*d = *s)) {
return d;
}
}
wd = (void *)d;
ws = (const void *)s;
for (; !HASZERO(*ws); *wd++ = *ws++);
d = (void *)wd;
s = (const void *)ws;
}
for (; (*d=*s); s++, d++);
return d;
}
char * strcpy(char * restrict dest, const char * restrict src) {
stpcpy(dest, src);
return dest;
}
size_t strspn(const char * s, const char * c) {
const char * a = s;
size_t byteset[32/sizeof(size_t)] = { 0 };
if (!c[0]) {
return 0;
}
if (!c[1]) {
for (; *s == *c; s++);
return s-a;
}
for (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++);
for (; *s && BITOP(byteset, *(unsigned char *)s, &); s++);
return s-a;
}
char * strchrnul(const char * s, int c) {
size_t * w;
size_t k;
c = (unsigned char)c;
if (!c) {
return (char *)s + strlen(s);
}
for (; (uintptr_t)s % ALIGN; s++) {
if (!*s || *(unsigned char *)s == c) {
return (char *)s;
}
}
k = ONES * c;
for (w = (void *)s; !HASZERO(*w) && !HASZERO(*w^k); w++);
for (s = (void *)w; *s && *(unsigned char *)s != c; s++);
return (char *)s;
}
char * strchr(const char * s, int c) {
char *r = strchrnul(s, c);
return *(unsigned char *)r == (unsigned char)c ? r : 0;
}
char * strrchr(const char * s, int c) {
return memrchr(s, c, strlen(s) + 1);
}
size_t strcspn(const char * s, const char * c) {
const char *a = s;
if (c[0] && c[1]) {
size_t byteset[32/sizeof(size_t)] = { 0 };
for (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++);
for (; *s && !BITOP(byteset, *(unsigned char *)s, &); s++);
return s-a;
}
return strchrnul(s, *c)-a;
}
char * strpbrk(const char * s, const char * b) {
s += strcspn(s, b);
return *s ? (char *)s : 0;
}
static char *strstr_2b(const unsigned char * h, const unsigned char * n) {
uint16_t nw = n[0] << 8 | n[1];
uint16_t hw = h[0] << 8 | h[1];
for (h++; *h && hw != nw; hw = hw << 8 | *++h);
return *h ? (char *)h-1 : 0;
}
static char *strstr_3b(const unsigned char * h, const unsigned char * n) {
uint32_t nw = n[0] << 24 | n[1] << 16 | n[2] << 8;
uint32_t hw = h[0] << 24 | h[1] << 16 | h[2] << 8;
for (h += 2; *h && hw != nw; hw = (hw|*++h) << 8);
return *h ? (char *)h-2 : 0;
}
static char *strstr_4b(const unsigned char * h, const unsigned char * n) {
uint32_t nw = n[0] << 24 | n[1] << 16 | n[2] << 8 | n[3];
uint32_t hw = h[0] << 24 | h[1] << 16 | h[2] << 8 | h[3];
for (h += 3; *h && hw != nw; hw = hw << 8 | *++h);
return *h ? (char *)h-3 : 0;
}
static char *strstr_twoway(const unsigned char * h, const unsigned char * n) {
size_t mem;
size_t mem0;
size_t byteset[32 / sizeof(size_t)] = { 0 };
size_t shift[256];
size_t l;
/* Computing length of needle and fill shift table */
for (l = 0; n[l] && h[l]; l++) {
BITOP(byteset, n[l], |=);
shift[n[l]] = l+1;
}
if (n[l]) {
return 0; /* hit the end of h */
}
/* Compute maximal suffix */
size_t ip = -1;
size_t jp = 0;
size_t k = 1;
size_t p = 1;
while (jp+k<l) {
if (n[ip+k] == n[jp+k]) {
if (k == p) {
jp += p;
k = 1;
} else {
k++;
}
} else if (n[ip+k] > n[jp+k]) {
jp += k;
k = 1;
p = jp - ip;
} else {
ip = jp++;
k = p = 1;
}
}
size_t ms = ip;
size_t p0 = p;
/* And with the opposite comparison */
ip = -1;
jp = 0;
k = p = 1;
while (jp+k<l) {
if (n[ip+k] == n[jp+k]) {
if (k == p) {
jp += p;
k = 1;
} else {
k++;
}
} else if (n[ip+k] < n[jp+k]) {
jp += k;
k = 1;
p = jp - ip;
} else {
ip = jp++;
k = p = 1;
}
}
if (ip+1 > ms+1) {
ms = ip;
} else {
p = p0;
}
/* Periodic needle? */
if (memcmp(n, n+p, ms+1)) {
mem0 = 0;
p = MAX(ms, l-ms-1) + 1;
} else {
mem0 = l-p;
}
mem = 0;
/* Initialize incremental end-of-haystack pointer */
const unsigned char * z = h;
/* Search loop */
for (;;) {
/* Update incremental end-of-haystack pointer */
if ((size_t)(z-h) < l) {
/* Fast estimate for MIN(l,63) */
size_t grow = l | 63;
const unsigned char *z2 = memchr(z, 0, grow);
if (z2) {
z = z2;
if ((size_t)(z-h) < l) {
return 0;
}
} else {
z += grow;
}
}
/* Check last byte first; advance by shift on mismatch */
if (BITOP(byteset, h[l-1], &)) {
k = l-shift[h[l-1]];
if (k) {
if (mem0 && mem && k < p) k = l-p;
h += k;
mem = 0;
continue;
}
} else {
h += l;
mem = 0;
continue;
}
/* Compare right half */
for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++);
if (n[k]) {
h += k-ms;
mem = 0;
continue;
}
/* Compare left half */
for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
if (k <= mem) {
return (char *)h;
}
h += p;
mem = mem0;
}
}
char *strstr(const char * h, const char * n) {
/* Return immediately on empty needle */
if (!n[0]) {
return (char *)h;
}
/* Use faster algorithms for short needles */
h = strchr(h, *n);
if (!h || !n[1]) {
return (char *)h;
}
if (!h[1]) return 0;
if (!n[2]) return strstr_2b((void *)h, (void *)n);
if (!h[2]) return 0;
if (!n[3]) return strstr_3b((void *)h, (void *)n);
if (!h[3]) return 0;
if (!n[4]) return strstr_4b((void *)h, (void *)n);
/* Two-way on large needles */
return strstr_twoway((void *)h, (void *)n);
}
static inline int isdigit(int ch) {
return (unsigned int)ch-'0' < 10;
}
static inline int isspace(int ch) {
return ch == ' ' || (unsigned int)ch-'\t' < 5;
}
int atoi(const char * s) {
int n = 0;
int neg = 0;
while (isspace(*s)) {
s++;
}
switch (*s) {
case '-':
neg = 1;
/* Fallthrough is intentional here */
case '+':
s++;
}
while (isdigit(*s)) {
n = 10*n - (*s++ - '0');
}
/* The sign order may look incorrect here but this is correct as n is calculated
* as a negative number to avoid overflow on INT_MAX.
*/
return neg ? n : -n;
}
/* Non-standard broken strtok_r */
char * strtok_r(char * str, const char * delim, char ** saveptr) {
char * token;
if (str == NULL) {
str = *saveptr;
}
str += strspn(str, delim);
if (*str == '\0') {
*saveptr = str;
return NULL;
}
token = str;
str = strpbrk(token, delim);
if (str == NULL) {
*saveptr = (char *)lfind(token, '\0');
} else {
*str = '\0';
*saveptr = str + 1;
}
return token;
}

View File

@ -133,42 +133,42 @@ static void * __attribute__ ((malloc)) klcalloc(uintptr_t nmemb, uintptr_t size)
static void * __attribute__ ((malloc)) klvalloc(uintptr_t size);
static void klfree(void * ptr);
static uint8_t volatile mem_lock = 0;
static spin_lock_t mem_lock = { 0 };
void * __attribute__ ((malloc)) malloc(uintptr_t size) {
spin_lock(&mem_lock);
spin_lock(mem_lock);
void * ret = klmalloc(size);
spin_unlock(&mem_lock);
spin_unlock(mem_lock);
return ret;
}
void * __attribute__ ((malloc)) realloc(void * ptr, uintptr_t size) {
spin_lock(&mem_lock);
spin_lock(mem_lock);
void * ret = klrealloc(ptr, size);
spin_unlock(&mem_lock);
spin_unlock(mem_lock);
return ret;
}
void * __attribute__ ((malloc)) calloc(uintptr_t nmemb, uintptr_t size) {
spin_lock(&mem_lock);
spin_lock(mem_lock);
void * ret = klcalloc(nmemb, size);
spin_unlock(&mem_lock);
spin_unlock(mem_lock);
return ret;
}
void * __attribute__ ((malloc)) valloc(uintptr_t size) {
spin_lock(&mem_lock);
spin_lock(mem_lock);
void * ret = klvalloc(size);
spin_unlock(&mem_lock);
spin_unlock(mem_lock);
return ret;
}
void free(void * ptr) {
spin_lock(&mem_lock);
spin_lock(mem_lock);
if ((uintptr_t)ptr > placement_pointer) {
klfree(ptr);
}
spin_unlock(&mem_lock);
spin_unlock(mem_lock);
}
@ -518,7 +518,7 @@ static void * klmalloc_stack_pop(klmalloc_bin_header *header) {
assert((uintptr_t)header->head < (uintptr_t)header + PAGE_SIZE);
assert((uintptr_t)header->head > (uintptr_t)header + sizeof(klmalloc_bin_header) - 1);
}
/*
* Remove the current head and point
* the head to where the old head pointed.
@ -758,7 +758,7 @@ static void klfree(void *ptr) {
if (bucket_id > (uintptr_t)NUM_BINS) {
bucket_id = BIG_BIN;
klmalloc_big_bin_header *bheader = (klmalloc_big_bin_header*)header;
assert(bheader);
assert(bheader->head == NULL);
assert((bheader->size + sizeof(klmalloc_big_bin_header)) % PAGE_SIZE == 0);
@ -955,7 +955,7 @@ static void * __attribute__ ((malloc)) klcalloc(uintptr_t nmemb, uintptr_t size)
/*
* Allocate memory and zero it before returning
* a pointer to the newly allocated memory.
*
*
* Implemented by way of a simple malloc followed
* by a memset to 0x00 across the length of the
* requested memory chunk.

View File

@ -23,7 +23,8 @@ uintptr_t placement_pointer = (uintptr_t)&end;
uintptr_t heap_end = (uintptr_t)NULL;
uintptr_t kernel_heap_alloc_point = KERNEL_HEAP_INIT;
static volatile uint8_t frame_alloc_lock = 0;
//static volatile uint8_t frame_alloc_lock = 0;
static spin_lock_t frame_alloc_lock = { 0 };
uint32_t first_n_frames(int n);
void
@ -56,9 +57,10 @@ kmalloc_real(
clear_frame(map_to_physical(i));
}
/* XXX This is going to get touchy... */
spin_lock(&frame_alloc_lock);
spin_lock(frame_alloc_lock);
uint32_t index = first_n_frames((size + 0xFFF) / 0x1000);
if (index == 0xFFFFFFFF) {
spin_unlock(frame_alloc_lock);
return 0;
}
for (unsigned int i = 0; i < (size + 0xFFF) / 0x1000; ++i) {
@ -66,7 +68,7 @@ kmalloc_real(
page_t * page = get_page((uintptr_t)address + (i * 0x1000),0,kernel_directory);
page->frame = index + i;
}
spin_unlock(&frame_alloc_lock);
spin_unlock(frame_alloc_lock);
}
*phys = map_to_physical((uintptr_t)address);
}
@ -220,12 +222,12 @@ alloc_frame(
page->user = (is_kernel == 1) ? 0 : 1;
return;
} else {
spin_lock(&frame_alloc_lock);
spin_lock(frame_alloc_lock);
uint32_t index = first_frame();
assert(index != (uint32_t)-1 && "Out of frames.");
set_frame(index * 0x1000);
page->frame = index;
spin_unlock(&frame_alloc_lock);
spin_unlock(frame_alloc_lock);
page->present = 1;
page->rw = (is_writeable == 1) ? 1 : 0;
page->user = (is_kernel == 1) ? 0 : 1;

View File

@ -15,7 +15,8 @@
#include <list.h>
static volatile uint8_t bsl; // big shm lock
//static volatile uint8_t bsl; // big shm lock
static spin_lock_t bsl; // big shm lock
tree_t * shm_tree = NULL;
@ -250,7 +251,7 @@ static size_t chunk_size (shm_chunk_t * chunk) {
void * shm_obtain (char * path, size_t * size) {
spin_lock(&bsl);
spin_lock(bsl);
process_t * proc = (process_t *)current_process;
if (proc->group != 0) {
@ -268,14 +269,14 @@ void * shm_obtain (char * path, size_t * size) {
if (size == 0) {
// The process doesn't want a chunk...?
spin_unlock(&bsl);
spin_unlock(bsl);
return NULL;
}
chunk = create_chunk(node, *size);
if (chunk == NULL) {
debug_print(ERROR, "Could not allocate a shm_chunk_t");
spin_unlock(&bsl);
spin_unlock(bsl);
return NULL;
}
@ -287,14 +288,14 @@ void * shm_obtain (char * path, size_t * size) {
void * vshm_start = map_in(chunk, proc);
*size = chunk_size(chunk);
spin_unlock(&bsl);
spin_unlock(bsl);
invalidate_page_tables();
return vshm_start;
}
int shm_release (char * path) {
spin_lock(&bsl);
spin_lock(bsl);
process_t * proc = (process_t *)current_process;
if (proc->group != 0) {
@ -304,7 +305,7 @@ int shm_release (char * path) {
/* First, find the right chunk */
shm_node_t * _node = get_node(path, 0);
if (!_node) {
spin_unlock(&bsl);
spin_unlock(bsl);
return 1;
}
shm_chunk_t * chunk = _node->chunk;
@ -319,7 +320,7 @@ int shm_release (char * path) {
}
}
if (node == NULL) {
spin_unlock(&bsl);
spin_unlock(bsl);
return 1;
}
@ -340,14 +341,14 @@ int shm_release (char * path) {
free(node);
free(mapping);
spin_unlock(&bsl);
spin_unlock(bsl);
return 0;
}
/* This function should only be called if the process's address space
* is about to be destroyed -- chunks will not be unmounted therefrom ! */
void shm_release_all (process_t * proc) {
spin_lock(&bsl);
spin_lock(bsl);
node_t * node;
while ((node = list_pop(proc->shm_mappings)) != NULL) {
@ -362,7 +363,7 @@ void shm_release_all (process_t * proc) {
proc->shm_mappings->head = proc->shm_mappings->tail = NULL;
proc->shm_mappings->length = 0;
spin_unlock(&bsl);
spin_unlock(bsl);
}

57
kernel/spin.c Normal file
View File

@ -0,0 +1,57 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2015 Dale Weiler
*
* Spin locks with waiters
*
*/
#include <system.h>
static inline int arch_atomic_swap(volatile int * x, int v) {
asm("xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory");
return v;
}
static inline void arch_atomic_store(volatile int * p, int x) {
asm("movl %1, %0" : "=m"(*p) : "r"(x) : "memory");
}
static inline void arch_atomic_inc(volatile int * x) {
asm("lock; incl %0" : "=m"(*x) : "m"(*x) : "memory");
}
static inline void arch_atomic_dec(volatile int * x) {
asm("lock; decl %0" : "=m"(*x) : "m"(*x) : "memory");
}
void spin_wait(volatile int * addr, volatile int * waiters) {
if (waiters) {
arch_atomic_inc(waiters);
}
while (*addr) {
switch_task(1);
}
if (waiters) {
arch_atomic_dec(waiters);
}
}
void spin_lock(spin_lock_t lock) {
while (arch_atomic_swap(lock, 1)) {
spin_wait(lock, lock+1);
}
}
void spin_init(spin_lock_t lock) {
lock[0] = 0;
lock[1] = 0;
}
void spin_unlock(spin_lock_t lock) {
if (lock[0]) {
arch_atomic_store(lock, 0);
if (lock[1])
switch_task(1);
}
}

View File

@ -16,13 +16,30 @@
static hashmap_t * symboltable = NULL;
static hashmap_t * modules = NULL;
extern char kernel_symbols_start[];
extern char kernel_symbols_end[];
typedef struct {
uintptr_t addr;
char name[];
} kernel_symbol_t;
extern char kernel_symbols_start[];
extern char kernel_symbols_end[];
/* Cannot use symboltable here because symbol_find is used during initialization
* of IRQs and ISRs.
*/
void (* symbol_find(const char * name))(void) {
kernel_symbol_t * k = (kernel_symbol_t *)&kernel_symbols_start;
while ((uintptr_t)k < (uintptr_t)&kernel_symbols_end) {
if (strcmp(k->name, name)) {
k = (kernel_symbol_t *)((uintptr_t)k + sizeof *k + strlen(k->name) + 1);
continue;
}
return (void (*)(void))k->addr;
}
return NULL;
}
int module_quickcheck(void * blob) {

View File

@ -3,6 +3,7 @@
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2011-2014 Kevin Lange
* Copyright (C) 2012 Markus Schober
* Copyright (C) 2015 Dale Weiler
*
* Processes
*
@ -13,6 +14,7 @@
#include <process.h>
#include <tree.h>
#include <list.h>
#include <bitset.h>
#include <logging.h>
#include <shm.h>
#include <printf.h>
@ -24,10 +26,12 @@ list_t * sleep_queue;
volatile process_t * current_process = NULL;
process_t * kernel_idle_task = NULL;
static uint8_t volatile tree_lock = 0;
static uint8_t volatile process_queue_lock = 0;
static uint8_t volatile wait_lock_tmp = 0;
static uint8_t volatile sleep_lock = 0;
static spin_lock_t tree_lock = { 0 };
static spin_lock_t process_queue_lock = { 0 };
static spin_lock_t wait_lock_tmp = { 0 };
static spin_lock_t sleep_lock = { 0 };
static bitset_t pid_set;
/* Default process name string */
char * default_name = "[unnamed]";
@ -40,6 +44,12 @@ void initialize_process_tree(void) {
process_list = list_create();
process_queue = list_create();
sleep_queue = list_create();
/* Start off with enough bits for 64 processes */
bitset_init(&pid_set, 64 / 8);
/* First two bits are set by default */
bitset_set(&pid_set, 0);
bitset_set(&pid_set, 1);
}
/*
@ -112,9 +122,9 @@ void make_process_ready(process_t * proc) {
/* XXX can't wake from timed sleep */
if (proc->timed_sleep_node) {
IRQ_OFF;
spin_lock(&sleep_lock);
spin_lock(sleep_lock);
list_delete(sleep_queue, proc->timed_sleep_node);
spin_unlock(&sleep_lock);
spin_unlock(sleep_lock);
IRQ_RES;
proc->sleep_node.owner = NULL;
free(proc->timed_sleep_node->value);
@ -122,14 +132,14 @@ void make_process_ready(process_t * proc) {
/* Else: I have no idea what happened. */
} else {
proc->sleep_interrupted = 1;
spin_lock(&wait_lock_tmp);
spin_lock(wait_lock_tmp);
list_delete((list_t*)proc->sleep_node.owner, &proc->sleep_node);
spin_unlock(&wait_lock_tmp);
spin_unlock(wait_lock_tmp);
}
}
spin_lock(&process_queue_lock);
spin_lock(process_queue_lock);
list_append(process_queue, &proc->sched_node);
spin_unlock(&process_queue_lock);
spin_unlock(process_queue_lock);
}
@ -155,11 +165,13 @@ void delete_process(process_t * proc) {
}
/* Remove the entry. */
spin_lock(&tree_lock);
spin_lock(tree_lock);
/* Reparent everyone below me to init */
tree_remove_reparent_root(process_tree, entry);
list_delete(process_list, list_find(process_list, proc));
spin_unlock(&tree_lock);
spin_unlock(tree_lock);
bitset_clear(&pid_set, proc->id);
/* Uh... */
free(proc);
@ -239,7 +251,8 @@ process_t * spawn_init(void) {
init->image.user_stack = 0;
init->image.size = 0;
init->image.shm_heap = SHM_START; /* Yeah, a bit of a hack. */
init->image.lock = 0;
spin_init(init->image.lock);
/* Process is not finished */
init->finished = 0;
@ -277,9 +290,14 @@ process_t * spawn_init(void) {
* @return A usable PID for a new process.
*/
pid_t get_next_pid(void) {
/* Terribly naïve, I know, but it works for now */
static pid_t next = 2;
return (next++);
int index = bitset_ffub(&pid_set);
if (index == -1) {
int next = pid_set.size * 8;
bitset_set(&pid_set, next);
return next;
}
bitset_set(&pid_set, index);
return index;
}
/*
@ -291,11 +309,11 @@ void process_disown(process_t * proc) {
/* Find the process in the tree */
tree_node_t * entry = proc->tree_entry;
/* Break it of from its current parent */
spin_lock(&tree_lock);
spin_lock(tree_lock);
tree_break_off(process_tree, entry);
/* And insert it back elsewhere */
tree_node_insert_child_node(process_tree, process_tree->root, entry);
spin_unlock(&tree_lock);
spin_unlock(tree_lock);
}
/*
@ -340,7 +358,8 @@ process_t * spawn_process(volatile process_t * parent) {
debug_print(INFO," }");
proc->image.user_stack = parent->image.user_stack;
proc->image.shm_heap = SHM_START; /* Yeah, a bit of a hack. */
proc->image.lock = 0;
spin_init(proc->image.lock);
assert(proc->image.stack && "Failed to allocate kernel stack for new process.");
@ -390,10 +409,10 @@ process_t * spawn_process(volatile process_t * parent) {
tree_node_t * entry = tree_node_create(proc);
assert(entry && "Failed to allocate a process tree node for new process.");
proc->tree_entry = entry;
spin_lock(&tree_lock);
spin_lock(tree_lock);
tree_node_insert_child_node(process_tree, parent->tree_entry, entry);
list_insert(process_list, (void *)proc);
spin_unlock(&tree_lock);
spin_unlock(tree_lock);
/* Return the new process */
return proc;
@ -409,9 +428,9 @@ uint8_t process_compare(void * proc_v, void * pid_v) {
process_t * process_from_pid(pid_t pid) {
if (pid < 0) return NULL;
spin_lock(&tree_lock);
spin_lock(tree_lock);
tree_node_t * entry = tree_find(process_tree,&pid,process_compare);
spin_unlock(&tree_lock);
spin_unlock(tree_lock);
if (entry) {
return (process_t *)entry->value;
}
@ -420,7 +439,7 @@ process_t * process_from_pid(pid_t pid) {
process_t * process_get_parent(process_t * process) {
process_t * result = NULL;
spin_lock(&tree_lock);
spin_lock(tree_lock);
tree_node_t * entry = process->tree_entry;
@ -428,7 +447,7 @@ process_t * process_get_parent(process_t * process) {
result = entry->parent->value;
}
spin_unlock(&tree_lock);
spin_unlock(tree_lock);
return result;
}
@ -539,9 +558,9 @@ uint32_t process_move_fd(process_t * proc, int src, int dest) {
int wakeup_queue(list_t * queue) {
int awoken_processes = 0;
while (queue->length > 0) {
spin_lock(&wait_lock_tmp);
spin_lock(wait_lock_tmp);
node_t * node = list_pop(queue);
spin_unlock(&wait_lock_tmp);
spin_unlock(wait_lock_tmp);
if (!((process_t *)node->value)->finished) {
make_process_ready(node->value);
}
@ -553,9 +572,9 @@ int wakeup_queue(list_t * queue) {
int wakeup_queue_interrupted(list_t * queue) {
int awoken_processes = 0;
while (queue->length > 0) {
spin_lock(&wait_lock_tmp);
spin_lock(wait_lock_tmp);
node_t * node = list_pop(queue);
spin_unlock(&wait_lock_tmp);
spin_unlock(wait_lock_tmp);
if (!((process_t *)node->value)->finished) {
process_t * proc = node->value;
proc->sleep_interrupted = 1;
@ -574,9 +593,9 @@ int sleep_on(list_t * queue) {
return 0;
}
current_process->sleep_interrupted = 0;
spin_lock(&wait_lock_tmp);
spin_lock(wait_lock_tmp);
list_append(queue, (node_t *)&current_process->sleep_node);
spin_unlock(&wait_lock_tmp);
spin_unlock(wait_lock_tmp);
switch_task(0);
return current_process->sleep_interrupted;
}
@ -588,7 +607,7 @@ int process_is_ready(process_t * proc) {
void wakeup_sleepers(unsigned long seconds, unsigned long subseconds) {
IRQ_OFF;
spin_lock(&sleep_lock);
spin_lock(sleep_lock);
if (sleep_queue->length) {
sleeper_t * proc = ((sleeper_t *)sleep_queue->head->value);
while (proc && (proc->end_tick < seconds || (proc->end_tick == seconds && proc->end_subtick <= subseconds))) {
@ -607,7 +626,7 @@ void wakeup_sleepers(unsigned long seconds, unsigned long subseconds) {
}
}
}
spin_unlock(&sleep_lock);
spin_unlock(sleep_lock);
IRQ_RES;
}
@ -619,7 +638,7 @@ void sleep_until(process_t * process, unsigned long seconds, unsigned long subse
process->sleep_node.owner = sleep_queue;
IRQ_OFF;
spin_lock(&sleep_lock);
spin_lock(sleep_lock);
node_t * before = NULL;
foreach(node, sleep_queue) {
sleeper_t * candidate = ((sleeper_t *)node->value);
@ -633,7 +652,7 @@ void sleep_until(process_t * process, unsigned long seconds, unsigned long subse
proc->end_tick = seconds;
proc->end_subtick = subseconds;
process->timed_sleep_node = list_insert_after(sleep_queue, before, proc);
spin_unlock(&sleep_lock);
spin_unlock(sleep_lock);
IRQ_RES;
}

View File

@ -36,8 +36,8 @@ void enter_signal_handler(uintptr_t location, int signum, uintptr_t stack) {
debug_print(CRITICAL, "Failed to jump to signal handler!");
}
static uint8_t volatile sig_lock;
static uint8_t volatile sig_lock_b;
static spin_lock_t sig_lock;
static spin_lock_t sig_lock_b;
char isdeadly[] = {
0, /* 0? */
@ -136,9 +136,9 @@ void return_from_signal_handler(void) {
rets_from_sig = list_create();
}
spin_lock(&sig_lock);
spin_lock(sig_lock);
list_insert(rets_from_sig, (process_t *)current_process);
spin_unlock(&sig_lock);
spin_unlock(sig_lock);
switch_next();
}
@ -146,11 +146,11 @@ void return_from_signal_handler(void) {
void fix_signal_stacks(void) {
uint8_t redo_me = 0;
if (rets_from_sig) {
spin_lock(&sig_lock_b);
spin_lock(sig_lock_b);
while (rets_from_sig->head) {
spin_lock(&sig_lock);
spin_lock(sig_lock);
node_t * n = list_dequeue(rets_from_sig);
spin_unlock(&sig_lock);
spin_unlock(sig_lock);
if (!n) {
continue;
}
@ -168,12 +168,12 @@ void fix_signal_stacks(void) {
p->signal_kstack = NULL;
make_process_ready(p);
}
spin_unlock(&sig_lock_b);
spin_unlock(sig_lock_b);
}
if (redo_me) {
spin_lock(&sig_lock);
spin_lock(sig_lock);
list_insert(rets_from_sig, (process_t *)current_process);
spin_unlock(&sig_lock);
spin_unlock(sig_lock);
switch_next();
}
}

View File

@ -151,7 +151,7 @@ static int sys_sbrk(int size) {
if (proc->group != 0) {
proc = process_from_pid(proc->group);
}
spin_lock(&proc->image.lock);
spin_lock(proc->image.lock);
uintptr_t ret = proc->image.heap;
uintptr_t i_ret = ret;
while (ret % 0x1000) {
@ -164,7 +164,7 @@ static int sys_sbrk(int size) {
alloc_frame(get_page(proc->image.heap_actual, 1, current_directory), 0, 1);
invalidate_tables_at(proc->image.heap_actual);
}
spin_unlock(&proc->image.lock);
spin_unlock(proc->image.lock);
return ret;
}
@ -428,7 +428,8 @@ static int sys_chdir(char * newdir) {
static int sys_getcwd(char * buf, size_t size) {
if (buf) {
PTR_VALIDATE(buf);
return (int)memcpy(buf, current_process->wd_name, min(size, strlen(current_process->wd_name) + 1));
size_t len = strlen(current_process->wd_name) + 1;
return (int)memcpy(buf, current_process->wd_name, MIN(size, len));
}
return 0;
}

View File

@ -8,90 +8,9 @@
*/
#include <system.h>
unsigned int __irq_sem = 0;
void spin_lock(uint8_t volatile * lock) {
while(__sync_lock_test_and_set(lock, 0x01)) {
switch_task(1);
}
}
void spin_unlock(uint8_t volatile * lock) {
__sync_lock_release(lock);
}
char * boot_arg = NULL;
char * boot_arg_extra = NULL;
/*
* memcpy
* Copy from source to destination. Assumes that
* source and destination are not overlapping.
*/
void * memcpy(void * restrict dest, const void * restrict src, size_t count) {
asm volatile ("cld; rep movsb" : "+c" (count), "+S" (src), "+D" (dest) :: "memory");
return dest;
}
int max(int a, int b) {
return (a > b) ? a : b;
}
int min(int a, int b) {
return (a > b) ? b : a;
}
int abs(int a) {
return (a >= 0) ? a : -a;
}
void swap(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
void * memmove(void * restrict dest, const void * restrict src, size_t count) {
size_t i;
unsigned char *a = dest;
const unsigned char *b = src;
if (src < dest) {
for ( i = count; i > 0; --i) {
a[i-1] = b[i-1];
}
} else {
for ( i = 0; i < count; ++i) {
a[i] = b[i];
}
}
return dest;
}
int strcmp(const char * a, const char * b) {
uint32_t i = 0;
while (1) {
if (a[i] < b[i]) {
return -1;
} else if (a[i] > b[i]) {
return 1;
} else {
if (a[i] == '\0') {
return 0;
}
++i;
}
}
}
/*
* memset
* Set `count` bytes to `val`.
*/
void * memset(void * b, int val, size_t count) {
asm volatile ("cld; rep stosb" : "+c" (count), "+D" (b) : "a" (val) : "memory");
return b;
}
/*
* memsetw
* Set `count` shorts to `val`.
@ -104,31 +23,6 @@ unsigned short * memsetw(unsigned short * dest, unsigned short val, int count) {
return dest;
}
/*
* strlen
* Returns the length of a given `str`.
*/
uint32_t strlen(const char *str) {
int i = 0;
while (str[i] != (char)0) {
++i;
}
return i;
}
char * strdup(const char *str) {
int len = strlen(str);
char * out = malloc(sizeof(char) * (len+1));
memcpy(out, str, len+1);
return out;
}
char * strcpy(char * dest, const char * src) {
int len = strlen(src);
memcpy(dest, src, len+1);
return dest;
}
uint32_t __attribute__ ((pure)) krand(void) {
static uint32_t x = 123456789;
static uint32_t y = 362436069;
@ -142,22 +36,6 @@ uint32_t __attribute__ ((pure)) krand(void) {
return w = w ^ (w >> 19) ^ t ^ (t >> 8);
}
/*
* atoi
* Naïve implementation thereof.
*/
int atoi(const char * str) {
uint32_t len = strlen(str);
uint32_t out = 0;
uint32_t i;
uint32_t pow = 1;
for (i = len; i > 0; --i) {
out += (str[i-1] - 48) * pow;
pow *= 10;
}
return out;
}
unsigned short inports(unsigned short _port) {
unsigned short rv;
asm volatile ("inw %1, %0" : "=a" (rv) : "dN" (_port));
@ -178,154 +56,33 @@ void outportl(unsigned short _port, unsigned int _data) {
asm volatile ("outl %%eax, %%dx" : : "dN" (_port), "a" (_data));
}
/*
* inportb
* Read from an I/O port.
*/
unsigned char inportb(unsigned short _port) {
unsigned char rv;
asm volatile ("inb %1, %0" : "=a" (rv) : "dN" (_port));
return rv;
}
/*
* outportb
* Write to an I/O port.
*/
void outportb(unsigned short _port, unsigned char _data) {
asm volatile ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
/*
* Output multiple sets of shorts
*/
void outportsm(unsigned short port, unsigned char * data, unsigned long size) {
asm volatile ("rep outsw" : "+S" (data), "+c" (size) : "d" (port));
}
/*
* Input multiple sets of shorts
*/
void inportsm(unsigned short port, unsigned char * data, unsigned long size) {
asm volatile ("rep insw" : "+D" (data), "+c" (size) : "d" (port) : "memory");
}
char * strtok_r(char * str, const char * delim, char ** saveptr) {
char * token;
if (str == NULL) {
str = *saveptr;
}
str += strspn(str, delim);
if (*str == '\0') {
*saveptr = str;
return NULL;
}
token = str;
str = strpbrk(token, delim);
if (str == NULL) {
*saveptr = (char *)lfind(token, '\0');
} else {
*str = '\0';
*saveptr = str + 1;
}
return token;
}
size_t lfind(const char * str, const char accept) {
size_t i = 0;
while ( str[i] != accept) {
i++;
}
return (size_t)(str) + i;
return (size_t)strchr(str, accept);
}
size_t rfind(const char * str, const char accept) {
size_t i = strlen(str) - 1;
while (str[i] != accept) {
if (i == 0) return UINT32_MAX;
i--;
}
return (size_t)(str) + i;
}
char * strstr(const char * haystack, const char * needle) {
const char * out = NULL;
const char * ptr;
const char * acc;
const char * p;
size_t s = strlen(needle);
for (ptr = haystack; *ptr != '\0'; ++ptr) {
size_t accept = 0;
out = ptr;
p = ptr;
for (acc = needle; (*acc != '\0') && (*p != '\0'); ++acc) {
if (*p == *acc) {
accept++;
p++;
} else {
break;
}
}
if (accept == s) {
return (char *)out;
}
}
return NULL;
return (size_t)strrchr(str, accept);
}
uint8_t startswith(const char * str, const char * accept) {
size_t s = strlen(accept);
for (size_t i = 0; i < s; ++i) {
if (*str != *accept) return 0;
str++;
accept++;
}
return 1;
}
size_t strspn(const char * str, const char * accept) {
const char * ptr = str;
const char * acc;
while (*str) {
for (acc = accept; *acc; ++acc) {
if (*str == *acc) {
break;
}
}
if (*acc == '\0') {
break;
}
str++;
}
return str - ptr;
}
char * strpbrk(const char * str, const char * accept) {
const char *acc = accept;
if (!*str) {
return NULL;
}
while (*str) {
for (acc = accept; *acc; ++acc) {
if (*str == *acc) {
break;
}
}
if (*acc) {
break;
}
++str;
}
if (*acc == '\0') {
return NULL;
}
return (char *)str;
return strstr(str, accept) == str;
}

View File

@ -26,7 +26,8 @@ struct ata_device {
ata_identify_t identity;
};
static volatile uint8_t ata_lock = 0;
//static volatile uint8_t ata_lock = 0;
static spin_lock_t ata_lock = { 0 };
/* TODO support other sector sizes */
#define ATA_SECTOR_SIZE 512
@ -302,7 +303,7 @@ static void ata_device_read_sector(struct ata_device * dev, uint32_t lba, uint8_
uint16_t bus = dev->io_base;
uint8_t slave = dev->slave;
spin_lock(&ata_lock);
spin_lock(ata_lock);
int errors = 0;
try_again:
@ -323,7 +324,7 @@ try_again:
errors++;
if (errors > 4) {
debug_print(WARNING, "-- Too many errors trying to read this block. Bailing.");
spin_unlock(&ata_lock);
spin_unlock(ata_lock);
return;
}
goto try_again;
@ -332,14 +333,14 @@ try_again:
int size = 256;
inportsm(bus,buf,size);
ata_wait(dev, 0);
spin_unlock(&ata_lock);
spin_unlock(ata_lock);
}
static void ata_device_write_sector(struct ata_device * dev, uint32_t lba, uint8_t * buf) {
uint16_t bus = dev->io_base;
uint8_t slave = dev->slave;
spin_lock(&ata_lock);
spin_lock(ata_lock);
outportb(bus + ATA_REG_CONTROL, 0x02);
@ -358,7 +359,7 @@ static void ata_device_write_sector(struct ata_device * dev, uint32_t lba, uint8
outportsm(bus,buf,size);
outportb(bus + 0x07, ATA_CMD_CACHE_FLUSH);
ata_wait(dev, 0);
spin_unlock(&ata_lock);
spin_unlock(ata_lock);
}
static int buffer_compare(uint32_t * ptr1, uint32_t * ptr2, size_t size) {

View File

@ -38,7 +38,7 @@ typedef struct {
unsigned int cache_entries; /* Size of ->disk_cache */
unsigned int cache_time; /* "timer" that increments with each cache read/write */
uint8_t volatile lock; /* Synchronization lock point */
spin_lock_t lock; /* Synchronization lock point */
uint8_t bgd_block_span;
uint8_t bgd_offset;
@ -120,14 +120,14 @@ static int read_block(ext2_fs_t * this, unsigned int block_no, uint8_t * buf) {
}
/* This operation requires the filesystem lock to be obtained */
spin_lock(&this->lock);
spin_lock(this->lock);
/* We can make reads without a cache in place. */
if (!DC) {
/* In such cases, we read directly from the block device */
read_fs(this->block_device, block_no * this->block_size, this->block_size, (uint8_t *)buf);
/* We are done, release the lock */
spin_unlock(&this->lock);
spin_unlock(this->lock);
/* And return SUCCESS */
return E_SUCCESS;
}
@ -145,7 +145,7 @@ static int read_block(ext2_fs_t * this, unsigned int block_no, uint8_t * buf) {
/* Read the block */
memcpy(buf, DC[i].block, this->block_size);
/* Release the lock */
spin_unlock(&this->lock);
spin_unlock(this->lock);
/* Success! */
return E_SUCCESS;
}
@ -178,7 +178,7 @@ static int read_block(ext2_fs_t * this, unsigned int block_no, uint8_t * buf) {
DC[oldest].dirty = 0;
/* Release the lock */
spin_unlock(&this->lock);
spin_unlock(this->lock);
/* And return success */
return E_SUCCESS;
@ -199,7 +199,7 @@ static int write_block(ext2_fs_t * this, unsigned int block_no, uint8_t *buf) {
}
/* This operation requires the filesystem lock */
spin_lock(&this->lock);
spin_lock(this->lock);
/* Find the entry in the cache */
int oldest = -1;
@ -210,7 +210,7 @@ static int write_block(ext2_fs_t * this, unsigned int block_no, uint8_t *buf) {
DC[i].last_use = get_cache_time(this);
DC[i].dirty = 1;
memcpy(DC[i].block, buf, this->block_size);
spin_unlock(&this->lock);
spin_unlock(this->lock);
return E_SUCCESS;
}
if (DC[i].last_use < oldest_age) {
@ -233,7 +233,7 @@ static int write_block(ext2_fs_t * this, unsigned int block_no, uint8_t *buf) {
DC[oldest].dirty = 1;
/* Release the lock */
spin_unlock(&this->lock);
spin_unlock(this->lock);
/* We're done. */
return E_SUCCESS;
@ -241,7 +241,7 @@ static int write_block(ext2_fs_t * this, unsigned int block_no, uint8_t *buf) {
static unsigned int ext2_sync(ext2_fs_t * this) {
/* This operation requires the filesystem lock */
spin_lock(&this->lock);
spin_lock(this->lock);
/* Flush each cache entry. */
for (unsigned int i = 0; i < this->cache_entries; ++i) {
@ -251,7 +251,7 @@ static unsigned int ext2_sync(ext2_fs_t * this) {
}
/* Release the lock */
spin_unlock(&this->lock);
spin_unlock(this->lock);
return 0;
}
@ -450,7 +450,7 @@ static int write_inode(ext2_fs_t * this, ext2_inodetable_t *inode, uint32_t inde
if (group > BGDS) {
return E_BADBLOCK;
}
uint32_t inode_table_block = BGD[group].inode_table;
index -= group * this->inodes_per_group;
uint32_t block_offset = ((index - 1) * this->inode_size) / this->block_size;
@ -953,7 +953,7 @@ static ext2_dir_t * direntry_ext2(ext2_fs_t * this, ext2_inodetable_t * inode, u
inode_read_block(this, inode, block_nr, block);
}
}
free(block);
return NULL;
}
@ -981,7 +981,7 @@ static fs_node_t * finddir_ext2(fs_node_t *node, char *name) {
inode_read_block(this, inode, block_nr, block);
}
ext2_dir_t *d_ent = (ext2_dir_t *)((uintptr_t)block + dir_offset);
if (d_ent->inode == 0 || strlen(name) != d_ent->name_len) {
dir_offset += d_ent->rec_len;
total_offset += d_ent->rec_len;
@ -1043,7 +1043,7 @@ static void unlink_ext2(fs_node_t * node, char * name) {
inode_read_block(this, inode, block_nr, block);
}
ext2_dir_t *d_ent = (ext2_dir_t *)((uintptr_t)block + dir_offset);
if (d_ent->inode == 0 || strlen(name) != d_ent->name_len) {
dir_offset += d_ent->rec_len;
total_offset += d_ent->rec_len;
@ -1439,7 +1439,7 @@ static fs_node_t * mount_ext2(fs_node_t * block_device) {
char * bg_buffer = malloc(this->block_size * sizeof(char));
for (uint32_t i = 0; i < BGDS; ++i) {
debug_print(INFO, "Block Group Descriptor #%d @ %d", i, this->bgd_offset + i * SB->blocks_per_group);
debug_print(INFO, "\tBlock Bitmap @ %d", BGD[i].block_bitmap); {
debug_print(INFO, "\tBlock Bitmap @ %d", BGD[i].block_bitmap); {
debug_print(INFO, "\t\tExamining block bitmap at %d", BGD[i].block_bitmap);
read_block(this, BGD[i].block_bitmap, (uint8_t *)bg_buffer);
uint32_t j = 0;

View File

@ -15,13 +15,13 @@
typedef struct packet_manager {
/* uh, nothing, lol */
list_t * exchanges;
volatile uint8_t lock;
spin_lock_t lock;
} pex_t;
typedef struct packet_exchange {
char * name;
char fresh;
volatile uint8_t lock;
spin_lock_t lock;
fs_node_t * server_pipe;
list_t * clients;
} pex_ex_t;
@ -130,12 +130,12 @@ static uint32_t write_server(fs_node_t * node, uint32_t offset, uint32_t size, u
if (head->target == NULL) {
/* Brodcast packet */
spin_lock(&p->lock);
spin_lock(p->lock);
foreach(f, p->clients) {
debug_print(INFO, "Sending to client 0x%x", f->value);
send_to_client(p, (pex_client_t *)f->value, size - sizeof(header_t), head->data);
}
spin_unlock(&p->lock);
spin_unlock(p->lock);
debug_print(INFO, "Done broadcasting to clients.");
return size;
} else if (head->target->parent != p) {
@ -221,7 +221,7 @@ static void close_client(fs_node_t * node) {
debug_print(WARNING, "Closing packetfs client: 0x%x:0x%x", p, c);
spin_lock(&p->lock);
spin_lock(p->lock);
node_t * n = list_find(p->clients, c);
if (n && n->owner == p->clients) {
@ -229,7 +229,7 @@ static void close_client(fs_node_t * node) {
free(n);
}
spin_unlock(&p->lock);
spin_unlock(p->lock);
char tmp[1];
@ -301,11 +301,11 @@ static struct dirent * readdir_packetfs(fs_node_t *node, uint32_t index) {
return NULL;
}
spin_lock(&p->lock);
spin_lock(p->lock);
foreach(f, p->exchanges) {
if (i == index) {
spin_unlock(&p->lock);
spin_unlock(p->lock);
pex_ex_t * t = (pex_ex_t *)f->value;
struct dirent * out = malloc(sizeof(struct dirent));
memset(out, 0x00, sizeof(struct dirent));
@ -317,7 +317,7 @@ static struct dirent * readdir_packetfs(fs_node_t *node, uint32_t index) {
}
}
spin_unlock(&p->lock);
spin_unlock(p->lock);
return NULL;
}
@ -341,17 +341,17 @@ static fs_node_t * finddir_packetfs(fs_node_t * node, char * name) {
debug_print(INFO, "[pex] finddir(%s)", name);
spin_lock(&p->lock);
spin_lock(p->lock);
foreach(f, p->exchanges) {
pex_ex_t * t = (pex_ex_t *)f->value;
if (!strcmp(name, t->name)) {
spin_unlock(&p->lock);
spin_unlock(p->lock);
return file_from_pex(t);
}
}
spin_unlock(&p->lock);
spin_unlock(p->lock);
return NULL;
}
@ -363,12 +363,12 @@ static void create_packetfs(fs_node_t *parent, char *name, uint16_t permission)
debug_print(NOTICE, "[pex] create(%s)", name);
spin_lock(&p->lock);
spin_lock(p->lock);
foreach(f, p->exchanges) {
pex_ex_t * t = (pex_ex_t *)f->value;
if (!strcmp(name, t->name)) {
spin_unlock(&p->lock);
spin_unlock(p->lock);
/* Already exists */
return;
}
@ -379,14 +379,15 @@ static void create_packetfs(fs_node_t *parent, char *name, uint16_t permission)
new_exchange->name = strdup(name);
new_exchange->fresh = 1;
new_exchange->lock = 0;
new_exchange->clients = list_create();
new_exchange->server_pipe = make_pipe(4096);
spin_init(new_exchange->lock);
/* XXX Create exchange server pipe */
list_insert(p->exchanges, new_exchange);
spin_unlock(&p->lock);
spin_unlock(p->lock);
}
@ -403,7 +404,7 @@ static void unlink_packetfs(fs_node_t *parent, char *name) {
int i = -1, j = 0;
spin_lock(&p->lock);
spin_lock(p->lock);
foreach(f, p->exchanges) {
pex_ex_t * t = (pex_ex_t *)f->value;
@ -419,13 +420,15 @@ static void unlink_packetfs(fs_node_t *parent, char *name) {
list_remove(p->exchanges, i);
}
spin_unlock(&p->lock);
spin_unlock(p->lock);
}
static fs_node_t * packetfs_manager(void) {
pex_t * pex = malloc(sizeof(pex_t));
pex->exchanges = list_create();
pex->lock = 0;
spin_init(pex->lock);
fs_node_t * fnode = malloc(sizeof(fs_node_t));
memset(fnode, 0x00, sizeof(fs_node_t));
fnode->inode = 0;

View File

@ -41,7 +41,9 @@ static void find_rtl(uint32_t device, uint16_t vendorid, uint16_t deviceid, void
static void net_handler_enqueue(void * buffer);
static list_t * net_queue = NULL;
static volatile uint8_t net_queue_lock = 0;
//static volatile uint8_t net_queue_lock = 0;
static spin_lock_t net_queue_lock = { 0 };
static int rtl_irq = 0;
static uint32_t rtl_iobase = 0;
@ -65,16 +67,17 @@ static fs_node_t * irc_socket;
static uint32_t seq_no = 0xff0000;
static uint32_t ack_no = 0x0;
static volatile uint8_t _lock;
//static volatile uint8_t _lock;
static spin_lock_t _lock;
static int next_tx_buf(void) {
int out;
spin_lock(&_lock);
spin_lock(_lock);
out = next_tx;
next_tx++;
if (next_tx == 4) {
next_tx = 0;
}
spin_unlock(&_lock);
spin_unlock(_lock);
return out;
}
@ -400,7 +403,9 @@ static char irc_input[400] = {'\0'};
static char irc_prompt[100] = {'\0'};
static char irc_nick[32] = {'\0'};
static char irc_payload[512];
static volatile uint8_t irc_tty_lock = 0;
static spin_lock_t irc_tty_lock = { 0 };
//static volatile uint8_t irc_tty_lock = 0;
//static struct netif rtl_netif;
static void irc_send(char * payload) {
@ -422,7 +427,7 @@ static void handle_irc_packet(fs_node_t * tty, size_t size, uint8_t * packet) {
if ((uintptr_t)e > (uintptr_t)packet + size) {
break;
}
spin_lock(&irc_tty_lock);
spin_lock(irc_tty_lock);
if (!e) {
/* XXX */
@ -445,7 +450,7 @@ static void handle_irc_packet(fs_node_t * tty, size_t size, uint8_t * packet) {
char * command;
char * channel;
char * message;
user = c;
command = strstr(user, " ");
@ -498,7 +503,7 @@ prompt_:
fprintf(tty, "%s", irc_prompt);
fprintf(tty, "%s", irc_input);
spin_unlock(&irc_tty_lock);
spin_unlock(irc_tty_lock);
if (!e) break;
@ -622,11 +627,11 @@ static struct ethernet_packet * net_receive(void) {
while (!net_queue->length) {
sleep_on(rx_wait);
}
spin_lock(&net_queue_lock);
spin_lock(net_queue_lock);
node_t * n = list_dequeue(net_queue);
struct ethernet_packet * eth = (struct ethernet_packet *)n->value;
free(n);
spin_unlock(&net_queue_lock);
spin_unlock(net_queue_lock);
return eth;
}
@ -655,11 +660,11 @@ static void net_handler(void * data, char * name) {
static void net_handler_enqueue(void * buffer) {
/* XXX size? source? */
spin_lock(&net_queue_lock);
spin_lock(net_queue_lock);
list_insert(net_queue, buffer);
spin_unlock(&net_queue_lock);
spin_unlock(net_queue_lock);
}
static void parse_dns_response(fs_node_t * tty, void * last_packet) {
@ -954,11 +959,11 @@ static int tty_readline(fs_node_t * dev, char * linebuf, int max) {
debug_print(WARNING, "Read nothing?");
continue;
}
spin_lock(&irc_tty_lock);
spin_lock(irc_tty_lock);
linebuf[read] = buf[0];
if (buf[0] == '\n') {
linebuf[read] = 0;
spin_unlock(&irc_tty_lock);
spin_unlock(irc_tty_lock);
break;
} else if (buf[0] == 0x08) {
if (read > 0) {
@ -970,18 +975,18 @@ static int tty_readline(fs_node_t * dev, char * linebuf, int max) {
switch (buf[0]) {
case 0x0C: /* ^L */
/* Should reset display here */
spin_unlock(&irc_tty_lock);
spin_unlock(irc_tty_lock);
break;
default:
/* do nothing */
spin_unlock(&irc_tty_lock);
spin_unlock(irc_tty_lock);
break;
}
} else {
fprintf(dev, "%c", buf[0]);
read += r;
}
spin_unlock(&irc_tty_lock);
spin_unlock(irc_tty_lock);
}
tty_set_buffered(dev);
return read;
@ -1091,7 +1096,7 @@ DEFINE_SHELL_FUNCTION(irc_join, "irc channel tool") {
fprintf(tty, irc_prompt);
int c = tty_readline(tty, irc_input, 400);
spin_lock(&irc_tty_lock);
spin_lock(irc_tty_lock);
irc_input[c] = '\0';
@ -1099,7 +1104,7 @@ DEFINE_SHELL_FUNCTION(irc_join, "irc channel tool") {
fprintf(tty, "\n");
sprintf(irc_payload, "PART %s\r\n", channel);
irc_send(irc_payload);
spin_unlock(&irc_tty_lock);
spin_unlock(irc_tty_lock);
break;
}
@ -1120,7 +1125,7 @@ DEFINE_SHELL_FUNCTION(irc_join, "irc channel tool") {
}
memset(irc_input, 0x00, sizeof(irc_input));
spin_unlock(&irc_tty_lock);
spin_unlock(irc_tty_lock);
}
memset(irc_prompt, 0x00, sizeof(irc_prompt));
memset(irc_input, 0x00, sizeof(irc_input));
@ -1153,7 +1158,7 @@ DEFINE_SHELL_FUNCTION(http, "Open a prompt to send HTTP commands.") {
/* /posting.php?mode=post&f=7 */
char * content =
char * content =
"-----------------------------2611311029845263341299213952\r\n"
"Content-Disposition: form-data; name=\"subject\"\r\n"
"\r\n"

View File

@ -21,7 +21,6 @@
#include <system.h>
/* Utility macros */
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
#define N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0]))
#define SND_BUF_SIZE 0x1000
@ -35,8 +34,9 @@ static int snd_mixer_ioctl(fs_node_t * node, int request, void * argp);
static void snd_mixer_open(fs_node_t * node, unsigned int flags);
static void snd_mixer_close(fs_node_t * node);
static uint8_t _devices_lock;
static list_t _devices;
static spin_lock_t _devices_lock;
static list_t _devices;
static fs_node_t _dsp_fnode = {
.name = "dsp",
.device = &_devices,
@ -52,7 +52,7 @@ static fs_node_t _mixer_fnode = {
.open = snd_mixer_open,
.close = snd_mixer_close,
};
static uint8_t _buffers_lock;
static spin_lock_t _buffers_lock;
static list_t _buffers;
static uint32_t _next_device_id = SND_DEVICE_MAIN;
@ -60,7 +60,7 @@ int snd_register(snd_device_t * device) {
int rv = 0;
debug_print(WARNING, "[snd] _devices lock: %d", _devices_lock);
spin_lock(&_devices_lock);
spin_lock(_devices_lock);
device->id = _next_device_id;
_next_device_id++;
if (list_find(&_devices, device)) {
@ -72,7 +72,7 @@ int snd_register(snd_device_t * device) {
debug_print(NOTICE, "[snd] %s registered", device->name);
snd_register_cleanup:
spin_unlock(&_devices_lock);
spin_unlock(_devices_lock);
return rv;
}
@ -89,7 +89,7 @@ int snd_unregister(snd_device_t * device) {
debug_print(NOTICE, "[snd] %s unregistered", device->name);
snd_unregister_cleanup:
spin_unlock(&_devices_lock);
spin_unlock(_devices_lock);
return rv;
}
@ -103,25 +103,25 @@ static int snd_dsp_ioctl(fs_node_t * node, int request, void * argp) {
}
static void snd_dsp_open(fs_node_t * node, unsigned int flags) {
/*
/*
* XXX(gerow): A process could take the memory of the entire system by opening
* too many of these...
*/
/* Allocate a buffer for the node and keep a reference for ourselves */
node->device = ring_buffer_create(SND_BUF_SIZE);
spin_lock(&_buffers_lock);
spin_lock(_buffers_lock);
list_insert(&_buffers, node->device);
spin_unlock(&_buffers_lock);
spin_unlock(_buffers_lock);
}
static void snd_dsp_close(fs_node_t * node) {
spin_lock(&_buffers_lock);
spin_lock(_buffers_lock);
list_delete(&_buffers, list_find(&_buffers, node->device));
spin_unlock(&_buffers_lock);
spin_unlock(_buffers_lock);
}
static snd_device_t * snd_device_by_id(uint32_t device_id) {
spin_lock(&_devices_lock);
spin_lock(_devices_lock);
snd_device_t * out = NULL;
snd_device_t * cur = NULL;
@ -131,7 +131,7 @@ static snd_device_t * snd_device_by_id(uint32_t device_id) {
out = cur;
}
}
spin_unlock(&_devices_lock);
spin_unlock(_devices_lock);
return out;
}
@ -199,7 +199,7 @@ int snd_request_buf(snd_device_t * device, uint32_t size, uint8_t *buffer) {
memset(buffer, 0, size);
spin_lock(&_buffers_lock);
spin_lock(_buffers_lock);
foreach(buf_node, &_buffers) {
ring_buffer_t * buf = buf_node->value;
/* ~0x3 is to ensure we don't read partial samples or just a single channel */
@ -223,19 +223,19 @@ int snd_request_buf(snd_device_t * device, uint32_t size, uint8_t *buffer) {
bytes_left -= this_read_size;
}
}
spin_unlock(&_buffers_lock);
spin_unlock(_buffers_lock);
return size;
}
static snd_device_t * snd_main_device() {
spin_lock(&_devices_lock);
spin_lock(_devices_lock);
foreach(node, &_devices) {
spin_unlock(&_devices_lock);
spin_unlock(_devices_lock);
return node->value;
}
spin_unlock(&_devices_lock);
spin_unlock(_devices_lock);
return NULL;
}

View File

@ -18,7 +18,7 @@
#define TMPFS_TYPE_FILE 1
#define TMPFS_TYPE_DIR 2
uint8_t volatile tmpfs_lock = 0;
static spin_lock_t tmpfs_lock = { 0 };
struct tmpfs_dir * tmpfs_root = NULL;
@ -26,7 +26,7 @@ static fs_node_t * tmpfs_from_dir(struct tmpfs_dir * d);
static struct tmpfs_file * tmpfs_file_new(char * name) {
spin_lock(&tmpfs_lock);
spin_lock(tmpfs_lock);
struct tmpfs_file * t = malloc(sizeof(struct tmpfs_file));
t->name = strdup(name);
@ -45,12 +45,12 @@ static struct tmpfs_file * tmpfs_file_new(char * name) {
t->blocks[i] = NULL;
}
spin_unlock(&tmpfs_lock);
spin_unlock(tmpfs_lock);
return t;
}
static struct tmpfs_dir * tmpfs_dir_new(char * name, struct tmpfs_dir * parent) {
spin_lock(&tmpfs_lock);
spin_lock(tmpfs_lock);
struct tmpfs_dir * d = malloc(sizeof(struct tmpfs_dir));
d->name = strdup(name);
@ -63,7 +63,7 @@ static struct tmpfs_dir * tmpfs_dir_new(char * name, struct tmpfs_dir * parent)
d->ctime = d->atime;
d->files = list_create();
spin_unlock(&tmpfs_lock);
spin_unlock(tmpfs_lock);
return d;
}
@ -82,7 +82,7 @@ static void tmpfs_file_blocks_embiggen(struct tmpfs_file * t) {
static char * tmpfs_file_getset_block(struct tmpfs_file * t, size_t blockid, int create) {
debug_print(INFO, "Reading block %d from file %s", blockid, t->name);
if (create) {
spin_lock(&tmpfs_lock);
spin_lock(tmpfs_lock);
while (blockid >= t->pointers) {
tmpfs_file_blocks_embiggen(t);
}
@ -91,7 +91,7 @@ static char * tmpfs_file_getset_block(struct tmpfs_file * t, size_t blockid, int
t->blocks[t->block_count] = malloc(BLOCKSIZE);
t->block_count += 1;
}
spin_unlock(&tmpfs_lock);
spin_unlock(tmpfs_lock);
} else {
if (blockid >= t->block_count) {
debug_print(CRITICAL, "This will probably end badly.");
@ -283,22 +283,23 @@ static fs_node_t * finddir_tmpfs(fs_node_t * node, char * name) {
struct tmpfs_dir * d = (struct tmpfs_dir *)node->device;
spin_lock(&tmpfs_lock);
spin_lock(tmpfs_lock);
foreach(f, d->files) {
struct tmpfs_file * t = (struct tmpfs_file *)f->value;
if (!strcmp(name, t->name)) {
spin_unlock(&tmpfs_lock);
spin_unlock(tmpfs_lock);
switch (t->type) {
case TMPFS_TYPE_FILE:
return tmpfs_from_file(t);
case TMPFS_TYPE_DIR:
return tmpfs_from_dir((struct tmpfs_dir *)t);
}
return NULL;
}
}
spin_unlock(&tmpfs_lock);
spin_unlock(tmpfs_lock);
return NULL;
}
@ -306,7 +307,7 @@ static fs_node_t * finddir_tmpfs(fs_node_t * node, char * name) {
static void unlink_tmpfs(fs_node_t * node, char * name) {
struct tmpfs_dir * d = (struct tmpfs_dir *)node->device;
int i = -1, j = 0;
spin_lock(&tmpfs_lock);
spin_lock(tmpfs_lock);
foreach(f, d->files) {
struct tmpfs_file * t = (struct tmpfs_file *)f->value;
@ -323,7 +324,7 @@ static void unlink_tmpfs(fs_node_t * node, char * name) {
list_remove(d->files, i);
}
spin_unlock(&tmpfs_lock);
spin_unlock(tmpfs_lock);
return;
}
@ -333,16 +334,16 @@ static void create_tmpfs(fs_node_t *parent, char *name, uint16_t permission) {
struct tmpfs_dir * d = (struct tmpfs_dir *)parent->device;
debug_print(CRITICAL, "Creating TMPFS file %s in %s", name, d->name);
spin_lock(&tmpfs_lock);
spin_lock(tmpfs_lock);
foreach(f, d->files) {
struct tmpfs_file * t = (struct tmpfs_file *)f->value;
if (!strcmp(name, t->name)) {
spin_unlock(&tmpfs_lock);
spin_unlock(tmpfs_lock);
debug_print(WARNING, "... already exists.");
return; /* Already exists */
}
}
spin_unlock(&tmpfs_lock);
spin_unlock(tmpfs_lock);
debug_print(NOTICE, "... creating a new file.");
struct tmpfs_file * t = tmpfs_file_new(name);
@ -350,9 +351,9 @@ static void create_tmpfs(fs_node_t *parent, char *name, uint16_t permission) {
t->uid = current_process->user;
t->gid = current_process->user;
spin_lock(&tmpfs_lock);
spin_lock(tmpfs_lock);
list_insert(d->files, t);
spin_unlock(&tmpfs_lock);
spin_unlock(tmpfs_lock);
}
static void mkdir_tmpfs(fs_node_t * parent, char * name, uint16_t permission) {
@ -361,16 +362,16 @@ static void mkdir_tmpfs(fs_node_t * parent, char * name, uint16_t permission) {
struct tmpfs_dir * d = (struct tmpfs_dir *)parent->device;
debug_print(CRITICAL, "Creating TMPFS directory %s (in %s)", name, d->name);
spin_lock(&tmpfs_lock);
spin_lock(tmpfs_lock);
foreach(f, d->files) {
struct tmpfs_file * t = (struct tmpfs_file *)f->value;
if (!strcmp(name, t->name)) {
spin_unlock(&tmpfs_lock);
spin_unlock(tmpfs_lock);
debug_print(WARNING, "... already exists.");
return; /* Already exists */
}
}
spin_unlock(&tmpfs_lock);
spin_unlock(tmpfs_lock);
debug_print(NOTICE, "... creating a new directory.");
struct tmpfs_dir * out = tmpfs_dir_new(name, d);
@ -378,9 +379,9 @@ static void mkdir_tmpfs(fs_node_t * parent, char * name, uint16_t permission) {
out->uid = current_process->user;
out->gid = current_process->user;
spin_lock(&tmpfs_lock);
spin_lock(tmpfs_lock);
list_insert(d->files, out);
spin_unlock(&tmpfs_lock);
spin_unlock(tmpfs_lock);
}
static fs_node_t * tmpfs_from_dir(struct tmpfs_dir * d) {