From c5875c4639e2d0aa8d2dd6e2bcdcc14c4840b080 Mon Sep 17 00:00:00 2001 From: Mark Date: Sat, 4 Jan 2020 15:29:44 +0200 Subject: [PATCH] Scheduler optimization, console optimization (still slow as hell) --- etc/make/amd64/conf.mk | 3 +- include/sys/amd64/hw/rtc.h | 11 +++++ include/sys/amd64/syscall.h | 3 ++ include/sys/debug.h | 12 +++--- include/sys/ring.h | 2 +- include/sys/string.h | 2 + sys/amd64/hw/con.c | 24 +++++------ sys/amd64/hw/irq0.S | 1 - sys/amd64/hw/pci/ide.c | 5 ++- sys/amd64/hw/rs232.c | 8 +++- sys/amd64/hw/rtc.c | 12 +----- sys/amd64/hw/timer.c | 4 +- sys/amd64/syscall.c | 20 +++++++-- sys/ring.c | 27 ++++++++----- sys/string.c | 13 ++++++ sys/tty.c | 2 +- sys/vfs/pty.c | 14 +------ usr/Makefile | 16 +++++++- usr/init.c | 72 +++++++++++++++++++++++++++++---- usr/libc/include/bits/syscall.h | 1 + usr/libc/include/time.h | 4 ++ usr/libc/syscall.c | 4 ++ usr/libc/time.c | 7 ++++ usr/time.c | 12 ++++++ 24 files changed, 206 insertions(+), 73 deletions(-) create mode 100644 usr/libc/include/time.h create mode 100644 usr/libc/time.c create mode 100644 usr/time.c diff --git a/etc/make/amd64/conf.mk b/etc/make/amd64/conf.mk index b5b53d3..abdafd9 100644 --- a/etc/make/amd64/conf.mk +++ b/etc/make/amd64/conf.mk @@ -118,8 +118,9 @@ endif QEMU_OPTS?=-m $(QEMU_MEM) \ -chardev stdio,nowait,id=char0,mux=on \ -serial chardev:char0 -mon chardev=char0 \ - --accel tcg,thread=multi \ -M $(QEMU_CHIPSET) \ + -cpu host \ + -enable-kvm \ -boot d \ $(QEMU_DEVS) \ -smp $(QEMU_SMP) diff --git a/include/sys/amd64/hw/rtc.h b/include/sys/amd64/hw/rtc.h index 1812228..7ccca18 100644 --- a/include/sys/amd64/hw/rtc.h +++ b/include/sys/amd64/hw/rtc.h @@ -1,5 +1,16 @@ #pragma once #include "sys/types.h" +struct rtc_time { + uint8_t second; + uint8_t minute; + uint8_t hour; + uint8_t weekday; + uint8_t day; + uint8_t month; + uint16_t year; +}; + +void rtc_read(struct rtc_time *time); void rtc_set_century(uint8_t c); void rtc_init(void); diff --git a/include/sys/amd64/syscall.h b/include/sys/amd64/syscall.h index 8a1740d..7efaa0f 100644 --- a/include/sys/amd64/syscall.h +++ b/include/sys/amd64/syscall.h @@ -2,5 +2,8 @@ struct cpu_context; +extern uint64_t syscall_last_time; +extern uint64_t syscall_count; + void amd64_syscall_init(void); extern void amd64_syscall_iretq(struct cpu_context *ctx); diff --git a/include/sys/debug.h b/include/sys/debug.h index 8c9d1c6..0f02f51 100644 --- a/include/sys/debug.h +++ b/include/sys/debug.h @@ -16,12 +16,12 @@ #define DEBUG_OUT_SERIAL 0 #define DEBUG_OUT_DISP 1 -#define kdebug(f, ...) debugf(DEBUG_DEFAULT, "[%s] " f, __func__, ##__VA_ARGS__) -#define kinfo(f, ...) debugf(DEBUG_INFO, "[%s] " f, __func__, ##__VA_ARGS__) -#define kwarn(f, ...) debugf(DEBUG_WARN, "[%s] " f, __func__, ##__VA_ARGS__) -#define kerror(f, ...) debugf(DEBUG_ERROR, "[%s] " f, __func__, ##__VA_ARGS__) -#define kfatal(f, ...) debugf(DEBUG_FATAL, "[%s] " f, __func__, ##__VA_ARGS__) -#define kprint(l, f, ...) debugf(l, "[%s] " f, __func__, ##__VA_ARGS__) +#define kdebug(f, ...) debugf(DEBUG_DEFAULT, "[%s] " f, __func__, ##__VA_ARGS__) +#define kinfo(f, ...) debugf(DEBUG_INFO, "[%s] " f, __func__, ##__VA_ARGS__) +#define kwarn(f, ...) debugf(DEBUG_WARN, "[%s] " f, __func__, ##__VA_ARGS__) +#define kerror(f, ...) debugf(DEBUG_ERROR, "[%s] " f, __func__, ##__VA_ARGS__) +#define kfatal(f, ...) debugf(DEBUG_FATAL, "[%s] " f, __func__, ##__VA_ARGS__) +#define kprint(l, f, ...) debugf(l, "[%s] " f, __func__, ##__VA_ARGS__) void fmtsiz(char *buf, size_t sz); diff --git a/include/sys/ring.h b/include/sys/ring.h index 094ebe6..d9247c6 100644 --- a/include/sys/ring.h +++ b/include/sys/ring.h @@ -14,5 +14,5 @@ struct ring { size_t ring_avail(struct ring *b); ssize_t ring_read(struct thread *ctx, struct ring *b, void *buf, size_t lim); -int ring_putc(struct ring *b, char c); +int ring_putc(struct thread *ctx, struct ring *b, char c); void ring_init(struct ring *b, size_t cap); diff --git a/include/sys/string.h b/include/sys/string.h index b766bf8..b2a18b5 100644 --- a/include/sys/string.h +++ b/include/sys/string.h @@ -9,10 +9,12 @@ #define MIN(x, y) ((x) < (y) ? (x) : (y)) void *memcpy(void *restrict dst, const void *restrict src, size_t cnt); +uint64_t *memcpyq(uint64_t *restrict dst, const uint64_t *restrict src, size_t cnt); void *memmove(void *dst, const void *src, size_t cnt); void *memset(void *dst, int v, size_t count); uint16_t *memsetw(uint16_t *dst, uint16_t v, size_t count); uint32_t *memsetl(uint32_t *dst, uint32_t v, size_t count); +uint64_t *memsetq(uint64_t *dst, uint64_t v, size_t count); int memcmp(const void *a, const void *b, size_t count); size_t strlen(const char *s); diff --git a/sys/amd64/hw/con.c b/sys/amd64/hw/con.c index f5a9be5..af33785 100644 --- a/sys/amd64/hw/con.c +++ b/sys/amd64/hw/con.c @@ -19,7 +19,7 @@ #define ESC_CSI 2 #define CGA_BUFFER_ADDR 0xB8000 -#define ATTR_DEFAULT 0x1700 +#define ATTR_DEFAULT 0x1700ULL static uint16_t *con_buffer; static uint16_t x = 0, y = 0; @@ -57,8 +57,8 @@ static uint16_t attr = ATTR_DEFAULT; static void setc(uint16_t row, uint16_t col, uint16_t v); -void con_blink(void) { #if defined(VESA_ENABLE) +void con_blink(void) { if (vesa_available) { uint32_t fg = rgb_map[(attr >> 8) & 0xF]; uint32_t bg = rgb_map[(attr >> 12) & 0xF]; @@ -70,8 +70,8 @@ void con_blink(void) { psf_draw(y, x, ' ', fg, bg); } } -#endif } +#endif static void amd64_con_moveto(uint8_t row, uint8_t col) { if (!vesa_available) { @@ -85,11 +85,7 @@ static void amd64_con_moveto(uint8_t row, uint8_t col) { } static void amd64_scroll_down(void) { - for (int i = 0; i < con_height - 1; ++i) { - memcpy(&con_buffer[i * con_width], &con_buffer[(i + 1) * con_width], con_width * 2); - } - memsetw(&con_buffer[(con_height - 1) * con_width], ATTR_DEFAULT, con_width); - y = con_height - 1; +#if defined(VESA_ENABLE) if (vesa_available) { for (uint16_t row = 0; row < con_height; ++row) { for (uint16_t col = 0; col < con_width; ++col) { @@ -98,6 +94,12 @@ static void amd64_scroll_down(void) { } } } +#else + memcpyq((uint64_t *) con_buffer, (uint64_t *) &con_buffer[con_width], 20 * 24); + memsetq((uint64_t *) &con_buffer[(con_height - 1) * con_width], + ATTR_DEFAULT | (ATTR_DEFAULT << 16) | (ATTR_DEFAULT << 32) | (ATTR_DEFAULT << 48), 20); + y = con_height - 1; +#endif } static void clear(void) { @@ -112,10 +114,6 @@ static void clear(void) { #endif } -//static void clear_line(uint16_t row) { -// -//} - // I guess I could've implemented VT100 escape handling better, but // this is all I invented so far static void process_csi(void) { @@ -257,6 +255,8 @@ void amd64_con_putc(int c) { return; } + c = (uint8_t) (c & 0xFF); + switch (esc_mode) { case ESC_CSI: if (c >= '0' && c <= '9') { diff --git a/sys/amd64/hw/irq0.S b/sys/amd64/hw/irq0.S index e8f0bf8..909a3b0 100644 --- a/sys/amd64/hw/irq0.S +++ b/sys/amd64/hw/irq0.S @@ -46,7 +46,6 @@ amd64_irq0: movq %rax, 4(%rdi) 1: // Assume we're now on TASK2's stack - // EOI irq_eoi_lapic 0 diff --git a/sys/amd64/hw/pci/ide.c b/sys/amd64/hw/pci/ide.c index 38e312b..e0904a1 100644 --- a/sys/amd64/hw/pci/ide.c +++ b/sys/amd64/hw/pci/ide.c @@ -13,6 +13,7 @@ static void pci_ide_init(pci_addr_t addr) { uint32_t irq_config = pci_config_read_dword(addr, PCI_CONFIG_IRQ); uint32_t class = pci_config_read_dword(addr, PCI_CONFIG_CLASS); + uint8_t prog_if = (class >> 8) & 0xFF; uint32_t bar; uint32_t cmd = pci_config_read_dword(addr, PCI_CONFIG_CMD); @@ -83,10 +84,10 @@ static void pci_ide_init(pci_addr_t addr) { } else { // The device either does not use IRQs or is a // paraller IDE with IRQs 14 and 15 - uint8_t prog_if = (class >> 8) & 0xFF; if (prog_if == 0x80 || prog_if == 0x8A) { // TODO: handle this case - panic("This is a parallel IDE controller\n"); + //panic("This is a parallel IDE controller\n"); + return; } else { // TODO: handle this case panic("The device has no IRQs\n"); diff --git a/sys/amd64/hw/rs232.c b/sys/amd64/hw/rs232.c index f732442..be03220 100644 --- a/sys/amd64/hw/rs232.c +++ b/sys/amd64/hw/rs232.c @@ -1,6 +1,7 @@ #include "sys/amd64/hw/rs232.h" #include "sys/amd64/hw/irq.h" #include "sys/amd64/hw/io.h" +#include "sys/tty.h" #include "sys/debug.h" #define RS232_DTR 0 @@ -41,8 +42,11 @@ static uint32_t rs232_irq(void *ctx) { has_data = 1; uint8_t c = inb(port); - // Act as echo for now - rs232_send(port, c); + if (c == '\r') { + c = '\n'; + } + + tty_buffer_write(0, c); } return has_data ? IRQ_HANDLED : IRQ_UNHANDLED; diff --git a/sys/amd64/hw/rtc.c b/sys/amd64/hw/rtc.c index e25302f..0158fe9 100644 --- a/sys/amd64/hw/rtc.c +++ b/sys/amd64/hw/rtc.c @@ -26,16 +26,6 @@ #define FROMBCD(bcd) ((((bcd) / 16) * 10) + \ ((bcd & 0xF))) -struct rtc_time { - uint8_t second; - uint8_t minute; - uint8_t hour; - uint8_t weekday; - uint8_t day; - uint8_t month; - uint16_t year; -}; - // [s]Please change this in Y3K[/s]I hope x86 dies by 3000 static uint8_t rtc_century = 20; @@ -60,7 +50,7 @@ static inline uint8_t cmos_read_time(uint8_t reg, uint8_t reg_b) { } } -static void rtc_read(struct rtc_time *time) { +void rtc_read(struct rtc_time *time) { uint8_t reg_b = cmos_inb(RTC_REGB_STATUS); time->second = cmos_read_time(RTC_REG_SECOND, reg_b); diff --git a/sys/amd64/hw/timer.c b/sys/amd64/hw/timer.c index 3d94bdf..638d1a6 100644 --- a/sys/amd64/hw/timer.c +++ b/sys/amd64/hw/timer.c @@ -25,11 +25,13 @@ uint64_t system_time = 0; static uint32_t timer_tick(void *arg) { switch ((uint64_t) arg) { case TIMER_PIT: +#if defined(VESA_ENABLE) ++int_timer_ticks; if (int_timer_ticks >= 500) { con_blink(); int_timer_ticks = 0; } +#endif // Each tick is approx. 1ms, so add 1ms to system time system_time += 1000000; break; @@ -60,7 +62,7 @@ void amd64_timer_init(void) { // LAPIC Timer is only used to trigger task switches LAPIC(LAPIC_REG_TMRDIV) = 0x3; LAPIC(LAPIC_REG_LVTT) = 32 | (1 << 17); - LAPIC(LAPIC_REG_TMRINITCNT) = 10000; + LAPIC(LAPIC_REG_TMRINITCNT) = 1562500; LAPIC(LAPIC_REG_TMRCURRCNT) = 0; get_cpu()->ticks = 0; diff --git a/sys/amd64/syscall.c b/sys/amd64/syscall.c index d9267c6..0345218 100644 --- a/sys/amd64/syscall.c +++ b/sys/amd64/syscall.c @@ -11,6 +11,7 @@ #include "sys/fcntl.h" #include "sys/tty.h" #include "sys/amd64/mm/phys.h" +#include "sys/amd64/hw/rtc.h" #include "sys/amd64/mm/map.h" #include "sys/fs/pty.h" #include "sys/time.h" @@ -41,8 +42,11 @@ static void sys_sigret(void); __attribute__((noreturn)) void amd64_syscall_yield_stopped(void); +uint64_t syscall_last_time = 0; +uint64_t syscall_count = 0; + intptr_t amd64_syscall(uintptr_t rdi, uintptr_t rsi, uintptr_t rdx, uintptr_t rcx, uintptr_t r10, uintptr_t rax) { - asm volatile ("cli"); + ++syscall_count; switch (rax) { case SYSCALL_NR_READ: return sys_read((int) rdi, (void *) rsi, (size_t) rdx); @@ -392,13 +396,21 @@ static int sys_nanosleep(const struct timespec *req, struct timespec *rem) { } static int sys_gettimeofday(struct timeval *tv, struct timezone *tz) { - tz->tz_dsttime = 0; - tz->tz_minuteswest = 0; + if (tz) { + tz->tz_dsttime = 0; + tz->tz_minuteswest = 0; + } + + uint64_t secs = system_time / 1000000000ULL; + + struct rtc_time time_rtc; + rtc_read(&time_rtc); + secs += time_rtc.second + time_rtc.minute * 60 + time_rtc.hour * 3600; // System time is in nanos // TODO: use RTC-provided time for full system time tv->tv_usec = (system_time / 1000) % 1000000; - tv->tv_sec = system_time / 1000000000ULL; + tv->tv_sec = secs; return 0; } diff --git a/sys/ring.c b/sys/ring.c index 086d74d..2e57b51 100644 --- a/sys/ring.c +++ b/sys/ring.c @@ -1,3 +1,4 @@ +#include "sys/thread.h" #include "sys/assert.h" #include "sys/debug.h" #include "sys/ring.h" @@ -44,22 +45,24 @@ static inline void ring_advance_write(struct ring *ring) { int ring_getc(struct thread *ctx, struct ring *ring, char *out) { uintptr_t flags; - spin_lock_irqsave(&ring->lock, &flags); + //spin_lock_irqsave(&ring->lock, &flags); do { if (ring_avail(ring)) { break; } - spin_release(&ring->lock); + //spin_release(&ring->lock); + ctx->flags |= THREAD_WAITING; asm volatile ("sti; hlt"); - spin_lock(&ring->lock); + ctx->flags &= ~THREAD_WAITING; + //spin_lock(&ring->lock); } while (1); *out = ring->data[ring->rdptr]; ring_advance_read(ring); - spin_release_irqrestore(&ring->lock, &flags); + //spin_release_irqrestore(&ring->lock, &flags); return 0; } @@ -80,25 +83,29 @@ ssize_t ring_read(struct thread *ctx, struct ring *ring, void *buf, size_t count return pos; } -int ring_putc(struct ring *ring, char c) { +int ring_putc(struct thread *ctx, struct ring *ring, char c) { uintptr_t flags; - spin_lock_irqsave(&ring->lock, &flags); + //spin_lock_irqsave(&ring->lock, &flags); do { if (ring_writable(ring)) { break; } - spin_release(&ring->lock); - asm volatile ("sti; hlt"); - spin_lock(&ring->lock); + //spin_release(&ring->lock); + if (ctx) { + asm volatile ("sti; hlt"); + } else { + asm volatile ("sti; hlt"); + } + //spin_lock(&ring->lock); } while (1); ring->data[ring->wrptr] = c; ring_advance_write(ring); - spin_release_irqrestore(&ring->lock, &flags); + //spin_release_irqrestore(&ring->lock, &flags); return 0; } diff --git a/sys/string.c b/sys/string.c index 8cb3ac8..4315947 100644 --- a/sys/string.c +++ b/sys/string.c @@ -172,6 +172,13 @@ uint32_t *memsetl(uint32_t *blk, uint32_t v, size_t sz) { return blk; } +uint64_t *memsetq(uint64_t *blk, uint64_t v, size_t sz) { + for (size_t i = 0; i < sz; ++i) { + blk[i] = v; + } + return blk; +} + void *memcpy(void *dst, const void *src, size_t sz) { for (size_t i = 0; i < sz; ++i) { ((char *) dst)[i] = ((const char *) src)[i]; @@ -179,3 +186,9 @@ void *memcpy(void *dst, const void *src, size_t sz) { return dst; } +uint64_t *memcpyq(uint64_t *restrict dst, const uint64_t *restrict src, size_t sz) { + for (size_t i = 0; i < sz; ++i) { + dst[i] = src[i]; + } + return dst; +} diff --git a/sys/tty.c b/sys/tty.c index 5aee163..fdad8dc 100644 --- a/sys/tty.c +++ b/sys/tty.c @@ -33,7 +33,7 @@ static struct ring tty_ring = {0}; // This function receives keystrokes from keyboard drivers void tty_buffer_write(int tty_no, char c) { - ring_putc(&tty_ring, c); + ring_putc(NULL, &tty_ring, c); } void tty_init(void) { diff --git a/sys/vfs/pty.c b/sys/vfs/pty.c index 01af730..cce7c69 100644 --- a/sys/vfs/pty.c +++ b/sys/vfs/pty.c @@ -15,16 +15,6 @@ static ssize_t pty_master_read(struct chrdev *dev, void *buf, size_t count, size static ssize_t pty_slave_write(struct chrdev *dev, const void *buf, size_t count, size_t off); static ssize_t pty_slave_read(struct chrdev *dev, void *buf, size_t count, size_t off); -//static struct chrdev pty_master_dev = { -// .read = pty_master_read, -// .write = pty_master_write -//}; -// -//static struct chrdev pty_slave_dev = { -// .read = pty_slave_read, -// .write = pty_slave_write -//}; - static ssize_t pty_slave_write(struct chrdev *dev, const void *buf, size_t off, size_t count) { // Slave writes -> pty output -> Master reads // AS-IS @@ -33,7 +23,7 @@ static ssize_t pty_slave_write(struct chrdev *dev, const void *buf, size_t off, int res = 0; for (size_t i = 0; i < count; ++i) { - if ((res = ring_putc(&pty->ring_output, ((const char *) buf)[i])) < 0) { + if ((res = ring_putc(get_cpu()->thread, &pty->ring_output, ((const char *) buf)[i])) < 0) { break; } } @@ -75,7 +65,7 @@ static ssize_t pty_master_write(struct chrdev *dev, const void *buf, size_t pos, int res = 0; for (size_t i = 0; i < count; ++i) { - if ((res = ring_putc(&pty->ring_input, ((const char *) buf)[i])) < 0) { + if ((res = ring_putc(get_cpu()->thread, &pty->ring_input, ((const char *) buf)[i])) < 0) { break; } } diff --git a/usr/Makefile b/usr/Makefile index 405dc78..8128f20 100644 --- a/usr/Makefile +++ b/usr/Makefile @@ -6,7 +6,8 @@ DIRS=$(O) \ $(O)/libc HDRS=$(shell find $(S) -type f -name "*.h") STAGE_BIN=$(STAGE)/init \ - $(STAGE)/hello + $(STAGE)/hello \ + $(STAGE)/time CFLAGS=-ffreestanding \ -nostdlib \ @@ -35,7 +36,8 @@ libc_OBJS=$(O)/libc/crt0.o \ $(O)/libc/malloc.o \ $(O)/libc/dirent.o \ $(O)/libc/signal.o \ - $(O)/libc/global.o + $(O)/libc/global.o \ + $(O)/libc/time.o sys_CRTBEGIN=$(shell $(CC) $(CFLAGS) -print-file-name=crtbegin.o) sys_CRTEND=$(shell $(CC) $(CFLAGS) -print-file-name=crtend.o) @@ -60,6 +62,16 @@ $(STAGE)/init: init.c $(libc_CRTI) $(libc_CRTN) $(O)/libc.a $(libc_CRTN) \ $(usr_STATIC_LIBS) +$(STAGE)/time: time.c $(libc_CRTI) $(libc_CRTN) $(O)/libc.a + @printf " CC\t%s\n" $(@:$(STAGE)/%=/%) + @$(CC) -o $@ $(CFLAGS) $(usr_LDFLAGS) \ + $(libc_CRTI) \ + $(sys_CRTBEGIN) \ + time.c \ + $(sys_CRTEND) \ + $(libc_CRTN) \ + $(usr_STATIC_LIBS) + $(STAGE)/hello: hello.c $(libc_CRTI) $(libc_CRTN) $(O)/libc.a @printf " CC\t%s\n" $(@:$(STAGE)/%=/%) @$(CC) -o $@ $(CFLAGS) $(usr_LDFLAGS) \ diff --git a/usr/init.c b/usr/init.c index 506cad0..803c65d 100644 --- a/usr/init.c +++ b/usr/init.c @@ -18,6 +18,13 @@ #define clear() \ write(STDOUT_FILENO, "\033[2J", 4) +#define BOX_ANGLE_UL "\332" +#define BOX_ANGLE_UR "\277" +#define BOX_ANGLE_LL "\300" +#define BOX_ANGLE_LR "\331" +#define BOX_HOR "\304" +#define BOX_VERT "\263" + // extern __attribute__((noreturn)) void abort(void); @@ -178,24 +185,62 @@ static int b_cat(const char *arg) { static int b_curs(const char *arg) { char c; + size_t w = 60; + size_t h = 20; + size_t off_y = (25 - h) / 2 + 1; + size_t off_x = (80 - w) / 2; + + const char *lines[18] = { + NULL, + "Demo something", + NULL, + "Slow as hell" + }; + clear(); while (1) { - // Draw some kind of status bar - curs_set(25, 1); - printf("\033[7m This is statusbar\033[K"); - if (c >= ' ') { - curs_set(25, 79); - printf("%c\033[0m", c); + printf("\033[47;30m"); + + curs_set(off_y, off_x); + printf(BOX_ANGLE_UL); + for (size_t i = 0; i < w; ++i) { + printf(BOX_HOR); } + printf(BOX_ANGLE_UR); + + for (size_t i = 0; i < h - 2; ++i) { + curs_set(off_y + 1 + i, off_x); + printf(BOX_VERT); + for (size_t j = 0; j < w; ++j) { + printf(" "); + } + if (lines[i]) { + curs_set(off_y + 1 + i, off_x + (w - strlen(lines[i])) / 2); + printf("%s", lines[i]); + } + curs_set(off_y + 1 + i, off_x + w + 1); + printf(BOX_VERT); + } + + curs_set(off_y + h - 3, off_x + (w - 8) / 2); + printf("\033[0m\033[7m[ OK ]\033[47;30m"); + curs_set(off_y + h - 1, off_x); + printf(BOX_ANGLE_LL); + for (size_t i = 0; i < w; ++i) { + printf(BOX_HOR); + } + printf(BOX_ANGLE_LR); + printf("\033[0m"); + curs_set(1, 1); if (read(STDIN_FILENO, &c, 1) < 0) { break; } - if (c == 'q') { + if (c == 'q' || c == '\n') { break; } } @@ -294,6 +339,19 @@ int main(int argc, char **argv) { int res; prompt(); + +#if 0 + if ((res = fork()) < 0) { + perror("fork()"); + return -1; + } else if (res == 0) { + if (execve("/time", NULL, NULL) != 0) { + perror("execve()"); + } + exit(-1); + } +#endif + while (1) { if (read(STDIN_FILENO, &c, 1) < 0) { break; diff --git a/usr/libc/include/bits/syscall.h b/usr/libc/include/bits/syscall.h index 7950cca..8e67833 100644 --- a/usr/libc/include/bits/syscall.h +++ b/usr/libc/include/bits/syscall.h @@ -22,5 +22,6 @@ int chdir(const char *filename); char *getcwd(char *buf, size_t size); int nanosleep(const struct timespec *req, struct timespec *rem); int openpty(int *amaster, int *aslave); +int gettimeofday(struct timeval *tv, struct timezone *tz); __attribute__((noreturn)) void exit(int code); diff --git a/usr/libc/include/time.h b/usr/libc/include/time.h new file mode 100644 index 0000000..2bfead5 --- /dev/null +++ b/usr/libc/include/time.h @@ -0,0 +1,4 @@ +#pragma once +#include + +int usleep(long us); diff --git a/usr/libc/syscall.c b/usr/libc/syscall.c index 0d041c1..c49feba 100644 --- a/usr/libc/syscall.c +++ b/usr/libc/syscall.c @@ -133,6 +133,10 @@ int openpty(int *master, int *slave) { return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NRX_OPENPTY, master, slave)); } +int gettimeofday(struct timeval *tv, struct timezone *tz) { + return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NR_GETTIMEOFDAY, tv, tz)); +} + // Although sbrk() is implemented in userspace, I guess it should also be here void *sbrk(intptr_t inc) { if (inc == 0) { diff --git a/usr/libc/time.c b/usr/libc/time.c new file mode 100644 index 0000000..756feac --- /dev/null +++ b/usr/libc/time.c @@ -0,0 +1,7 @@ +#include "time.h" +#include "bits/syscall.h" + +int usleep(long us) { + struct timeval tv = { us / 1000000, (us % 1000) * 1000 }; + return nanosleep(&tv, NULL); +} diff --git a/usr/time.c b/usr/time.c new file mode 100644 index 0000000..d04801d --- /dev/null +++ b/usr/time.c @@ -0,0 +1,12 @@ +#include +#include + +int main() { + struct timeval tv; + while (1) { + usleep(100000); + gettimeofday(&tv, NULL); + + printf("\033[s\033[1;70f%u\033[u", tv.tv_sec); + } +}