about summary refs log tree commit diff stats
path: root/init.soso
blob: 8753b4121a7b548fcd5735cf78ba09931eb3ffa9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Some OS-specific preliminaries for Soso.

# Memory layout
#
# 0x40000000 - 0x40001ffff - for ELF code+data
# 0x40002000 - 0x401ffffff - for heap
== code 0x40000000
== data 0x40001000

# Syscalls
#
# We don't have libc, so we need to know Soso's precise syscall layout.
# https://github.com/ozkl/soso/blob/master/kernel/syscalltable.h
== code

syscall_exit:  # status/ebx : int
    b8/copy-to-eax 8/imm32
    cd/syscall 0x80/imm8

syscall_read:  # fd/ebx : int, buf/ecx : addr, size/edx : int -> nbytes-or-error/eax : int
    b8/copy-to-eax 2/imm32
    cd/syscall 0x80/imm8
    c3/return

syscall_write:  # fd/ebx : int, buf/ecx : addr, size/edx : int -> nbytes-or-error/eax : int
    b8/copy-to-eax 3/imm32
    cd/syscall 0x80/imm8
    c3/return

syscall_open:  # filename/ebx : (addr kernel-string), flags/ecx : int -> fd-or-error/eax : int
    b8/copy-to-eax 0/imm32
    cd/syscall 0x80/imm8
    c3/return

syscall_close:  # fd/ebx : int -> status/eax
    b8/copy-to-eax 1/imm32
    cd/syscall 0x80/imm8
    c3/return

# anonymous mmap not implemented
ss="o">-space:space-address <- new space:literal 30:literal) (chan:channel-address <- next-input) ; n = 0 (n:integer <- copy 0:literal) { begin (done?:boolean <- less-than n:integer 5:literal) (break-unless done?:boolean) ; other threads might get between these prints ($print (("produce: " literal))) (print-integer nil:literal/terminal n:integer) ($print (("\n" literal))) ; 'box' n into a dynamically typed 'tagged value' because that's what ; channels take (n2:integer <- copy n:integer) (n3:tagged-value-address <- init-tagged-value integer:literal n2:integer) (chan:channel-address/deref <- write chan:channel-address n3:tagged-value-address/deref) (n:integer <- add n:integer 1:literal) (loop) } ]) (function consumer [ ; consume and print integers from a channel (default-space:space-address <- new space:literal 30:literal) (chan:channel-address <- next-input) { begin ; read a tagged value from the channel (x:tagged-value chan:channel-address/deref <- read chan:channel-address) ; unbox the tagged value into an integer (n2:integer <- maybe-coerce x:tagged-value integer:literal) ; other threads might get between these prints ($print (("consume: " literal))) (print-integer nil:literal/terminal n2:integer) ($print (("\n" literal))) (loop) } ]) (function main [ (default-space:space-address <- new space:literal 30:literal) (chan:channel-address <- init-channel 3:literal) ; create two background 'routines' that communicate by a channel (routine1:integer <- fork consumer:fn nil:literal/globals nil:literal/limit chan:channel-address) (routine2:integer <- fork producer:fn nil:literal/globals nil:literal/limit chan:channel-address) (sleep until-routine-done:literal routine1:integer) (sleep until-routine-done:literal routine2:integer) ])