From 83e17e29456ec9b6d45f4d9f2634eb280c6f414f Mon Sep 17 00:00:00 2001 From: stefan Date: Wed, 19 Apr 2023 20:50:10 -0400 Subject: ticket locks --- sys/Makefile | 13 ++++--- sys/dev/cpu.c | 6 --- sys/dev/fdt/fdt.c | 11 +++--- sys/include/asm.h | 1 + sys/include/fdt.h | 2 +- sys/include/kalloc.h | 15 +++++++ sys/include/mm/kalloc.h | 15 ------- sys/include/spinlock.h | 22 ++++++----- sys/kern/entry.S | 69 --------------------------------- sys/kern/init.c | 51 ------------------------ sys/kern/kernel.lds | 58 --------------------------- sys/kern/mm/kalloc.c | 66 ------------------------------- sys/kern/printf.c | 101 ------------------------------------------------ sys/kern/spinlock.c | 38 ------------------ sys/sys/entry.S | 69 +++++++++++++++++++++++++++++++++ sys/sys/init.c | 51 ++++++++++++++++++++++++ sys/sys/kernel.lds | 58 +++++++++++++++++++++++++++ sys/sys/mm/kalloc.c | 74 +++++++++++++++++++++++++++++++++++ sys/sys/printf.c | 96 +++++++++++++++++++++++++++++++++++++++++++++ sys/sys/smp/spinlock.c | 38 ++++++++++++++++++ 20 files changed, 428 insertions(+), 426 deletions(-) delete mode 100644 sys/dev/cpu.c create mode 100644 sys/include/kalloc.h delete mode 100644 sys/include/mm/kalloc.h delete mode 100644 sys/kern/entry.S delete mode 100644 sys/kern/init.c delete mode 100644 sys/kern/kernel.lds delete mode 100644 sys/kern/mm/kalloc.c delete mode 100644 sys/kern/printf.c delete mode 100644 sys/kern/spinlock.c create mode 100644 sys/sys/entry.S create mode 100644 sys/sys/init.c create mode 100644 sys/sys/kernel.lds create mode 100644 sys/sys/mm/kalloc.c create mode 100644 sys/sys/printf.c create mode 100644 sys/sys/smp/spinlock.c diff --git a/sys/Makefile b/sys/Makefile index 02ee0df..a766174 100644 --- a/sys/Makefile +++ b/sys/Makefile @@ -8,11 +8,11 @@ TARGETDIR=../mainboard/${TARGET} .endif SRC=\ - kern/entry.S\ - kern/init.c\ - kern/printf.c\ - kern/mm/kalloc.c\ - kern/spinlock.c\ + sys/entry.S\ + sys/init.c\ + sys/printf.c\ + sys/mm/kalloc.c\ + sys/smp/spinlock.c\ dev/fdt/fdt.c @@ -25,8 +25,9 @@ ${BUILDDIR}/kernel.elf: ${SRC} -DLOAD_ADDR=${LOAD_ADDR}\ -DNPROC=${NPROC}\ -DPAGE_SIZE=${PAGE_SIZE}\ + -I ../include\ -I ./include\ - ${CFLAGS} -T kern/kernel.lds ${LDFLAGS}\ + ${CFLAGS} -T sys/kernel.lds ${LDFLAGS}\ -L../lib/${BUILDDIR}/\ -l:libc.a\ -o $@ diff --git a/sys/dev/cpu.c b/sys/dev/cpu.c deleted file mode 100644 index f96b807..0000000 --- a/sys/dev/cpu.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -extern struct hart harts[NPROC]; - - - diff --git a/sys/dev/fdt/fdt.c b/sys/dev/fdt/fdt.c index 4b132e2..0bd0a52 100644 --- a/sys/dev/fdt/fdt.c +++ b/sys/dev/fdt/fdt.c @@ -20,9 +20,10 @@ fdt_walk(struct fdt_header *header) printf("header->size_dt_strings: %d\n", fdt_uint32(header->size_dt_strings)); printf("header->size_dt_struct: %d\n", fdt_uint32(header->size_dt_struct)); - uint8_t *dts = header + fdt_uint32(header->off_dt_struct) + sizeof(uint32_t); - uint8_t *dtstr = header + fdt_uint32(header->off_dt_strings); - printf("parsing dt struct @%p...\n", dts); - printf(dts); + printf("walking the memory reservation block...\n"); + struct fdt_reserve_entry *p = header + fdt_uint32(header->off_mem_rsvmap); +// do { +// printf("reserved entry at %p with size %i\n", p->address, p->size); +// p++; +// } while (!(p->size == 0 && p->address == 0)); } - diff --git a/sys/include/asm.h b/sys/include/asm.h index 86e6354..0995f88 100644 --- a/sys/include/asm.h +++ b/sys/include/asm.h @@ -50,6 +50,7 @@ read_tp(void) { uint64_t x; asm volatile("addi %0, tp, 0" : "=r"(x)); + return x; } #endif /* _ASM_H */ diff --git a/sys/include/fdt.h b/sys/include/fdt.h index ca1cea0..77c9d6e 100644 --- a/sys/include/fdt.h +++ b/sys/include/fdt.h @@ -40,7 +40,7 @@ struct fdt_node_header { char name[]; }; -void walk_fdt(struct fdt_header *header); +void fdt_walk(struct fdt_header *header); #define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ #define FDT_TAGSIZE sizeof(fdt32_t) diff --git a/sys/include/kalloc.h b/sys/include/kalloc.h new file mode 100644 index 0000000..10adbda --- /dev/null +++ b/sys/include/kalloc.h @@ -0,0 +1,15 @@ +#ifndef _KALLOC_H +#define _KALLOC_H + +void *kalloc(void); + +void *kzalloc(void); + +void kfree(void *); + +void kalloc_init(void); + +void walkfree(void); + +#endif /* _KALLOC_H */ + diff --git a/sys/include/mm/kalloc.h b/sys/include/mm/kalloc.h deleted file mode 100644 index 10adbda..0000000 --- a/sys/include/mm/kalloc.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _KALLOC_H -#define _KALLOC_H - -void *kalloc(void); - -void *kzalloc(void); - -void kfree(void *); - -void kalloc_init(void); - -void walkfree(void); - -#endif /* _KALLOC_H */ - diff --git a/sys/include/spinlock.h b/sys/include/spinlock.h index ef81499..82c1585 100644 --- a/sys/include/spinlock.h +++ b/sys/include/spinlock.h @@ -1,15 +1,17 @@ -#ifndef _LOCK_H -#define _LOCK_H +#ifndef _SPINLOCK_H +#define _SPINLOCK_H -struct spinlock { - int locked; - int tp; -}; +/* fifo ticket lock implementation */ -void initlock(struct spinlock *); +typedef struct _spinlock { + int ticket; + int turn; +} spinlock_t; -void acquire(struct spinlock *); +void initlock(spinlock_t *); -void release(struct spinlock *); +void acquire(spinlock_t *); -#endif /* _LOCK_H */ +void release(spinlock_t *); + +#endif /* _SPINLOCK_H */ diff --git a/sys/kern/entry.S b/sys/kern/entry.S deleted file mode 100644 index 9bf72ea..0000000 --- a/sys/kern/entry.S +++ /dev/null @@ -1,69 +0,0 @@ -.section ".text.init" - -// entrypoint for boot hart(s). a0: hartid, a1: *fdt -.globl _start - - -// entrypoint for other harts. a0: hartid, a1: unused for now -.global _mpentry - -_start: - /* disable interrupts and paging */ - csrw satp, zero - csrw sie, zero - csrw sip, zero - - .option push - .option norelax - la gp, __global_pointer$ - .option pop - - /* setup stack. - * stack grows toward lower address so sp will mark end of frame. - */ - addi t0, a0, 1 - li t1, PAGE_SIZE - la sp, __stack_start - mul t1, t1, t0 - add sp, sp, t1 - - /* setup thread pointer */ - mv tp, a0 - - /* the label _boot_hart is shared between threads. after the first atomic swap, all other harts will branch to mpentry */ - li a2, 1 - lla a3, _boot_hart - amoswap.w a3, a2, (a3) - bnez a3, _mpentry - - /* clear the bss section */ - la a2, __bss_start - la a3, __bss_end -1: - sd zero, (a2) - addi a2, a2, __SIZEOF_POINTER__ - blt a2, a3, 1b -2: - call init - j _spin - -_mpentry: - /* satp = 0, sstatus.sie = 0, a0 = hartid, a1 = opaque */ - - call mpinit - /* shouldn't reach this point */ - j _spin - -_spin: - wfi - j _spin - -.section ".data" -_boot_hart: - .word 0 - -.section ".rodata" -/* linker imports */ -.globl HEAP_START -HEAP_START: .dword __heap_start - diff --git a/sys/kern/init.c b/sys/kern/init.c deleted file mode 100644 index a58d3bc..0000000 --- a/sys/kern/init.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include -#include -#include - -extern uint64_t HEAP_START; - -#define HLT()\ - for (;;)\ - asm("wfi") - -void -init(unsigned long hartid, struct fdt_header *fdt) -{ - - printf("booting from hart #%d\n", hartid); - asm volatile ("mv tp, %0" : : "r"(hartid)); - if (fdt_uint32(fdt->magic) == FDT_HEADER_MAGIC) - printf("found flattened device tree at %p!\n", (uint64_t)fdt); - - printf("parsing device tree!\n"); - fdt_walk(fdt); - - printf("setting up the heap at %p\n", HEAP_START); - kalloc_init(); - printf("done!\n"); - // printf("printing free pages:\n"); - ///walkfree(); - printf("bringing up other harts...\n"); - // todo: detect harts from device tree can also be used for more conservative stack allocation - for (int i = 0; i < NPROC; ++i) { - if (i == hartid) { - printf("skipping hart #%d\n", i); - continue; - } - printf("starting hart #%d\n", i); - struct sbiret r = _start_hart(i, (unsigned long)LOAD_ADDR); - if (r.err != SBI_SUCCESS) - printf("ERROR"); - } -} - -void -mpinit(unsigned long hartid) -{ - printf("mpinit: %d", hartid); - HLT(); -} - diff --git a/sys/kern/kernel.lds b/sys/kern/kernel.lds deleted file mode 100644 index 2e2fe29..0000000 --- a/sys/kern/kernel.lds +++ /dev/null @@ -1,58 +0,0 @@ -OUTPUT_ARCH(riscv) -ENTRY(_start) - -SECTIONS -{ - . = LOAD_ADDR; - . = ALIGN(PAGE_SIZE); - - .text : - { - PROVIDE(__text_start = .); - *(.text.init) - *(.text .text.*) - . = ALIGN(8); - PROVIDE(__text_end = .); - } - . = ALIGN(PAGE_SIZE); - - PROVIDE(__global_pointer$ = .); - - .rodata : - { - PROVIDE(__rodata_start = .); - *(.rodata .rodata.*) - . = ALIGN(8); - PROVIDE(__rodata_end = .); - } - - . = ALIGN(PAGE_SIZE); - - .data : - { - PROVIDE(__data_start = .); - *(.sdata .sdata.*) - *(.data .data.*) - *(.readmostly.data) - *(*.data) - . = ALIGN(8); - PROVIDE(__data_end = .); - } - - . = ALIGN(PAGE_SIZE); - - .bss : - { - PROVIDE(__bss_start = .); - *(.sbss .sbss.*) - *(.bss .bss.*) - . = ALIGN(8); - PROVIDE(__bss_end = .); - } - - . = ALIGN(PAGE_SIZE); - - PROVIDE(__stack_start = .); - PROVIDE(__stack_end = __stack_start + (PAGE_SIZE * NPROC)); - PROVIDE(__heap_start = __stack_end); -} diff --git a/sys/kern/mm/kalloc.c b/sys/kern/mm/kalloc.c deleted file mode 100644 index bfd4f3f..0000000 --- a/sys/kern/mm/kalloc.c +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include -#include -#include -#include - -extern uint64_t HEAP_START; - -typedef struct freenode { - struct freenode *next; -} freenode_t; - -freenode_t *head = NULL; - -void * -kalloc(void) -{ - freenode_t *p = head; - - if (p == NULL) - return NULL; - - head = p->next; - return p; -} - -void * -kzalloc(void) -{ - freenode_t *p = kalloc(); - memset(p, 0, PAGE_SIZE); - return p; -} - -void -kfree(void *p) -{ - if (p == NULL) - return; - - freenode_t *tmp = head; - head = p; - head->next = tmp; -} - -void -kalloc_init(void) -{ - freenode_t *p = (freenode_t*)HEAP_START; - for (;(unsigned long)p + PAGE_SIZE <= (HEAP_START + 0x100000); p += PAGE_SIZE) { - kfree(p); - } -} - -void -walkfree(void) -{ - freenode_t *node = head; - int nfree = 0; - while (node) { - printf("freenode at %p\n", node); - node = node->next; - nfree++; - } - printf("found and printed %d free pages!\n", nfree); -} diff --git a/sys/kern/printf.c b/sys/kern/printf.c deleted file mode 100644 index 89add9e..0000000 --- a/sys/kern/printf.c +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include -#include -#include -#include - -static char digits[] = "0123456789abcdef"; - -struct spinlock mutex; -int locked = 0; - -int -puts(const char *str) -{ - do { - sbi_console_putchar(*str); - } while (*(str++) != '\0'); -} - -#define PUTCHAR(c) sbi_console_putchar(c) - -static void -printint(int xx, int base, int sign) -{ - char buf[16]; - int i; - unsigned int x; - - if (sign && (sign = xx < 0)) - x = -xx; - else - x = xx; - - i = 0; - do { - buf[i++] = digits[x % base]; - } while ((x /= base) != 0); - - if (sign) - buf[i++] = '-'; - while (--i >= 0) - PUTCHAR(buf[i]); - -} - -static void -printptr(uint64_t x) -{ - int i; - puts("0x"); - for (i = 0; i < (sizeof(uint64_t) * 2); i++, x <<= 4) - PUTCHAR(digits[x >> (sizeof(int64_t) * 8 - 4)]); -} - -void -printf(const char *fmt, ...) -{ - va_list ap; - int i, c, _locked; - char *s; - - _locked = locked; - if (_locked) - acquire(&mutex); - - va_start(ap, fmt); - - for (i = 0; (c = fmt[i] & 0xff) != 0; i++) { - if (c != '%') { - PUTCHAR(c); - continue; - } - c = fmt[++i] & 0xff; - if (!c) - break; - - switch (c) { - case 'd': - case 'i': - printint(va_arg(ap, int), 10, 1); - break; - case 'x': - printint(va_arg(ap, int), 16, 1); - break; - case 'p': - printptr(va_arg(ap, uint64_t)); - break; - case '%': - PUTCHAR('%'); - break; - } - } - if (_locked) - release(&mutex); -} - -void printf_init(void) -{ - initlock(&mutex); - locked = 1; -} diff --git a/sys/kern/spinlock.c b/sys/kern/spinlock.c deleted file mode 100644 index ade270f..0000000 --- a/sys/kern/spinlock.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include - -void -initlock(struct spinlock *l) -{ - l->locked = 0; -} - -void -acquire(struct spinlock *l) -{ - sie_disable(); - - if (l->locked) - return; - - while (__sync_lock_test_and_set(&l->locked, 1)) - ; - - __sync_synchronize(); -} - -void -release(struct spinlock *l) -{ - sie_disable(); // avoid deadlock - - if (l->locked) - return; // interrupts are still disabled, what to do here? - - /* fence */ - __sync_synchronize(); - - __sync_lock_release(&l->locked); - - sie_enable(); -} diff --git a/sys/sys/entry.S b/sys/sys/entry.S new file mode 100644 index 0000000..9bf72ea --- /dev/null +++ b/sys/sys/entry.S @@ -0,0 +1,69 @@ +.section ".text.init" + +// entrypoint for boot hart(s). a0: hartid, a1: *fdt +.globl _start + + +// entrypoint for other harts. a0: hartid, a1: unused for now +.global _mpentry + +_start: + /* disable interrupts and paging */ + csrw satp, zero + csrw sie, zero + csrw sip, zero + + .option push + .option norelax + la gp, __global_pointer$ + .option pop + + /* setup stack. + * stack grows toward lower address so sp will mark end of frame. + */ + addi t0, a0, 1 + li t1, PAGE_SIZE + la sp, __stack_start + mul t1, t1, t0 + add sp, sp, t1 + + /* setup thread pointer */ + mv tp, a0 + + /* the label _boot_hart is shared between threads. after the first atomic swap, all other harts will branch to mpentry */ + li a2, 1 + lla a3, _boot_hart + amoswap.w a3, a2, (a3) + bnez a3, _mpentry + + /* clear the bss section */ + la a2, __bss_start + la a3, __bss_end +1: + sd zero, (a2) + addi a2, a2, __SIZEOF_POINTER__ + blt a2, a3, 1b +2: + call init + j _spin + +_mpentry: + /* satp = 0, sstatus.sie = 0, a0 = hartid, a1 = opaque */ + + call mpinit + /* shouldn't reach this point */ + j _spin + +_spin: + wfi + j _spin + +.section ".data" +_boot_hart: + .word 0 + +.section ".rodata" +/* linker imports */ +.globl HEAP_START +HEAP_START: .dword __heap_start + diff --git a/sys/sys/init.c b/sys/sys/init.c new file mode 100644 index 0000000..e5cb4e4 --- /dev/null +++ b/sys/sys/init.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include + +extern uint64_t HEAP_START; + +#define HLT()\ + for (;;)\ + asm("wfi") + +void +init(unsigned long hartid, struct fdt_header *fdt) +{ + + printf("booting from hart #%d\n", hartid); + if (fdt_uint32(fdt->magic) == FDT_HEADER_MAGIC) + printf("found flattened device tree at %p!\n", (uint64_t)fdt); + + printf("parsing device tree!\n"); + fdt_walk(fdt); + + printf("setting up the heap at %p\n", HEAP_START); + kalloc_init(); + printf_init(); + printf("done!\n"); + // printf("printing free pages:\n"); + ///walkfree(); + printf("bringing up other harts...\n"); + // todo: detect harts from device tree can also be used for more conservative stack allocation + for (int i = 0; i < NPROC; ++i) { + if (i == hartid) { + printf("skipping hart #%d\n", i); + continue; + } + printf("starting hart #%d\n", i); + struct sbiret r = _start_hart(i, (unsigned long)LOAD_ADDR); + if (r.err != SBI_SUCCESS) + printf("ERROR"); + } +} + +void +mpinit(unsigned long hartid) +{ + printf("mpinit: %d", hartid); + HLT(); +} + diff --git a/sys/sys/kernel.lds b/sys/sys/kernel.lds new file mode 100644 index 0000000..2e2fe29 --- /dev/null +++ b/sys/sys/kernel.lds @@ -0,0 +1,58 @@ +OUTPUT_ARCH(riscv) +ENTRY(_start) + +SECTIONS +{ + . = LOAD_ADDR; + . = ALIGN(PAGE_SIZE); + + .text : + { + PROVIDE(__text_start = .); + *(.text.init) + *(.text .text.*) + . = ALIGN(8); + PROVIDE(__text_end = .); + } + . = ALIGN(PAGE_SIZE); + + PROVIDE(__global_pointer$ = .); + + .rodata : + { + PROVIDE(__rodata_start = .); + *(.rodata .rodata.*) + . = ALIGN(8); + PROVIDE(__rodata_end = .); + } + + . = ALIGN(PAGE_SIZE); + + .data : + { + PROVIDE(__data_start = .); + *(.sdata .sdata.*) + *(.data .data.*) + *(.readmostly.data) + *(*.data) + . = ALIGN(8); + PROVIDE(__data_end = .); + } + + . = ALIGN(PAGE_SIZE); + + .bss : + { + PROVIDE(__bss_start = .); + *(.sbss .sbss.*) + *(.bss .bss.*) + . = ALIGN(8); + PROVIDE(__bss_end = .); + } + + . = ALIGN(PAGE_SIZE); + + PROVIDE(__stack_start = .); + PROVIDE(__stack_end = __stack_start + (PAGE_SIZE * NPROC)); + PROVIDE(__heap_start = __stack_end); +} diff --git a/sys/sys/mm/kalloc.c b/sys/sys/mm/kalloc.c new file mode 100644 index 0000000..a574c41 --- /dev/null +++ b/sys/sys/mm/kalloc.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include +#include +#include + +extern uint64_t HEAP_START; + +typedef struct freenode { + struct freenode *next; +} freenode_t; + +freenode_t *head = NULL; +static spinlock_t mutex; + +void * +kalloc(void) +{ + acquire(&mutex); + freenode_t *p = head; + + if (p == NULL) + return NULL; + + head = p->next; + release(&mutex); + return p; +} + +void * +kzalloc(void) +{ + freenode_t *p = kalloc(); + memset(p, 0, PAGE_SIZE); + return p; +} + +void +kfree(void *p) +{ + if (p == NULL || (uint64_t)p % (uint64_t)PAGE_SIZE) + return; + + acquire(&mutex); + freenode_t *tmp = head; + head = p; + head->next = tmp; + release(&mutex); +} + +void +kalloc_init(void) +{ + initlock(&mutex); + freenode_t *p = (freenode_t*)HEAP_START; + for (;(unsigned long)p + PAGE_SIZE <= (HEAP_START + 0x100000); p += PAGE_SIZE) { + kfree(p); + } +} + +void +walkfree(void) +{ + freenode_t *node = head; + int nfree = 0; + while (node) { + printf("freenode at %p\n", node); + node = node->next; + nfree++; + } + printf("found and printed %d free pages!\n", nfree); +} diff --git a/sys/sys/printf.c b/sys/sys/printf.c new file mode 100644 index 0000000..19b2315 --- /dev/null +++ b/sys/sys/printf.c @@ -0,0 +1,96 @@ +#include +#include +#include +#include +#include + +static char digits[] = "0123456789abcdef"; + +static spinlock_t mutex; + +int +puts(const char *str) +{ + do { + sbi_console_putchar(*str); + } while (*(str++) != '\0'); +} + +#define PUTCHAR(c) sbi_console_putchar(c) + +static void +printint(int xx, int base, int sign) +{ + char buf[16]; + int i; + unsigned int x; + + if (sign && (sign = xx < 0)) + x = -xx; + else + x = xx; + + i = 0; + do { + buf[i++] = digits[x % base]; + } while ((x /= base) != 0); + + if (sign) + buf[i++] = '-'; + while (--i >= 0) + PUTCHAR(buf[i]); + +} + +static void +printptr(uint64_t x) +{ + int i; + puts("0x"); + for (i = 0; i < (sizeof(uint64_t) * 2); i++, x <<= 4) + PUTCHAR(digits[x >> (sizeof(int64_t) * 8 - 4)]); +} + +void +printf(const char *fmt, ...) +{ + va_list ap; + int i, c, _locked; + char *s; + + acquire(&mutex); + + va_start(ap, fmt); + + for (i = 0; (c = fmt[i] & 0xff) != 0; i++) { + if (c != '%') { + PUTCHAR(c); + continue; + } + c = fmt[++i] & 0xff; + if (!c) + break; + + switch (c) { + case 'd': + case 'i': + printint(va_arg(ap, int), 10, 1); + break; + case 'x': + printint(va_arg(ap, int), 16, 1); + break; + case 'p': + printptr(va_arg(ap, uint64_t)); + break; + case '%': + PUTCHAR('%'); + break; + } + } + release(&mutex); +} + +void printf_init(void) +{ + initlock(&mutex); +} diff --git a/sys/sys/smp/spinlock.c b/sys/sys/smp/spinlock.c new file mode 100644 index 0000000..ff48a84 --- /dev/null +++ b/sys/sys/smp/spinlock.c @@ -0,0 +1,38 @@ +/* simple ticket spinlock implementation as outlined by + * John M. Mellor-Crummey and Michael L. Scott. 1991. + * Algorithms for scalable synchronization on shared-memory multiprocessors. + * ACM Trans. Comput. Syst. 9, 1 (Feb. 1991), 21–65. https://doi.org/10.1145/103727.103729 + */ +#include +#include +#include +#include + +void +initlock(spinlock_t *l) +{ + l->ticket = 0; + l->turn = 0; +} + +void +acquire(spinlock_t *l) +{ + sie_disable(); + + + int myturn = __sync_fetch_and_add(&l->ticket, 1); + while (l->turn != myturn) + ; + __sync_synchronize(); +} + +void +release(spinlock_t *l) +{ + sie_disable(); + + __sync_add_and_fetch(&l->turn, 1); + + sie_enable(); +} -- cgit v1.2.3