diff --git a/.gitignore b/.gitignore index 17addf0..46dc322 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.o umka_shell umka_fuse +umka_os mkdirrange mkfilepattern *.img diff --git a/makefile b/makefile index de18939..81c5bc4 100644 --- a/makefile +++ b/makefile @@ -6,7 +6,7 @@ CFLAGS_32=$(CFLAGS) -m32 LDFLAGS= LDFLAGS_32=$(LDFLAGS) -m32 -all: umka_shell umka_fuse umka.sym umka.prp umka.lst tags tools/mkdirrange tools/mkfilepattern covpreproc default.skn skin.skn +all: umka_shell umka_fuse umka_os umka.sym umka.prp umka.lst tags tools/mkdirrange tools/mkfilepattern covpreproc default.skn skin.skn covpreproc: covpreproc.c $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ @@ -17,6 +17,9 @@ umka_shell: umka_shell.o umka.o trace.o trace_lbr.o vdisk.o vnet.o lodepng.o pci umka_fuse: umka_fuse.o umka.o trace.o trace_lbr.o vdisk.o pci.o $(CC) $(LDFLAGS_32) $^ -o $@ `pkg-config fuse3 --libs` +umka_os: umka_os.o umka.o trace.o trace_lbr.o vdisk.o pci.o + $(CC) $(LDFLAGS_32) $^ -o $@ + umka.o umka.fas: umka.asm INCLUDE="$(KOLIBRI)/kernel/trunk;$(KOLIBRI)/programs/develop/libraries/libcrash/trunk" $(FASM) $< umka.o -s umka.fas -m 1234567 @@ -62,6 +65,9 @@ umka_shell.o: umka_shell.c umka.h trace.h umka_fuse.o: umka_fuse.c umka.h $(CC) $(CFLAGS_32) `pkg-config fuse3 --cflags` -c $< +umka_os.o: umka_os.c umka.h + $(CC) $(CFLAGS_32) -c $< + tools/mkdirrange: tools/mkdirrange.c $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ @@ -71,5 +77,5 @@ tools/mkfilepattern: tools/mkfilepattern.c .PHONY: all clean clean: - rm -f *.o umka_shell umka_fuse umka.fas umka.sym umka.lst umka.prp coverage tools/mkdirrange tools/mkfilepattern + rm -f *.o umka_shell umka_fuse umka_os umka.fas umka.sym umka.lst umka.prp coverage tools/mkdirrange tools/mkfilepattern diff --git a/umka_os.c b/umka_os.c new file mode 100644 index 0000000..657f711 --- /dev/null +++ b/umka_os.c @@ -0,0 +1,106 @@ +#include +#include +#include +#include +#include "umka.h" + +#define THREAD_STACK_SIZE 0x2000 +#define MAX_THREADS 16 + +struct itimerval timeout = {.it_value = {.tv_sec = 0, .tv_usec = 999}}; +sigjmp_buf threads[MAX_THREADS], trampoline; +size_t cur_thread = 0; +size_t thread_cnt = 1; +uint8_t stack_os[THREAD_STACK_SIZE]; +uint8_t stack_thrda[THREAD_STACK_SIZE]; +uint8_t stack_thrdb[THREAD_STACK_SIZE]; + +static void add_new_thread(void (*func)(void), void *stack) { + if (!sigsetjmp(trampoline, 1)) { + __asm__ __inline__ __volatile__ ( + "mov esp, eax;" + "push ecx" + : + : "a"(stack), + "c"(func) + : "memory"); + if (!sigsetjmp(threads[thread_cnt++], 1)) { + longjmp(trampoline, 1); + } else { + __asm__ __inline__ __volatile__ ( + "pop ecx;" + "call ecx" + : + : + : "memory"); + } + } +} + +void scheduler(int signo, siginfo_t *info, void *context) { + (void)signo; + (void)info; + (void)context; + printf("##### cur_thread: %u\n", cur_thread); + if (!sigsetjmp(threads[cur_thread], 1)) { + printf("##### saved\n"); + cur_thread += 1; + if (cur_thread == thread_cnt) { + cur_thread = 0; + } + setitimer(ITIMER_PROF, &timeout, NULL); + siglongjmp(threads[cur_thread], 1); + } +} + +void os() { + printf("0 osidle begin\n"); + raise(SIGPROF); + while (1) { // osloop + for (int i = 0; i < 10000000; i++) ; + printf("0 osloop\n"); + fflush(stdout); + } + printf("0 osidle end\n"); +} + +void thrda() { + printf("1 thrd a begin\n"); + while (1) { + for (int i = 0; i < 10000000; i++) ; + printf("1 thrd a\n"); + fflush(stdout); + } + printf("1 thrd a end\n"); +} + +void thrdb() { + printf("2 thrd b begin\n"); + while (1) { + for (int i = 0; i < 10000000; i++) ; + printf("2 thrd b\n"); + fflush(stdout); + } + printf("2 thrd b end\n"); +} + +int main() { + struct sigaction sa; + + sa.sa_sigaction = scheduler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + + if (sigaction(SIGPROF, &sa, NULL) == -1) { + printf("Can't install signal handler!\n"); + return 1; + } + +// add_new_thread(os, stack_os[0x1000]); + add_new_thread(thrda, stack_thrda+THREAD_STACK_SIZE); + add_new_thread(thrdb, stack_thrdb+THREAD_STACK_SIZE); + + os(); + + return 0; +}