From: Matthias Kruk Date: Sat, 8 Aug 2020 10:27:27 +0000 (+0900) Subject: libc: Add cx_spinlock_t type X-Git-Url: https://git.corax.cc/?a=commitdiff_plain;h=59e5e9901dc80fdcadd1818efe650495a0efb15d;p=corax libc: Add cx_spinlock_t type --- diff --git a/include/corax/spinlock.h b/include/corax/spinlock.h new file mode 100644 index 0000000..8072d1a --- /dev/null +++ b/include/corax/spinlock.h @@ -0,0 +1,65 @@ +#ifndef __CORAX_SPINLOCK_H +#define __CORAX_SPINLOCK_H + +#include + +typedef u32_t cx_spinlock_t; + +/* + * cx_spinlock_lock() - Lock a cx_spinlock, waiting indefinitely + * + * SYNOPSIS + * void cx_spinlock_lock(cx_spinlock_t *lock); + * + * DESCRIPTION + * The cx_spinlock_lock() function will indefinitely attempt to lock the cx_spinlock pointed to + * by `lock' until it succeeds, waiting in a busy loop. + * + * RETURN VALUE + * None + * + * ERRORS + * This function does not signal any errors. + */ +void cx_spinlock_lock(cx_spinlock_t*); + +/* + * cx_spinlock_trylock() - Attempt to lock a cx_spinlock + * + * SYNOPSIS + * int cx_spinlock_trylock(cx_spinlock_t *lock); + * + * DESCRIPTION + * The cx_spinlock_trylock() function will attempt once to lock the spinlock pointed to by + * `lock'. This function will not block. + * + * RETURN VALUE + * This function returns zero upon success, or a non-zero value if the lock could not be + * acquired. + * + * ERRORS + * This function does not signal any errors. + */ +int cx_spinlock_trylock(cx_spinlock_t*); + +/* + * cx_spinlock_unlock() - Unlock a cx_spinlock + * + * SYNOPSIS + * int cx_spinlock_unlock(cx_spinlock_t *lock); + * + * DESCRIPTION + * The cx_spinlock_unlock() function will unlock the cx_spinlock pointed to by `lock'. This + * function will unlock any cx_spinlock regardless of spinlock ownership, and the spinlock will + * always be unlocked when this function returns. + * + * RETURN VALUE + * This function returns zero if the lock was not locked, or a non-zero value if the lock had + * been locked. Either way, it is in an unlocked state when the call returns. + * + * ERRORS + * This function does not signal any errors. + */ +int cx_spinlock_unlock(cx_spinlock_t*); + +#endif /* __CORAX_SPINLOCK_H */ diff --git a/libc/Makefile b/libc/Makefile index 074199a..6a80c91 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -1,5 +1,5 @@ OUTPUT = libc.a -OBJECTS = syscall.o string.o signal.o start.o stdio.o string_ia32.o unistd.o +OBJECTS = syscall.o string.o signal.o start.o stdio.o string_ia32.o unistd.o spinlock.o PHONY = clean INCLUDES = -I../include -I.. CFLAGS = -m32 -Wall -nostdlib -nodefaultlibs -nostartfiles -ffreestanding $(INCLUDES) diff --git a/libc/spinlock.S b/libc/spinlock.S new file mode 100644 index 0000000..66ec7e0 --- /dev/null +++ b/libc/spinlock.S @@ -0,0 +1,58 @@ + .section .text + + .global cx_spinlock_lock + .global cx_spinlock_trylock + .global cx_spinlock_unlock + +#ifdef __i386__ + +cx_spinlock_lock: + movl 4(%esp), %edx +0: xorl %eax, %eax + movl $1, %ecx + lock + cmpxchgl %ecx, (%edx) + jnz 0b /* lock failed */ + ret /* lock succeeded */ + +cx_spinlock_trylock: + movl 4(%esp), %edx + xorl %eax, %eax + movl $1, %ecx + lock + cmpxchgl %ecx, (%edx) + ret + +cx_spinlock_unlock: + movl 4(%esp), %edx + xorl %eax, %eax + lock + xchgl %eax, (%edx) + ret + +#endif /* __i386__ */ + +#ifdef __amd64__ + +cx_spinlock_lock: + xorq %rax, %rax + movl $1, %ecx + lock + cmpxchgl %ecx, (%rdi) + jnz cx_spinlock_lock + ret + +cx_spinlock_trylock: + xorl %rax, %rax + movl $1, %ecx + lock + cmpxchgl %ecx, (%rdi) + ret + +cx_spinlock_unlock: + xorq %rax, %rax + lock + xchgl %eax, (%rdi) + ret + +#endif /* __amd64__ */