Changeset 3b3e776 in mainline for uspace/lib/libc
- Timestamp:
- 2010-02-05T10:57:50Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0358da0
- Parents:
- 3f085132 (diff), b4cbef1 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/lib/libc
- Files:
-
- 40 added
- 2 deleted
- 70 edited
- 3 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/Makefile
r3f085132 r3b3e776 1 1 # 2 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 27 28 # 28 29 29 include Makefile.common 30 -include ../../../Makefile.config 30 31 31 .PHONY: all clean 32 USPACE_PREFIX = $(shell pwd)/../.. 33 #LIBS = $(LIBC_PREFIX)/libc.a 34 LIBS = 32 35 33 all: ../../../Makefile.config ../../../config.h ../../../config.defs 34 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 35 $(MAKE) -f Makefile.build 36 LINK = arch/$(UARCH)/_link.ld 36 37 37 clean: 38 rm -f $(DEPEND) $(DEPEND_PREV) $(INCLUDE_KERNEL) $(INCLUDE_ARCH) $(INCLUDE_LIBARCH) $(LIBC) arch/*/_link.ld 39 find generic/ arch/*/ -name '*.o' -follow -exec rm \{\} \; 38 PRE_DEPEND = $(INCLUDE_KERNEL) $(INCLUDE_ARCH) $(INCLUDE_LIBARCH) 39 EXTRA_CLEAN = $(INCLUDE_KERNEL) $(INCLUDE_ARCH) $(INCLUDE_LIBARCH) 40 EXTRA_OUTPUT = $(LINK) 41 42 INCLUDE_KERNEL = include/kernel 43 INCLUDE_ARCH = include/arch 44 INCLUDE_LIBARCH = include/libarch 45 46 OUTPUT = libc.a 47 48 GENERIC_SOURCES = \ 49 generic/libc.c \ 50 generic/ddi.c \ 51 generic/as.c \ 52 generic/cap.c \ 53 generic/clipboard.c \ 54 generic/devmap.c \ 55 generic/event.c \ 56 generic/errno.c \ 57 generic/mem.c \ 58 generic/string.c \ 59 generic/fibril.c \ 60 generic/fibril_synch.c \ 61 generic/pcb.c \ 62 generic/smc.c \ 63 generic/thread.c \ 64 generic/tls.c \ 65 generic/task.c \ 66 generic/futex.c \ 67 generic/io/asprintf.c \ 68 generic/io/io.c \ 69 generic/io/printf.c \ 70 generic/io/klog.c \ 71 generic/io/snprintf.c \ 72 generic/io/vprintf.c \ 73 generic/io/vsnprintf.c \ 74 generic/io/printf_core.c \ 75 generic/io/console.c \ 76 generic/malloc.c \ 77 generic/sysinfo.c \ 78 generic/ipc.c \ 79 generic/async.c \ 80 generic/loader.c \ 81 generic/getopt.c \ 82 generic/adt/list.o \ 83 generic/adt/hash_table.o \ 84 generic/time.c \ 85 generic/err.c \ 86 generic/stdlib.c \ 87 generic/mman.c \ 88 generic/udebug.c \ 89 generic/vfs/vfs.c \ 90 generic/vfs/canonify.c \ 91 generic/stacktrace.c 92 93 ARCH_SOURCES = \ 94 arch/$(UARCH)/src/entry.s \ 95 arch/$(UARCH)/src/thread_entry.s 96 97 SOURCES = \ 98 $(GENERIC_SOURCES) \ 99 $(ARCH_SOURCES) 100 101 include ../Makefile.common 102 103 $(INCLUDE_ARCH): $(INCLUDE_KERNEL) $(INCLUDE_KERNEL)/arch 104 ln -sfn kernel/arch $@ 105 106 $(INCLUDE_LIBARCH): arch/$(UARCH)/include 107 ln -sfn ../$< $@ 108 109 $(INCLUDE_KERNEL)/arch: ../../../kernel/generic/include/arch $(INCLUDE_KERNEL) 110 111 $(INCLUDE_KERNEL): ../../../kernel/generic/include/ 112 ln -sfn ../$< $@ 113 114 $(LINK): $(LINK).in 115 $(GCC) $(DEFS) $(CFLAGS) -DLIBC_PREFIX=$(LIBC_PREFIX) -E -x c $< | grep -v "^\#" > $@ -
uspace/lib/libc/Makefile.toolchain
r3f085132 r3b3e776 59 59 # 60 60 61 include $(LIBC_PREFIX)/../../../Makefile.config62 include $(LIBC_PREFIX)/../../../config.defs63 include $(LIBC_PREFIX)/arch/$(UARCH)/Makefile.inc61 -include $(LIBC_PREFIX)/../../../Makefile.config 62 -include $(LIBC_PREFIX)/../../../config.defs 63 -include $(LIBC_PREFIX)/arch/$(UARCH)/Makefile.inc 64 64 65 65 ## Simple detection of the host system … … 77 77 ## Toolchain configuration 78 78 # 79 80 JOBFILE = $(LIBC_PREFIX)/../../../tools/jobfile.py 79 81 80 82 ifeq ($(COMPILER),gcc_cross) -
uspace/lib/libc/arch/amd64/Makefile.inc
r3f085132 r3b3e776 36 36 ARCH_SOURCES += arch/$(UARCH)/src/syscall.S \ 37 37 arch/$(UARCH)/src/fibril.S \ 38 arch/$(UARCH)/src/tls.c 38 arch/$(UARCH)/src/tls.c \ 39 arch/$(UARCH)/src/stacktrace.c \ 40 arch/$(UARCH)/src/stacktrace_asm.S 39 41 42 GCC_CFLAGS += -fno-omit-frame-pointer 40 43 LFLAGS += -N 41 44 -
uspace/lib/libc/arch/amd64/include/atomic.h
r3f085132 r3b3e776 37 37 #ifndef LIBC_amd64_ATOMIC_H_ 38 38 #define LIBC_amd64_ATOMIC_H_ 39 40 #define LIBC_ARCH_ATOMIC_H_ 41 42 #include <atomicdflt.h> 39 43 40 44 static inline void atomic_inc(atomic_t *val) { -
uspace/lib/libc/arch/amd64/include/fibril.h
r3f085132 r3b3e776 44 44 #define SP_DELTA 16 45 45 46 #define context_set(c, _pc, stack, size, ptls) \ 47 do { \ 48 (c)->pc = (sysarg_t) (_pc); \ 49 (c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \ 50 (c)->tls = (sysarg_t) (ptls); \ 51 (c)->rbp = 0; \ 52 } while (0) 53 46 54 /* We include only registers that must be preserved 47 55 * during function call -
uspace/lib/libc/arch/amd64/include/types.h
r3f085132 r3b3e776 36 36 #define LIBC_amd64_TYPES_H_ 37 37 38 #define __64_BITS__ 39 38 40 typedef unsigned long long sysarg_t; 39 41 -
uspace/lib/libc/arch/amd64/src/entry.s
r3f085132 r3b3e776 38 38 # 39 39 __entry: 40 # 41 # Create the first stack frame. 42 # 43 pushq $0 44 mov %rsp, %rbp 45 40 46 # %rdi was deliberately chosen as the first argument is also in %rdi 41 47 # Pass PCB pointer to __main (no operation) -
uspace/lib/libc/arch/amd64/src/thread_entry.s
r3f085132 r3b3e776 36 36 __thread_entry: 37 37 # 38 # Create the first stack frame. 39 # 40 pushq $0 41 movq %rsp, %rbp 42 43 # 38 44 # RAX contains address of uarg 39 45 # -
uspace/lib/libc/arch/arm32/Makefile.inc
r3f085132 r3b3e776 37 37 arch/$(UARCH)/src/fibril.S \ 38 38 arch/$(UARCH)/src/tls.c \ 39 arch/$(UARCH)/src/eabi.S 39 arch/$(UARCH)/src/eabi.S \ 40 arch/$(UARCH)/src/stacktrace.c \ 41 arch/$(UARCH)/src/stacktrace_asm.S 40 42 41 GCC_CFLAGS += -ffixed-r9 -mtp=soft 43 GCC_CFLAGS += -ffixed-r9 -mtp=soft -mapcs-frame -fno-omit-frame-pointer 42 44 LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a 43 45 -
uspace/lib/libc/arch/arm32/include/atomic.h
r3f085132 r3b3e776 37 37 #define LIBC_arm32_ATOMIC_H_ 38 38 39 #define LIBC_ARCH_ATOMIC_H_ 40 #define CAS 41 42 #include <atomicdflt.h> 43 #include <bool.h> 44 #include <sys/types.h> 45 46 extern uintptr_t *ras_page; 47 48 static inline bool cas(atomic_t *val, long ov, long nv) 49 { 50 long ret = 0; 51 52 /* 53 * The following instructions between labels 1 and 2 constitute a 54 * Restartable Atomic Seqeunce. Should the sequence be non-atomic, 55 * the kernel will restart it. 56 */ 57 asm volatile ( 58 "1:\n" 59 " adr %[ret], 1b\n" 60 " str %[ret], %[rp0]\n" 61 " adr %[ret], 2f\n" 62 " str %[ret], %[rp1]\n" 63 " ldr %[ret], %[addr]\n" 64 " cmp %[ret], %[ov]\n" 65 " streq %[nv], %[addr]\n" 66 "2:\n" 67 " moveq %[ret], #1\n" 68 " movne %[ret], #0\n" 69 : [ret] "+&r" (ret), 70 [rp0] "=m" (ras_page[0]), 71 [rp1] "=m" (ras_page[1]), 72 [addr] "+m" (val->count) 73 : [ov] "r" (ov), 74 [nv] "r" (nv) 75 : "memory" 76 ); 77 78 ras_page[0] = 0; 79 asm volatile ("" ::: "memory"); 80 ras_page[1] = 0xffffffff; 81 82 return (bool) ret; 83 } 84 39 85 /** Atomic addition. 40 86 * … … 46 92 static inline long atomic_add(atomic_t *val, int i) 47 93 { 48 int ret; 49 volatile long * mem = &(val->count); 94 long ret = 0; 50 95 96 /* 97 * The following instructions between labels 1 and 2 constitute a 98 * Restartable Atomic Seqeunce. Should the sequence be non-atomic, 99 * the kernel will restart it. 100 */ 51 101 asm volatile ( 52 "1:\n" 53 "ldr r2, [%1]\n" 54 "add r3, r2, %2\n" 55 "str r3, %0\n" 56 "swp r3, r3, [%1]\n" 57 "cmp r3, r2\n" 58 "bne 1b\n" 102 "1:\n" 103 " adr %[ret], 1b\n" 104 " str %[ret], %[rp0]\n" 105 " adr %[ret], 2f\n" 106 " str %[ret], %[rp1]\n" 107 " ldr %[ret], %[addr]\n" 108 " add %[ret], %[ret], %[imm]\n" 109 " str %[ret], %[addr]\n" 110 "2:\n" 111 : [ret] "+&r" (ret), 112 [rp0] "=m" (ras_page[0]), 113 [rp1] "=m" (ras_page[1]), 114 [addr] "+m" (val->count) 115 : [imm] "r" (i) 116 ); 59 117 60 : "=m" (ret) 61 : "r" (mem), "r" (i) 62 : "r3", "r2" 63 ); 118 ras_page[0] = 0; 119 asm volatile ("" ::: "memory"); 120 ras_page[1] = 0xffffffff; 64 121 65 122 return ret; -
uspace/lib/libc/arch/arm32/include/fibril.h
r3f085132 r3b3e776 58 58 * @param ptls Pointer to the TCB. 59 59 */ 60 #define context_set(c, _pc, stack, size, ptls) \ 61 (c)->pc = (sysarg_t) (_pc); \ 62 (c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \ 63 (c)->tls = ((sysarg_t)(ptls)) + sizeof(tcb_t) + ARM_TP_OFFSET; 64 60 #define context_set(c, _pc, stack, size, ptls) \ 61 do { \ 62 (c)->pc = (sysarg_t) (_pc); \ 63 (c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \ 64 (c)->tls = ((sysarg_t)(ptls)) + sizeof(tcb_t) + ARM_TP_OFFSET; \ 65 (c)->fp = 0; \ 66 } while (0) 65 67 66 68 /** Fibril context. … … 79 81 uint32_t r7; 80 82 uint32_t r8; 81 uint32_t tls; 83 uint32_t tls; /* r9 */ 82 84 uint32_t r10; 83 uint32_t r11;85 uint32_t fp; /* r11 */ 84 86 } context_t; 85 87 -
uspace/lib/libc/arch/arm32/include/types.h
r3f085132 r3b3e776 37 37 #define LIBC_arm32_TYPES_H_ 38 38 39 #define __32_BITS__ 40 39 41 typedef unsigned int sysarg_t; 40 42 -
uspace/lib/libc/arch/arm32/src/entry.s
r3f085132 r3b3e776 36 36 # 37 37 # r1 contains the PCB pointer 38 # r2 contains the RAS page address 38 39 # 39 40 __entry: 41 # Store the RAS page address into the ras_page variable 42 ldr r0, =ras_page 43 str r2, [r0] 44 45 # 46 # Create the first stack frame. 47 # 48 mov fp, #0 49 mov ip, sp 50 push {fp, ip, lr, pc} 51 sub fp, ip, #4 52 40 53 # Pass pcb_ptr to __main as the first argument (in r0) 41 54 mov r0, r1 … … 43 56 44 57 bl __exit 58 59 .data 60 61 .global ras_page 62 ras_page: 63 .long 0 64 -
uspace/lib/libc/arch/arm32/src/syscall.c
r3f085132 r3b3e776 60 60 register sysarg_t __arm_reg_r5 asm("r5") = p6; 61 61 register sysarg_t __arm_reg_r6 asm("r6") = id; 62 63 asm volatile ( "swi" 62 63 asm volatile ( 64 "swi 0" 64 65 : "=r" (__arm_reg_r0) 65 66 : "r" (__arm_reg_r0), … … 71 72 "r" (__arm_reg_r6) 72 73 ); 73 74 74 75 return __arm_reg_r0; 75 76 } -
uspace/lib/libc/arch/arm32/src/thread_entry.s
r3f085132 r3b3e776 35 35 # 36 36 __thread_entry: 37 # 38 # Create the first stack frame. 39 # 40 mov fp, #0 41 mov ip, sp 42 push {fp, ip, lr, pc} 43 sub fp, ip, #4 44 37 45 b __thread_main -
uspace/lib/libc/arch/ia32/Makefile.inc
r3f085132 r3b3e776 37 37 arch/$(UARCH)/src/fibril.S \ 38 38 arch/$(UARCH)/src/tls.c \ 39 arch/$(UARCH)/src/setjmp.S 39 arch/$(UARCH)/src/setjmp.S \ 40 arch/$(UARCH)/src/stacktrace.c \ 41 arch/$(UARCH)/src/stacktrace_asm.S 40 42 43 GCC_CFLAGS += -march=pentium 41 44 LFLAGS += -N 42 45 -
uspace/lib/libc/arch/ia32/include/atomic.h
r3f085132 r3b3e776 35 35 #ifndef LIBC_ia32_ATOMIC_H_ 36 36 #define LIBC_ia32_ATOMIC_H_ 37 38 #define LIBC_ARCH_ATOMIC_H_ 39 40 #include <atomicdflt.h> 37 41 38 42 static inline void atomic_inc(atomic_t *val) { -
uspace/lib/libc/arch/ia32/include/fibril.h
r3f085132 r3b3e776 44 44 #define SP_DELTA (12) 45 45 46 #define context_set(c, _pc, stack, size, ptls) \ 47 do { \ 48 (c)->pc = (sysarg_t) (_pc); \ 49 (c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \ 50 (c)->tls = (sysarg_t) (ptls); \ 51 (c)->ebp = 0; \ 52 } while (0) 53 46 54 /* We include only registers that must be preserved 47 55 * during function call -
uspace/lib/libc/arch/ia32/include/types.h
r3f085132 r3b3e776 36 36 #define LIBC_ia32_TYPES_H_ 37 37 38 #define __32_BITS__ 39 38 40 typedef unsigned int sysarg_t; 39 41 -
uspace/lib/libc/arch/ia32/src/entry.s
r3f085132 r3b3e776 55 55 movl $__syscall_fast, (%eax) 56 56 0: 57 # 58 # Create the first stack frame. 59 # 60 pushl $0 61 movl %esp, %ebp 57 62 58 63 # Pass the PCB pointer to __main as the first argument -
uspace/lib/libc/arch/ia32/src/thread_entry.s
r3f085132 r3b3e776 42 42 43 43 # 44 # Create the first stack frame. 45 # 46 pushl $0 47 mov %esp, %ebp 48 49 # 44 50 # EAX contains address of uarg. 45 51 # -
uspace/lib/libc/arch/ia64/Makefile.inc
r3f085132 r3b3e776 36 36 arch/$(UARCH)/src/fibril.S \ 37 37 arch/$(UARCH)/src/tls.c \ 38 arch/$(UARCH)/src/ddi.c 38 arch/$(UARCH)/src/ddi.c \ 39 arch/$(UARCH)/src/stacktrace.c \ 40 arch/$(UARCH)/src/stacktrace_asm.S 39 41 40 42 GCC_CFLAGS += -fno-unwind-tables -
uspace/lib/libc/arch/ia64/include/atomic.h
r3f085132 r3b3e776 35 35 #ifndef LIBC_ia64_ATOMIC_H_ 36 36 #define LIBC_ia64_ATOMIC_H_ 37 38 #define LIBC_ARCH_ATOMIC_H_ 39 40 #include <atomicdflt.h> 37 41 38 42 static inline void atomic_inc(atomic_t *val) -
uspace/lib/libc/arch/ia64/include/types.h
r3f085132 r3b3e776 36 36 #define LIBC_ia64_TYPES_H_ 37 37 38 #define __64_BITS__ 39 38 40 typedef unsigned long long sysarg_t; 39 41 -
uspace/lib/libc/arch/mips32/Makefile.inc
r3f085132 r3b3e776 35 35 ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \ 36 36 arch/$(UARCH)/src/fibril.S \ 37 arch/$(UARCH)/src/tls.c 37 arch/$(UARCH)/src/tls.c \ 38 arch/$(UARCH)/src/stacktrace.c \ 39 arch/$(UARCH)/src/stacktrace_asm.S 38 40 39 41 GCC_CFLAGS += -mips3 -
uspace/lib/libc/arch/mips32/include/atomic.h
r3f085132 r3b3e776 36 36 #ifndef LIBC_mips32_ATOMIC_H_ 37 37 #define LIBC_mips32_ATOMIC_H_ 38 39 #define LIBC_ARCH_ATOMIC_H_ 40 41 #include <atomicdflt.h> 38 42 39 43 #define atomic_inc(x) ((void) atomic_add(x, 1)) -
uspace/lib/libc/arch/mips32/include/types.h
r3f085132 r3b3e776 37 37 #define LIBC_mips32_TYPES_H_ 38 38 39 #define __32_BITS__ 40 39 41 typedef unsigned int sysarg_t; 40 42 -
uspace/lib/libc/arch/mips32eb/Makefile.inc
r3f085132 r3b3e776 35 35 ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \ 36 36 arch/$(UARCH)/src/fibril.S \ 37 arch/$(UARCH)/src/tls.c 37 arch/$(UARCH)/src/tls.c \ 38 arch/$(UARCH)/src/stacktrace.c \ 39 arch/$(UARCH)/src/stacktrace_asm.S 38 40 39 41 GCC_CFLAGS += -mips3 -
uspace/lib/libc/arch/ppc32/Makefile.inc
r3f085132 r3b3e776 35 35 ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \ 36 36 arch/$(UARCH)/src/fibril.S \ 37 arch/$(UARCH)/src/tls.c 37 arch/$(UARCH)/src/tls.c \ 38 arch/$(UARCH)/src/stacktrace.c \ 39 arch/$(UARCH)/src/stacktrace_asm.S 38 40 39 41 GCC_CFLAGS += -mcpu=powerpc -msoft-float -m32 -
uspace/lib/libc/arch/ppc32/include/atomic.h
r3f085132 r3b3e776 35 35 #ifndef LIBC_ppc32_ATOMIC_H_ 36 36 #define LIBC_ppc32_ATOMIC_H_ 37 38 #define LIBC_ARCH_ATOMIC_H_ 39 40 #include <atomicdflt.h> 37 41 38 42 static inline void atomic_inc(atomic_t *val) -
uspace/lib/libc/arch/ppc32/include/types.h
r3f085132 r3b3e776 36 36 #define LIBC_ppc32_TYPES_H_ 37 37 38 #define __32_BITS__ 39 38 40 typedef unsigned int sysarg_t; 39 41 -
uspace/lib/libc/arch/ppc32/src/entry.s
r3f085132 r3b3e776 38 38 # 39 39 __entry: 40 # 41 # Create the first stack frame. 42 # 43 li %r3, 0 44 stw %r3, 0(%r1) 45 stwu %r1, -16(%r1) 46 40 47 # Pass the PCB pointer to __main() as the first argument. 41 48 # The first argument is passed in r3. -
uspace/lib/libc/arch/ppc32/src/thread_entry.s
r3f085132 r3b3e776 35 35 # 36 36 __thread_entry: 37 # 38 # Create the first stack frame. 39 # 40 li %r4, 0 41 stw %r4, 0(%r1) 42 stwu %r1, -16(%r1) 43 37 44 b __thread_main 38 45 -
uspace/lib/libc/arch/sparc64/Makefile.inc
r3f085132 r3b3e776 34 34 35 35 ARCH_SOURCES += arch/$(UARCH)/src/fibril.S \ 36 arch/$(UARCH)/src/tls.c 36 arch/$(UARCH)/src/tls.c \ 37 arch/$(UARCH)/src/stacktrace.c \ 38 arch/$(UARCH)/src/stacktrace_asm.S 37 39 38 40 GCC_CFLAGS += -mcpu=ultrasparc -m64 -
uspace/lib/libc/arch/sparc64/include/atomic.h
r3f085132 r3b3e776 36 36 #define LIBC_sparc64_ATOMIC_H_ 37 37 38 #define LIBC_ARCH_ATOMIC_H_ 39 40 #include <atomicdflt.h> 38 41 #include <sys/types.h> 39 42 -
uspace/lib/libc/arch/sparc64/include/fibril.h
r3f085132 r3b3e776 46 46 #endif 47 47 48 #define context_set(c, _pc, stack, size, ptls) \ 49 (c)->pc = ((uintptr_t) _pc) - 8; \ 50 (c)->sp = ((uintptr_t) stack) + ALIGN_UP((size), \ 51 STACK_ALIGNMENT) - (STACK_BIAS + SP_DELTA); \ 52 (c)->fp = -STACK_BIAS; \ 53 (c)->tp = ptls 48 #define context_set(c, _pc, stack, size, ptls) \ 49 do { \ 50 (c)->pc = ((uintptr_t) _pc) - 8; \ 51 (c)->sp = ((uintptr_t) stack) + ALIGN_UP((size), \ 52 STACK_ALIGNMENT) - (STACK_BIAS + SP_DELTA); \ 53 (c)->fp = -STACK_BIAS; \ 54 (c)->tp = ptls; \ 55 } while (0) 54 56 55 57 /* -
uspace/lib/libc/arch/sparc64/include/types.h
r3f085132 r3b3e776 36 36 #define LIBC_sparc64_TYPES_H_ 37 37 38 #define __64_BITS__ 39 38 40 typedef unsigned long sysarg_t; 39 41 -
uspace/lib/libc/arch/sparc64/src/entry.s
r3f085132 r3b3e776 39 39 # 40 40 __entry: 41 # 42 # Create the first stack frame. 43 # 44 save %sp, -176, %sp 45 flushw 46 add %g0, -0x7ff, %fp 47 41 48 # Pass pcb_ptr as the first argument to __main() 42 mov % o1, %o049 mov %i1, %o0 43 50 sethi %hi(_gp), %l7 44 51 call __main -
uspace/lib/libc/arch/sparc64/src/fibril.S
r3f085132 r3b3e776 35 35 36 36 context_save: 37 # 38 # We rely on the kernel to flush our active register windows to memory 39 # should a thread switch occur. 40 # 37 41 CONTEXT_SAVE_ARCH_CORE %o0 38 42 retl … … 42 46 # 43 47 # Flush all active windows. 44 # This is essential, because CONTEXT_LOAD overwrites 45 # %sp of CWP - 1 with the value written to %fp of CWP. 46 # Flushing all active windows mitigates this problem 47 # as CWP - 1 becomes the overlap window. 48 # 48 # This is essential, because CONTEXT_RESTORE_ARCH_CORE overwrites %sp of 49 # CWP - 1 with the value written to %fp of CWP. Flushing all active 50 # windows mitigates this problem as CWP - 1 becomes the overlap window. 51 # 49 52 flushw 50 53 -
uspace/lib/libc/arch/sparc64/src/stacktrace_asm.S
r3f085132 r3b3e776 1 1 # 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 2 # Copyright (c) 2009 Jakub Jermar 4 3 # All rights reserved. 5 4 # … … 28 27 # 29 28 30 include Makefile.common 29 #include <libarch/stack.h> 31 30 32 . PHONY: all clean31 .text 33 32 34 all: $(LIBC_PREFIX)/../../../version $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS) 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 33 .global stacktrace_prepare 34 .global stacktrace_fp_get 35 .global stacktrace_pc_get 37 36 38 clean: 39 rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm 40 find . -name '*.o' -follow -exec rm \{\} \; 37 stacktrace_prepare: 38 save %sp, -(STACK_WINDOW_SAVE_AREA_SIZE+STACK_ARG_SAVE_AREA_SIZE), %sp 39 # Flush all other windows to memory so that we can read their contents. 40 flushw 41 ret 42 restore 43 44 stacktrace_fp_get: 45 # Add the stack bias to %sp to get the actual address. 46 retl 47 add %sp, STACK_BIAS, %o0 48 49 stacktrace_pc_get: 50 retl 51 mov %o7, %o0 -
uspace/lib/libc/arch/sparc64/src/thread_entry.s
r3f085132 r3b3e776 35 35 # 36 36 __thread_entry: 37 # 38 # Create the first stack frame. 39 # 40 save %sp, -176, %sp 41 flushw 42 add %g0, -0x7ff, %fp 43 37 44 sethi %hi(_gp), %l7 38 45 call __thread_main ! %o0 contains address of uarg -
uspace/lib/libc/generic/adt/hash_table.c
r3f085132 r3b3e776 193 193 } 194 194 195 /** Apply fucntion to all items in hash table. 196 * 197 * @param h Hash table. 198 * @param f Function to be applied. 199 * @param arg Argument to be passed to the function. 200 */ 201 void 202 hash_table_apply(hash_table_t *h, void (*f)(link_t *, void *), void *arg) 203 { 204 hash_index_t bucket; 205 link_t *cur; 206 207 for (bucket = 0; bucket < h->entries; bucket++) { 208 for (cur = h->entry[bucket].next; cur != &h->entry[bucket]; 209 cur = cur->next) { 210 f(cur, arg); 211 } 212 } 213 } 214 195 215 /** @} 196 216 */ -
uspace/lib/libc/generic/async.c
r3f085132 r3b3e776 392 392 /* If nothing in queue, wait until something arrives */ 393 393 while (list_empty(&conn->msg_queue)) { 394 if (conn->close_callid) { 395 /* 396 * Handle the case when the connection was already 397 * closed by the client but the server did not notice 398 * the first IPC_M_PHONE_HUNGUP call and continues to 399 * call async_get_call_timeout(). Repeat 400 * IPC_M_PHONE_HUNGUP until the caller notices. 401 */ 402 memset(call, 0, sizeof(ipc_call_t)); 403 IPC_SET_METHOD(*call, IPC_M_PHONE_HUNGUP); 404 futex_up(&async_futex); 405 return conn->close_callid; 406 } 407 394 408 if (usecs) 395 409 async_insert_timeout(&conn->wdata); … … 528 542 list_initialize(&conn->msg_queue); 529 543 conn->callid = callid; 530 conn->close_callid = false;544 conn->close_callid = 0; 531 545 532 546 if (call) … … 1273 1287 } 1274 1288 1289 /** Wrapper for forwarding any read request 1290 * 1291 * 1292 */ 1293 int async_data_read_forward_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, 1294 ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr) 1295 { 1296 ipc_callid_t callid; 1297 if (!async_data_read_receive(&callid, NULL)) { 1298 ipc_answer_0(callid, EINVAL); 1299 return EINVAL; 1300 } 1301 1302 aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4, 1303 dataptr); 1304 if (msg == 0) { 1305 ipc_answer_0(callid, EINVAL); 1306 return EINVAL; 1307 } 1308 1309 int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0, 1310 IPC_FF_ROUTE_FROM_ME); 1311 if (retval != EOK) { 1312 ipc_answer_0(callid, retval); 1313 return retval; 1314 } 1315 1316 ipcarg_t rc; 1317 async_wait_for(msg, &rc); 1318 1319 return (int) rc; 1320 } 1321 1275 1322 /** Wrapper for making IPC_M_DATA_WRITE calls using the async framework. 1276 1323 * 1277 * @param phoneid Phone that will be used to contact the receiving side. 1278 * @param src Address of the beginning of the source buffer. 1279 * @param size Size of the source buffer. 1280 * 1281 * @return Zero on success or a negative error code from errno.h. 1324 * @param phoneid Phone that will be used to contact the receiving side. 1325 * @param src Address of the beginning of the source buffer. 1326 * @param size Size of the source buffer. 1327 * 1328 * @return Zero on success or a negative error code from errno.h. 1329 * 1282 1330 */ 1283 1331 int async_data_write_start(int phoneid, const void *src, size_t size) … … 1294 1342 * So far, this wrapper is to be used from within a connection fibril. 1295 1343 * 1296 * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will 1297 * be stored. 1298 * @param size Storage where the suggested size will be stored. May be 1299 * NULL 1300 * 1301 * @return Non-zero on success, zero on failure. 1344 * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will 1345 * be stored. 1346 * @param size Storage where the suggested size will be stored. May be 1347 * NULL 1348 * 1349 * @return Non-zero on success, zero on failure. 1350 * 1302 1351 */ 1303 1352 int async_data_write_receive(ipc_callid_t *callid, size_t *size) … … 1306 1355 1307 1356 assert(callid); 1308 1357 1309 1358 *callid = async_get_call(&data); 1310 1359 if (IPC_GET_METHOD(data) != IPC_M_DATA_WRITE) 1311 1360 return 0; 1361 1312 1362 if (size) 1313 1363 *size = (size_t) IPC_GET_ARG2(data); 1364 1314 1365 return 1; 1315 1366 } … … 1320 1371 * so that the user doesn't have to remember the meaning of each IPC argument. 1321 1372 * 1322 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 1323 * @param dst Final destination address for the IPC_M_DATA_WRITE call. 1324 * @param size Final size for the IPC_M_DATA_WRITE call. 1325 * 1326 * @return Zero on success or a value from @ref errno.h on failure. 1373 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 1374 * @param dst Final destination address for the IPC_M_DATA_WRITE call. 1375 * @param size Final size for the IPC_M_DATA_WRITE call. 1376 * 1377 * @return Zero on success or a value from @ref errno.h on failure. 1378 * 1327 1379 */ 1328 1380 int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size) … … 1331 1383 } 1332 1384 1385 /** Wrapper for receiving binary data 1386 * 1387 * This wrapper only makes it more comfortable to use async_data_write_* 1388 * functions to receive binary data. 1389 * 1390 * @param data Pointer to data pointer (which should be later disposed 1391 * by free()). If the operation fails, the pointer is not 1392 * touched. 1393 * @param min_size Minimum size (in bytes) of the data to receive. 1394 * @param max_size Maximum size (in bytes) of the data to receive. 0 means 1395 * no limit. 1396 * @param granulariy If non-zero, then the size of the received data has to 1397 * be divisible by this value. 1398 * @param received If not NULL, the size of the received data is stored here. 1399 * 1400 * @return Zero on success or a value from @ref errno.h on failure. 1401 * 1402 */ 1403 int async_data_receive(void **data, const size_t min_size, 1404 const size_t max_size, const size_t granularity, size_t *received) 1405 { 1406 ipc_callid_t callid; 1407 size_t size; 1408 if (!async_data_write_receive(&callid, &size)) { 1409 ipc_answer_0(callid, EINVAL); 1410 return EINVAL; 1411 } 1412 1413 if (size < min_size) { 1414 ipc_answer_0(callid, EINVAL); 1415 return EINVAL; 1416 } 1417 1418 if ((max_size > 0) && (size > max_size)) { 1419 ipc_answer_0(callid, EINVAL); 1420 return EINVAL; 1421 } 1422 1423 if ((granularity > 0) && ((size % granularity) != 0)) { 1424 ipc_answer_0(callid, EINVAL); 1425 return EINVAL; 1426 } 1427 1428 void *_data = malloc(size); 1429 if (_data == NULL) { 1430 ipc_answer_0(callid, ENOMEM); 1431 return ENOMEM; 1432 } 1433 1434 int rc = async_data_write_finalize(callid, _data, size); 1435 if (rc != EOK) { 1436 free(_data); 1437 return rc; 1438 } 1439 1440 *data = _data; 1441 if (received != NULL) 1442 *received = size; 1443 1444 return EOK; 1445 } 1446 1447 /** Wrapper for receiving strings 1448 * 1449 * This wrapper only makes it more comfortable to use async_data_write_* 1450 * functions to receive strings. 1451 * 1452 * @param str Pointer to string pointer (which should be later disposed 1453 * by free()). If the operation fails, the pointer is not 1454 * touched. 1455 * @param max_size Maximum size (in bytes) of the string to receive. 0 means 1456 * no limit. 1457 * @param received If not NULL, the size of the received data is stored here. 1458 * 1459 * @return Zero on success or a value from @ref errno.h on failure. 1460 * 1461 */ 1462 int async_string_receive(char **str, const size_t max_size, size_t *received) 1463 { 1464 ipc_callid_t callid; 1465 size_t size; 1466 if (!async_data_write_receive(&callid, &size)) { 1467 ipc_answer_0(callid, EINVAL); 1468 return EINVAL; 1469 } 1470 1471 if ((max_size > 0) && (size > max_size)) { 1472 ipc_answer_0(callid, EINVAL); 1473 return EINVAL; 1474 } 1475 1476 char *data = (char *) malloc(size + 1); 1477 if (data == NULL) { 1478 ipc_answer_0(callid, ENOMEM); 1479 return ENOMEM; 1480 } 1481 1482 int rc = async_data_write_finalize(callid, data, size); 1483 if (rc != EOK) { 1484 free(data); 1485 return rc; 1486 } 1487 1488 data[size] = 0; 1489 *str = data; 1490 if (received != NULL) 1491 *received = size; 1492 1493 return EOK; 1494 } 1495 1496 /** Wrapper for voiding any data that is about to be received 1497 * 1498 * This wrapper can be used to void any pending data 1499 * 1500 * @param retval Error value from @ref errno.h to be returned to the caller. 1501 * 1502 */ 1503 void async_data_void(const int retval) 1504 { 1505 ipc_callid_t callid; 1506 async_data_write_receive(&callid, NULL); 1507 ipc_answer_0(callid, retval); 1508 } 1509 1510 /** Wrapper for forwarding any data that is about to be received 1511 * 1512 * 1513 */ 1514 int async_data_forward_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, 1515 ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr) 1516 { 1517 ipc_callid_t callid; 1518 if (!async_data_write_receive(&callid, NULL)) { 1519 ipc_answer_0(callid, EINVAL); 1520 return EINVAL; 1521 } 1522 1523 aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4, 1524 dataptr); 1525 if (msg == 0) { 1526 ipc_answer_0(callid, EINVAL); 1527 return EINVAL; 1528 } 1529 1530 int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0, 1531 IPC_FF_ROUTE_FROM_ME); 1532 if (retval != EOK) { 1533 ipc_answer_0(callid, retval); 1534 return retval; 1535 } 1536 1537 ipcarg_t rc; 1538 async_wait_for(msg, &rc); 1539 1540 return (int) rc; 1541 } 1542 1333 1543 /** @} 1334 1544 */ -
uspace/lib/libc/generic/devmap.c
r3f085132 r3b3e776 35 35 #include <async.h> 36 36 #include <errno.h> 37 #include <malloc.h> 38 #include <bool.h> 37 39 38 40 static int devmap_phone_driver = -1; … … 105 107 aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer); 106 108 107 ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1); 108 109 ipcarg_t retval = async_data_write_start(phone, name, str_size(name)); 109 110 if (retval != EOK) { 110 111 async_wait_for(req, NULL); … … 126 127 /** Register new device. 127 128 * 128 * @param name Device name. 129 * @param handle Output: Handle to the created instance of device. 129 * @param namespace Namespace name. 130 * @param fqdn Fully qualified device name. 131 * @param handle Output: Handle to the created instance of device. 130 132 * 131 133 */ 132 int devmap_device_register(const char * name, dev_handle_t *handle)134 int devmap_device_register(const char *fqdn, dev_handle_t *handle) 133 135 { 134 136 int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING); … … 143 145 &answer); 144 146 145 ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1); 146 147 ipcarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn)); 147 148 if (retval != EOK) { 148 149 async_wait_for(req, NULL); … … 167 168 } 168 169 169 int devmap_device_get_handle(const char * name, dev_handle_t *handle, unsigned int flags)170 int devmap_device_get_handle(const char *fqdn, dev_handle_t *handle, unsigned int flags) 170 171 { 171 172 int phone = devmap_get_phone(DEVMAP_CLIENT, flags); … … 180 181 &answer); 181 182 182 ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1); 183 183 ipcarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn)); 184 184 if (retval != EOK) { 185 185 async_wait_for(req, NULL); … … 202 202 203 203 return retval; 204 } 205 206 int devmap_namespace_get_handle(const char *name, dev_handle_t *handle, unsigned int flags) 207 { 208 int phone = devmap_get_phone(DEVMAP_CLIENT, flags); 209 210 if (phone < 0) 211 return phone; 212 213 async_serialize_start(); 214 215 ipc_call_t answer; 216 aid_t req = async_send_2(phone, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0, 217 &answer); 218 219 ipcarg_t retval = async_data_write_start(phone, name, str_size(name)); 220 if (retval != EOK) { 221 async_wait_for(req, NULL); 222 async_serialize_end(); 223 return retval; 224 } 225 226 async_wait_for(req, &retval); 227 228 async_serialize_end(); 229 230 if (retval != EOK) { 231 if (handle != NULL) 232 *handle = (dev_handle_t) -1; 233 return retval; 234 } 235 236 if (handle != NULL) 237 *handle = (dev_handle_t) IPC_GET_ARG1(answer); 238 239 return retval; 240 } 241 242 devmap_handle_type_t devmap_handle_probe(dev_handle_t handle) 243 { 244 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 245 246 if (phone < 0) 247 return phone; 248 249 ipcarg_t type; 250 int retval = async_req_1_1(phone, DEVMAP_HANDLE_PROBE, handle, &type); 251 if (retval != EOK) 252 return DEV_HANDLE_NONE; 253 254 return (devmap_handle_type_t) type; 204 255 } 205 256 … … 227 278 228 279 ipcarg_t null_id; 229 int retval = async_req_0_1(phone, DEVMAP_ DEVICE_NULL_CREATE, &null_id);280 int retval = async_req_0_1(phone, DEVMAP_NULL_CREATE, &null_id); 230 281 if (retval != EOK) 231 282 return -1; … … 241 292 return; 242 293 243 async_req_1_0(phone, DEVMAP_DEVICE_NULL_DESTROY, (ipcarg_t) null_id); 244 } 245 246 ipcarg_t devmap_device_get_count(void) 247 { 248 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 249 250 if (phone < 0) 251 return 0; 252 294 async_req_1_0(phone, DEVMAP_NULL_DESTROY, (ipcarg_t) null_id); 295 } 296 297 static size_t devmap_count_namespaces_internal(int phone) 298 { 253 299 ipcarg_t count; 254 int retval = async_req_0_1(phone, DEVMAP_ DEVICE_GET_COUNT, &count);300 int retval = async_req_0_1(phone, DEVMAP_GET_NAMESPACE_COUNT, &count); 255 301 if (retval != EOK) 256 302 return 0; … … 259 305 } 260 306 261 ipcarg_t devmap_device_get_devices(ipcarg_t count, dev_desc_t *data) 262 { 263 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 264 265 if (phone < 0) 266 return 0; 267 268 async_serialize_start(); 269 270 ipc_call_t answer; 271 aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer); 272 273 ipcarg_t retval = async_data_read_start(phone, data, count * sizeof(dev_desc_t)); 274 275 if (retval != EOK) { 276 async_wait_for(req, NULL); 277 async_serialize_end(); 278 return 0; 279 } 280 281 async_wait_for(req, &retval); 282 283 async_serialize_end(); 284 307 static size_t devmap_count_devices_internal(int phone, dev_handle_t ns_handle) 308 { 309 ipcarg_t count; 310 int retval = async_req_1_1(phone, DEVMAP_GET_DEVICE_COUNT, ns_handle, &count); 285 311 if (retval != EOK) 286 312 return 0; 287 313 288 return IPC_GET_ARG1(answer); 289 } 314 return count; 315 } 316 317 size_t devmap_count_namespaces(void) 318 { 319 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 320 321 if (phone < 0) 322 return 0; 323 324 return devmap_count_namespaces_internal(phone); 325 } 326 327 size_t devmap_count_devices(dev_handle_t ns_handle) 328 { 329 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 330 331 if (phone < 0) 332 return 0; 333 334 return devmap_count_devices_internal(phone, ns_handle); 335 } 336 337 size_t devmap_get_namespaces(dev_desc_t **data) 338 { 339 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 340 341 if (phone < 0) 342 return 0; 343 344 /* Loop until namespaces read succesful */ 345 while (true) { 346 size_t count = devmap_count_namespaces_internal(phone); 347 if (count == 0) 348 return 0; 349 350 dev_desc_t *devs = (dev_desc_t *) calloc(count, sizeof(dev_desc_t)); 351 if (devs == NULL) 352 return 0; 353 354 async_serialize_start(); 355 356 ipc_call_t answer; 357 aid_t req = async_send_0(phone, DEVMAP_GET_NAMESPACES, &answer); 358 359 int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t)); 360 if (rc == EOVERFLOW) { 361 /* 362 * Number of namespaces has changed since 363 * the last call of DEVMAP_DEVICE_GET_NAMESPACE_COUNT 364 */ 365 async_serialize_end(); 366 free(devs); 367 continue; 368 } 369 370 if (rc != EOK) { 371 async_wait_for(req, NULL); 372 async_serialize_end(); 373 free(devs); 374 return 0; 375 } 376 377 ipcarg_t retval; 378 async_wait_for(req, &retval); 379 async_serialize_end(); 380 381 if (retval != EOK) 382 return 0; 383 384 *data = devs; 385 return count; 386 } 387 } 388 389 size_t devmap_get_devices(dev_handle_t ns_handle, dev_desc_t **data) 390 { 391 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 392 393 if (phone < 0) 394 return 0; 395 396 /* Loop until namespaces read succesful */ 397 while (true) { 398 size_t count = devmap_count_devices_internal(phone, ns_handle); 399 if (count == 0) 400 return 0; 401 402 dev_desc_t *devs = (dev_desc_t *) calloc(count, sizeof(dev_desc_t)); 403 if (devs == NULL) 404 return 0; 405 406 async_serialize_start(); 407 408 ipc_call_t answer; 409 aid_t req = async_send_1(phone, DEVMAP_GET_DEVICES, ns_handle, &answer); 410 411 int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t)); 412 if (rc == EOVERFLOW) { 413 /* 414 * Number of devices has changed since 415 * the last call of DEVMAP_DEVICE_GET_DEVICE_COUNT 416 */ 417 async_serialize_end(); 418 free(devs); 419 continue; 420 } 421 422 if (rc != EOK) { 423 async_wait_for(req, NULL); 424 async_serialize_end(); 425 free(devs); 426 return 0; 427 } 428 429 ipcarg_t retval; 430 async_wait_for(req, &retval); 431 async_serialize_end(); 432 433 if (retval != EOK) 434 return 0; 435 436 *data = devs; 437 return count; 438 } 439 } -
uspace/lib/libc/generic/fibril_synch.c
r3f085132 r3b3e776 33 33 */ 34 34 35 #include <fibril_sync .h>35 #include <fibril_synch.h> 36 36 #include <fibril.h> 37 37 #include <async.h> -
uspace/lib/libc/generic/futex.c
r3f085132 r3b3e776 36 36 #include <atomic.h> 37 37 #include <libc.h> 38 #include <stdio.h>39 38 #include <sys/types.h> 40 #include <kernel/synch/synch.h>41 42 /*43 * Note about race conditions.44 * Because of non-atomic nature of operations performed sequentially on the45 * futex counter and the futex wait queue, there is a race condition:46 *47 * (wq->missed_wakeups == 1) && (futex->count = 1)48 *49 * Scenario 1 (wait queue timeout vs. futex_up()):50 * 1. assume wq->missed_wakeups == 0 && futex->count == -151 * (ie. thread A sleeping, thread B in the critical section)52 * 2. A receives timeout and gets removed from the wait queue53 * 3. B wants to leave the critical section and calls futex_up()54 * 4. B thus changes futex->count from -1 to 055 * 5. B has to call SYS_FUTEX_WAKEUP syscall to wake up the sleeping thread56 * 6. B finds the wait queue empty and changes wq->missed_wakeups from 0 to 157 * 7. A fixes futex->count (i.e. the number of waiting threads) by changing it58 * from 0 to 159 *60 * Scenario 2 (conditional down operation vs. futex_up)61 * 1. assume wq->missed_wakeups == 0 && futex->count == 062 * (i.e. thread A is in the critical section)63 * 2. thread B performs futex_trydown() operation and changes futex->count from64 * 0 to -165 * B is now obliged to call SYS_FUTEX_SLEEP syscall66 * 3. A wants to leave the critical section and does futex_up()67 * 4. A thus changes futex->count from -1 to 0 and must call SYS_FUTEX_WAKEUP68 * syscall69 * 5. B finds the wait queue empty and immediatelly aborts the conditional sleep70 * 6. No thread is queueing in the wait queue so wq->missed_wakeups changes from71 * 0 to 172 * 6. B fixes futex->count (i.e. the number of waiting threads) by changing it73 * from 0 to 174 *75 * Both scenarios allow two threads to be in the critical section76 * simultaneously. One without kernel intervention and the other through77 * wq->missed_wakeups being 1.78 *79 * To mitigate this problem, futex_down_timeout() detects that the syscall80 * didn't sleep in the wait queue, fixes the futex counter and RETRIES the81 * whole operation again.82 */83 39 84 40 /** Initialize futex counter. … … 92 48 } 93 49 94 int futex_down(futex_t *futex)95 {96 return futex_down_timeout(futex, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);97 }98 99 int futex_trydown(futex_t *futex)100 {101 return futex_down_timeout(futex, SYNCH_NO_TIMEOUT,102 SYNCH_FLAGS_NON_BLOCKING);103 }104 105 50 /** Try to down the futex. 106 51 * 107 52 * @param futex Futex. 108 * @param usec Microseconds to wait. Zero value means sleep without 109 * timeout. 110 * @param flags Select mode of operation. See comment for 111 * waitq_sleep_timeout(). 53 * @return Non-zero if the futex was acquired. 54 * @return Zero if the futex was not acquired. 55 */ 56 int futex_trydown(futex_t *futex) 57 { 58 return cas(futex, 1, 0); 59 } 60 61 /** Down the futex. 112 62 * 113 * @return ENOENT if there is no such virtual address. One of 114 * ESYNCH_OK_ATOMIC and ESYNCH_OK_BLOCKED on success or 115 * ESYNCH_TIMEOUT if the lock was not acquired because of 116 * a timeout or ESYNCH_WOULD_BLOCK if the operation could 117 * not be carried out atomically (if requested so). 63 * @param futex Futex. 64 * @return ENOENT if there is no such virtual address. 65 * @return Zero in the uncontended case. 66 * @return Otherwise one of ESYNCH_OK_ATOMIC or ESYNCH_OK_BLOCKED. 118 67 */ 119 int futex_down _timeout(futex_t *futex, uint32_t usec, int flags)68 int futex_down(futex_t *futex) 120 69 { 121 int rc; 122 123 while (atomic_predec(futex) < 0) { 124 rc = __SYSCALL3(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count, 125 (sysarg_t) usec, (sysarg_t) flags); 126 127 switch (rc) { 128 case ESYNCH_OK_ATOMIC: 129 /* 130 * Because of a race condition between timeout and 131 * futex_up() and between conditional 132 * futex_down_timeout() and futex_up(), we have to give 133 * up and try again in this special case. 134 */ 135 atomic_inc(futex); 136 break; 70 if (atomic_predec(futex) < 0) 71 return __SYSCALL1(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count); 137 72 138 case ESYNCH_TIMEOUT: 139 atomic_inc(futex); 140 return ESYNCH_TIMEOUT; 141 break; 142 143 case ESYNCH_WOULD_BLOCK: 144 /* 145 * The conditional down operation should be implemented 146 * this way. The userspace-only variant tends to 147 * accumulate missed wakeups in the kernel futex wait 148 * queue. 149 */ 150 atomic_inc(futex); 151 return ESYNCH_WOULD_BLOCK; 152 break; 153 154 case ESYNCH_OK_BLOCKED: 155 /* 156 * Enter the critical section. 157 * The futex counter has already been incremented for 158 * us. 159 */ 160 return ESYNCH_OK_BLOCKED; 161 break; 162 default: 163 return rc; 164 } 165 } 166 167 /* 168 * Enter the critical section. 169 */ 170 return ESYNCH_OK_ATOMIC; 73 return 0; 171 74 } 172 75 … … 174 77 * 175 78 * @param futex Futex. 176 * 177 * @return ENOENT if there is no such virtual address. Otherwise 178 * zero. 79 * @return ENOENT if there is no such virtual address. 80 * @return Zero in the uncontended case. 179 81 */ 180 82 int futex_up(futex_t *futex) 181 83 { 182 long val; 183 184 val = atomic_postinc(futex); 185 if (val < 0) 84 if (atomic_postinc(futex) < 0) 186 85 return __SYSCALL1(SYS_FUTEX_WAKEUP, (sysarg_t) &futex->count); 187 86 -
uspace/lib/libc/generic/io/console.c
r3f085132 r3b3e776 94 94 } 95 95 96 int console_get_pos(int phone, int *col, int *row) 97 { 98 ipcarg_t col_v; 99 ipcarg_t row_v; 100 int rc; 101 102 rc = async_req_0_2(phone, CONSOLE_GET_POS, &col_v, &row_v); 103 104 *col = (int) col_v; 105 *row = (int) row_v; 106 return rc; 107 } 108 96 109 void console_goto(int phone, int col, int row) 97 110 { -
uspace/lib/libc/generic/io/io.c
r3f085132 r3b3e776 341 341 size_t fread(void *buf, size_t size, size_t nmemb, FILE *stream) 342 342 { 343 size_t left = size * nmemb; 344 size_t done = 0; 345 343 size_t left, done; 344 345 if (size == 0 || nmemb == 0) 346 return 0; 347 346 348 /* Make sure no data is pending write. */ 347 349 _fflushbuf(stream); 350 351 left = size * nmemb; 352 done = 0; 348 353 349 354 while ((left > 0) && (!stream->error) && (!stream->eof)) { … … 365 370 static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream) 366 371 { 367 size_t left = size * nmemb; 368 size_t done = 0; 369 372 size_t left; 373 size_t done; 374 375 if (size == 0 || nmemb == 0) 376 return 0; 377 378 left = size * nmemb; 379 done = 0; 380 370 381 while ((left > 0) && (!stream->error)) { 371 382 ssize_t wr; … … 421 432 uint8_t b; 422 433 bool need_flush; 423 434 435 if (size == 0 || nmemb == 0) 436 return 0; 437 424 438 /* If not buffered stream, write out directly. */ 425 439 if (stream->btype == _IONBF) { … … 480 494 481 495 if (chr_encode(c, buf, &sz, STR_BOUNDS(1)) == EOK) { 482 size_t wr = fwrite(buf, sz, 1, stream);496 size_t wr = fwrite(buf, 1, sz, stream); 483 497 484 498 if (wr < sz) … … 540 554 } 541 555 556 int ftell(FILE *stream) 557 { 558 off_t rc = lseek(stream->fd, 0, SEEK_CUR); 559 if (rc == (off_t) (-1)) { 560 /* errno has been set by lseek. */ 561 return -1; 562 } 563 564 return rc; 565 } 566 542 567 void rewind(FILE *stream) 543 568 { … … 570 595 } 571 596 597 void clearerr(FILE *stream) 598 { 599 stream->eof = false; 600 stream->error = false; 601 } 602 572 603 int fphone(FILE *stream) 573 604 { -
uspace/lib/libc/generic/string.c
r3f085132 r3b3e776 471 471 * null-terminated and containing only complete characters. 472 472 * 473 * @param d st Destination buffer.473 * @param dest Destination buffer. 474 474 * @param count Size of the destination buffer (must be > 0). 475 475 * @param src Source string. … … 505 505 * have to be null-terminated. 506 506 * 507 * @param d st Destination buffer.507 * @param dest Destination buffer. 508 508 * @param count Size of the destination buffer (must be > 0). 509 509 * @param src Source string. … … 537 537 * null-terminated and containing only complete characters. 538 538 * 539 * @param d st Destination buffer.539 * @param dest Destination buffer. 540 540 * @param count Size of the destination buffer. 541 541 * @param src Source string. … … 549 549 } 550 550 551 /** Copy NULL-terminated wide string to string 552 * 553 * Copy source wide string @a src to destination buffer @a dst. 554 * No more than @a size bytes are written. NULL-terminator is always 555 * written after the last succesfully copied character (i.e. if the 556 * destination buffer is has at least 1 byte, it will be always 557 * NULL-terminated). 558 * 559 * @param src Source wide string. 560 * @param dst Destination buffer. 561 * @param count Size of the destination buffer. 562 * 563 */ 564 void wstr_nstr(char *dst, const wchar_t *src, size_t size) 565 { 566 /* No space for the NULL-terminator in the buffer */ 567 if (size == 0) 568 return; 569 551 /** Convert wide string to string. 552 * 553 * Convert wide string @a src to string. The output is written to the buffer 554 * specified by @a dest and @a size. @a size must be non-zero and the string 555 * written will always be well-formed. 556 * 557 * @param dest Destination buffer. 558 * @param size Size of the destination buffer. 559 * @param src Source wide string. 560 */ 561 void wstr_to_str(char *dest, size_t size, const wchar_t *src) 562 { 570 563 wchar_t ch; 571 size_t src_idx = 0; 572 size_t dst_off = 0; 573 564 size_t src_idx; 565 size_t dest_off; 566 567 /* There must be space for a null terminator in the buffer. */ 568 assert(size > 0); 569 570 src_idx = 0; 571 dest_off = 0; 572 574 573 while ((ch = src[src_idx++]) != 0) { 575 if (chr_encode(ch, d st, &dst_off, size) != EOK)574 if (chr_encode(ch, dest, &dest_off, size - 1) != EOK) 576 575 break; 577 576 } 578 579 if (dst_off >= size) 580 dst[size - 1] = 0; 581 else 582 dst[dst_off] = 0; 577 578 dest[dest_off] = '\0'; 579 } 580 581 /** Convert wide string to new string. 582 * 583 * Convert wide string @a src to string. Space for the new string is allocated 584 * on the heap. 585 * 586 * @param src Source wide string. 587 * @return New string. 588 */ 589 char *wstr_to_astr(const wchar_t *src) 590 { 591 char dbuf[STR_BOUNDS(1)]; 592 char *str; 593 wchar_t ch; 594 595 size_t src_idx; 596 size_t dest_off; 597 size_t dest_size; 598 599 /* Compute size of encoded string. */ 600 601 src_idx = 0; 602 dest_size = 0; 603 604 while ((ch = src[src_idx++]) != 0) { 605 dest_off = 0; 606 if (chr_encode(ch, dbuf, &dest_off, STR_BOUNDS(1)) != EOK) 607 break; 608 dest_size += dest_off; 609 } 610 611 str = malloc(dest_size + 1); 612 if (str == NULL) 613 return NULL; 614 615 /* Encode string. */ 616 617 src_idx = 0; 618 dest_off = 0; 619 620 while ((ch = src[src_idx++]) != 0) { 621 if (chr_encode(ch, str, &dest_off, dest_size) != EOK) 622 break; 623 } 624 625 str[dest_size] = '\0'; 626 return str; 627 } 628 629 630 /** Convert string to wide string. 631 * 632 * Convert string @a src to wide string. The output is written to the 633 * buffer specified by @a dest and @a dlen. @a dlen must be non-zero 634 * and the wide string written will always be null-terminated. 635 * 636 * @param dest Destination buffer. 637 * @param dlen Length of destination buffer (number of wchars). 638 * @param src Source string. 639 */ 640 void str_to_wstr(wchar_t *dest, size_t dlen, const char *src) 641 { 642 size_t offset; 643 size_t di; 644 wchar_t c; 645 646 assert(dlen > 0); 647 648 offset = 0; 649 di = 0; 650 651 do { 652 if (di >= dlen - 1) 653 break; 654 655 c = str_decode(src, &offset, STR_NO_LIMIT); 656 dest[di++] = c; 657 } while (c != '\0'); 658 659 dest[dlen - 1] = '\0'; 583 660 } 584 661 … … 819 896 } 820 897 898 char *str_dup(const char *src) 899 { 900 size_t size = str_size(src); 901 void *dest = malloc(size + 1); 902 903 if (dest == NULL) 904 return (char *) NULL; 905 906 return (char *) memcpy(dest, src, size + 1); 907 } 908 909 char *str_ndup(const char *src, size_t max_size) 910 { 911 size_t size = str_size(src); 912 if (size > max_size) 913 size = max_size; 914 915 char *dest = (char *) malloc(size + 1); 916 917 if (dest == NULL) 918 return (char *) NULL; 919 920 memcpy(dest, src, size); 921 dest[size] = 0; 922 return dest; 923 } 924 821 925 822 926 /** Convert initial part of string to unsigned long according to given base. … … 843 947 } 844 948 845 char *str_dup(const char *src)846 {847 size_t size = str_size(src);848 void *dest = malloc(size + 1);849 850 if (dest == NULL)851 return (char *) NULL;852 853 return (char *) memcpy(dest, src, size + 1);854 }855 856 949 char *strtok(char *s, const char *delim) 857 950 { -
uspace/lib/libc/generic/time.c
r3f085132 r3b3e776 31 31 */ 32 32 /** @file 33 */ 33 */ 34 34 35 35 #include <sys/time.h> … … 40 40 #include <unistd.h> 41 41 #include <atomic.h> 42 #include <futex.h>43 42 #include <sysinfo.h> 44 43 #include <ipc/services.h> 44 #include <libc.h> 45 45 46 46 #include <sysinfo.h> … … 189 189 190 190 /** Wait unconditionally for specified number of microseconds */ 191 int usleep(unsigned long usec) 192 { 193 atomic_t futex = FUTEX_INITIALIZER; 194 195 futex_initialize(&futex, 0); 196 futex_down_timeout(&futex, usec, 0); 191 int usleep(useconds_t usec) 192 { 193 (void) __SYSCALL1(SYS_THREAD_USLEEP, usec); 197 194 return 0; 198 195 } 199 196 200 197 /** Wait unconditionally for specified number of seconds */ 201 unsigned int sleep(unsigned int seconds) 202 { 203 atomic_t futex = FUTEX_INITIALIZER; 204 205 futex_initialize(&futex, 0); 206 198 unsigned int sleep(unsigned int sec) 199 { 207 200 /* Sleep in 1000 second steps to support 208 201 full argument range */ 209 while (sec onds> 0) {210 unsigned int period = (sec onds > 1000) ? 1000 : seconds;202 while (sec > 0) { 203 unsigned int period = (sec > 1000) ? 1000 : sec; 211 204 212 futex_down_timeout(&futex, period * 1000000,0);213 sec onds-= period;205 usleep(period * 1000000); 206 sec -= period; 214 207 } 215 208 return 0; -
uspace/lib/libc/generic/udebug.c
r3f085132 r3b3e776 69 69 } 70 70 71 int udebug_name_read(int phoneid, void *buffer, size_t n, 72 size_t *copied, size_t *needed) 73 { 74 ipcarg_t a_copied, a_needed; 75 int rc; 76 77 rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_NAME_READ, 78 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed); 79 80 *copied = (size_t)a_copied; 81 *needed = (size_t)a_needed; 82 83 return rc; 84 } 85 86 int udebug_areas_read(int phoneid, void *buffer, size_t n, 87 size_t *copied, size_t *needed) 88 { 89 ipcarg_t a_copied, a_needed; 90 int rc; 91 92 rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_AREAS_READ, 93 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed); 94 95 *copied = (size_t)a_copied; 96 *needed = (size_t)a_needed; 97 98 return rc; 99 } 100 71 101 int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n) 72 102 { … … 78 108 { 79 109 return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_ARGS_READ, 110 tid, (sysarg_t)buffer); 111 } 112 113 int udebug_regs_read(int phoneid, thash_t tid, void *buffer) 114 { 115 return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_REGS_READ, 80 116 tid, (sysarg_t)buffer); 81 117 } -
uspace/lib/libc/generic/vfs/canonify.c
r3f085132 r3b3e776 142 142 t->start[-1] = '\0'; 143 143 } 144 /** Eat the extra '/'. .144 /** Eat the extra '/'. 145 145 * 146 146 * @param t The current TK_SLASH token. … … 288 288 * 289 289 * A file system path is canonical, if the following holds: 290 * 1) the path is absolute (i.e. a/b/c is not canonical) 291 * 2) there is no trailing slash in the path (i.e. /a/b/c is not canonical) 292 * 3) there is no extra slash in the path (i.e. /a//b/c is not canonical) 293 * 4) there is no '.' component in the path (i.e. /a/./b/c is not canonical) 294 * 5) there is no '..' component in the path (i.e. /a/b/../c is not canonical) 290 * 291 * 1) the path is absolute 292 * (i.e. a/b/c is not canonical) 293 * 2) there is no trailing slash in the path if it has components 294 * (i.e. /a/b/c/ is not canonical) 295 * 3) there is no extra slash in the path 296 * (i.e. /a//b/c is not canonical) 297 * 4) there is no '.' component in the path 298 * (i.e. /a/./b/c is not canonical) 299 * 5) there is no '..' component in the path 300 * (i.e. /a/b/../c is not canonical) 295 301 * 296 302 * This function makes a potentially non-canonical file system path canonical. -
uspace/lib/libc/generic/vfs/vfs.c
r3f085132 r3b3e776 117 117 } 118 118 119 int mount(const char *fs_name, const char *mp, const char * dev,119 int mount(const char *fs_name, const char *mp, const char *fqdn, 120 120 const char *opts, unsigned int flags) 121 121 { 122 int res; 122 int null_id = -1; 123 char null[DEVMAP_NAME_MAXLEN]; 124 125 if (str_cmp(fqdn, "") == 0) { 126 /* No device specified, create a fresh 127 null/%d device instead */ 128 null_id = devmap_null_create(); 129 130 if (null_id == -1) 131 return ENOMEM; 132 133 snprintf(null, DEVMAP_NAME_MAXLEN, "null/%d", null_id); 134 fqdn = null; 135 } 136 137 dev_handle_t dev_handle; 138 int res = devmap_device_get_handle(fqdn, &dev_handle, flags); 139 if (res != EOK) { 140 if (null_id != -1) 141 devmap_null_destroy(null_id); 142 143 return res; 144 } 145 146 size_t mpa_size; 147 char *mpa = absolutize(mp, &mpa_size); 148 if (!mpa) { 149 if (null_id != -1) 150 devmap_null_destroy(null_id); 151 152 return ENOMEM; 153 } 154 155 futex_down(&vfs_phone_futex); 156 async_serialize_start(); 157 vfs_connect(); 158 159 ipcarg_t rc_orig; 160 aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL); 161 ipcarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size); 162 if (rc != EOK) { 163 async_wait_for(req, &rc_orig); 164 async_serialize_end(); 165 futex_up(&vfs_phone_futex); 166 free(mpa); 167 168 if (null_id != -1) 169 devmap_null_destroy(null_id); 170 171 if (rc_orig == EOK) 172 return (int) rc; 173 else 174 return (int) rc_orig; 175 } 176 177 rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts)); 178 if (rc != EOK) { 179 async_wait_for(req, &rc_orig); 180 async_serialize_end(); 181 futex_up(&vfs_phone_futex); 182 free(mpa); 183 184 if (null_id != -1) 185 devmap_null_destroy(null_id); 186 187 if (rc_orig == EOK) 188 return (int) rc; 189 else 190 return (int) rc_orig; 191 } 192 193 rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name)); 194 if (rc != EOK) { 195 async_wait_for(req, &rc_orig); 196 async_serialize_end(); 197 futex_up(&vfs_phone_futex); 198 free(mpa); 199 200 if (null_id != -1) 201 devmap_null_destroy(null_id); 202 203 if (rc_orig == EOK) 204 return (int) rc; 205 else 206 return (int) rc_orig; 207 } 208 209 /* Ask VFS whether it likes fs_name. */ 210 rc = async_req_0_0(vfs_phone, IPC_M_PING); 211 if (rc != EOK) { 212 async_wait_for(req, &rc_orig); 213 async_serialize_end(); 214 futex_up(&vfs_phone_futex); 215 free(mpa); 216 217 if (null_id != -1) 218 devmap_null_destroy(null_id); 219 220 if (rc_orig == EOK) 221 return (int) rc; 222 else 223 return (int) rc_orig; 224 } 225 226 async_wait_for(req, &rc); 227 async_serialize_end(); 228 futex_up(&vfs_phone_futex); 229 free(mpa); 230 231 if ((rc != EOK) && (null_id != -1)) 232 devmap_null_destroy(null_id); 233 234 return (int) rc; 235 } 236 237 int unmount(const char *mp) 238 { 123 239 ipcarg_t rc; 124 240 ipcarg_t rc_orig; 125 241 aid_t req; 126 dev_handle_t dev_handle;127 128 res = devmap_device_get_handle(dev, &dev_handle, flags);129 if (res != EOK)130 return res;131 132 242 size_t mpa_size; 133 char *mpa = absolutize(mp, &mpa_size); 243 char *mpa; 244 245 mpa = absolutize(mp, &mpa_size); 134 246 if (!mpa) 135 247 return ENOMEM; … … 139 251 vfs_connect(); 140 252 141 req = async_send_ 2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL);253 req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL); 142 254 rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size); 143 255 if (rc != EOK) { … … 152 264 } 153 265 154 rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts)); 155 if (rc != EOK) { 156 async_wait_for(req, &rc_orig); 157 async_serialize_end(); 158 futex_up(&vfs_phone_futex); 159 free(mpa); 160 if (rc_orig == EOK) 161 return (int) rc; 162 else 163 return (int) rc_orig; 164 } 165 166 rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name)); 167 if (rc != EOK) { 168 async_wait_for(req, &rc_orig); 169 async_serialize_end(); 170 futex_up(&vfs_phone_futex); 171 free(mpa); 172 if (rc_orig == EOK) 173 return (int) rc; 174 else 175 return (int) rc_orig; 176 } 177 178 /* Ask VFS whether it likes fs_name. */ 179 rc = async_req_0_0(vfs_phone, IPC_M_PING); 180 if (rc != EOK) { 181 async_wait_for(req, &rc_orig); 182 async_serialize_end(); 183 futex_up(&vfs_phone_futex); 184 free(mpa); 185 if (rc_orig == EOK) 186 return (int) rc; 187 else 188 return (int) rc_orig; 189 } 190 266 191 267 async_wait_for(req, &rc); 192 268 async_serialize_end(); … … 703 779 rc = fstat(fildes, &stat); 704 780 705 if (!stat.dev fs_stat.device)781 if (!stat.device) 706 782 return -1; 707 783 708 return devmap_device_connect(stat.dev fs_stat.device, 0);784 return devmap_device_connect(stat.device, 0); 709 785 } 710 786 -
uspace/lib/libc/include/adt/hash_table.h
r3f085132 r3b3e776 88 88 extern void hash_table_remove(hash_table_t *, unsigned long [], hash_count_t); 89 89 extern void hash_table_destroy(hash_table_t *); 90 extern void hash_table_apply(hash_table_t *, void (*)(link_t *, void *), 91 void *); 90 92 91 93 #endif -
uspace/lib/libc/include/assert.h
r3f085132 r3b3e776 51 51 52 52 #ifndef NDEBUG 53 # define assert(expr) if (!(expr)) { printf("Assertion failed (%s) at file '%s', line %d.\n", #expr, __FILE__, __LINE__); abort();} 53 # define assert(expr) \ 54 do { \ 55 if (!(expr)) { \ 56 printf("Assertion failed (%s) at file '%s', " \ 57 "line %d.\n", #expr, __FILE__, __LINE__); \ 58 abort(); \ 59 } \ 60 } while (0) 54 61 #else 55 62 # define assert(expr) -
uspace/lib/libc/include/async.h
r3f085132 r3b3e776 277 277 extern int async_share_out_receive(ipc_callid_t *, size_t *, int *); 278 278 extern int async_share_out_finalize(ipc_callid_t, void *); 279 280 /* 281 * User-friendly wrappers for async_data_read_forward_fast(). 282 */ 283 #define async_data_read_forward_0_0(phoneid, method, answer) \ 284 async_data_read_forward_fast((phoneid), (method), 0, 0, 0, 0, NULL) 285 #define async_data_read_forward_0_1(phoneid, method, answer) \ 286 async_data_read_forward_fast((phoneid), (method), 0, 0, 0, 0, (answer)) 287 #define async_data_read_forward_1_0(phoneid, method, arg1, answer) \ 288 async_data_read_forward_fast((phoneid), (method), (arg1), 0, 0, 0, NULL) 289 #define async_data_read_forward_1_1(phoneid, method, arg1, answer) \ 290 async_data_read_forward_fast((phoneid), (method), (arg1), 0, 0, 0, (answer)) 291 #define async_data_read_forward_2_0(phoneid, method, arg1, arg2, answer) \ 292 async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL) 293 #define async_data_read_forward_2_1(phoneid, method, arg1, arg2, answer) \ 294 async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \ 295 (answer)) 296 #define async_data_read_forward_3_0(phoneid, method, arg1, arg2, arg3, answer) \ 297 async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \ 298 NULL) 299 #define async_data_read_forward_3_1(phoneid, method, arg1, arg2, arg3, answer) \ 300 async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \ 301 (answer)) 302 #define async_data_read_forward_4_0(phoneid, method, arg1, arg2, arg3, arg4, answer) \ 303 async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \ 304 (arg4), NULL) 305 #define async_data_read_forward_4_1(phoneid, method, arg1, arg2, arg3, arg4, answer) \ 306 async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \ 307 (arg4), (answer)) 308 279 309 extern int async_data_read_start(int, void *, size_t); 280 310 extern int async_data_read_receive(ipc_callid_t *, size_t *); 281 311 extern int async_data_read_finalize(ipc_callid_t, const void *, size_t); 312 extern int async_data_read_forward_fast(int, ipcarg_t, ipcarg_t, ipcarg_t, 313 ipcarg_t, ipcarg_t, ipc_call_t *); 314 315 /* 316 * User-friendly wrappers for async_data_forward_fast(). 317 */ 318 #define async_data_forward_0_0(phoneid, method, answer) \ 319 async_data_forward_fast((phoneid), (method), 0, 0, 0, 0, NULL) 320 #define async_data_forward_0_1(phoneid, method, answer) \ 321 async_data_forward_fast((phoneid), (method), 0, 0, 0, 0, (answer)) 322 #define async_data_forward_1_0(phoneid, method, arg1, answer) \ 323 async_data_forward_fast((phoneid), (method), (arg1), 0, 0, 0, NULL) 324 #define async_data_forward_1_1(phoneid, method, arg1, answer) \ 325 async_data_forward_fast((phoneid), (method), (arg1), 0, 0, 0, (answer)) 326 #define async_data_forward_2_0(phoneid, method, arg1, arg2, answer) \ 327 async_data_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL) 328 #define async_data_forward_2_1(phoneid, method, arg1, arg2, answer) \ 329 async_data_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \ 330 (answer)) 331 #define async_data_forward_3_0(phoneid, method, arg1, arg2, arg3, answer) \ 332 async_data_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \ 333 NULL) 334 #define async_data_forward_3_1(phoneid, method, arg1, arg2, arg3, answer) \ 335 async_data_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \ 336 (answer)) 337 #define async_data_forward_4_0(phoneid, method, arg1, arg2, arg3, arg4, answer) \ 338 async_data_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \ 339 (arg4), NULL) 340 #define async_data_forward_4_1(phoneid, method, arg1, arg2, arg3, arg4, answer) \ 341 async_data_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \ 342 (arg4), (answer)) 343 282 344 extern int async_data_write_start(int, const void *, size_t); 283 345 extern int async_data_write_receive(ipc_callid_t *, size_t *); 284 346 extern int async_data_write_finalize(ipc_callid_t, void *, size_t); 347 extern int async_data_receive(void **, const size_t, const size_t, 348 const size_t, size_t *); 349 extern int async_string_receive(char **, const size_t, size_t *); 350 extern void async_data_void(const int); 351 extern int async_data_forward_fast(int, ipcarg_t, ipcarg_t, ipcarg_t, ipcarg_t, 352 ipcarg_t, ipc_call_t *); 285 353 286 354 #endif -
uspace/lib/libc/include/atomic.h
r3f085132 r3b3e776 1 1 /* 2 * Copyright (c) 200 6Jakub Jermar2 * Copyright (c) 2009 Jakub Jermar 3 3 * All rights reserved. 4 4 * … … 36 36 #define LIBC_ATOMIC_H_ 37 37 38 typedef struct atomic {39 volatile long count;40 } atomic_t;41 42 38 #include <libarch/atomic.h> 43 44 static inline void atomic_set(atomic_t *val, long i)45 {46 val->count = i;47 }48 49 static inline long atomic_get(atomic_t *val)50 {51 return val->count;52 }53 39 54 40 #endif -
uspace/lib/libc/include/devmap.h
r3f085132 r3b3e776 38 38 #include <ipc/devmap.h> 39 39 #include <async.h> 40 #include <bool.h> 40 41 41 42 extern int devmap_get_phone(devmap_interface_t, unsigned int); … … 46 47 47 48 extern int devmap_device_get_handle(const char *, dev_handle_t *, unsigned int); 49 extern int devmap_namespace_get_handle(const char *, dev_handle_t *, unsigned int); 50 extern devmap_handle_type_t devmap_handle_probe(dev_handle_t); 51 48 52 extern int devmap_device_connect(dev_handle_t, unsigned int); 49 53 … … 51 55 extern void devmap_null_destroy(int); 52 56 53 extern ipcarg_t devmap_device_get_count(void); 54 extern ipcarg_t devmap_device_get_devices(ipcarg_t, dev_desc_t *); 57 extern size_t devmap_count_namespaces(void); 58 extern size_t devmap_count_devices(dev_handle_t); 59 60 extern size_t devmap_get_namespaces(dev_desc_t **); 61 extern size_t devmap_get_devices(dev_handle_t, dev_desc_t **); 55 62 56 63 #endif -
uspace/lib/libc/include/fibril_synch.h
r3f085132 r3b3e776 33 33 */ 34 34 35 #ifndef LIBC_FIBRIL_SYNC _H_36 #define LIBC_FIBRIL_SYNC _H_35 #ifndef LIBC_FIBRIL_SYNCH_H_ 36 #define LIBC_FIBRIL_SYNCH_H_ 37 37 38 38 #include <async.h> -
uspace/lib/libc/include/futex.h
r3f085132 r3b3e776 46 46 extern int futex_down(futex_t *futex); 47 47 extern int futex_trydown(futex_t *futex); 48 extern int futex_down_timeout(futex_t *futex, uint32_t usec, int flags);49 48 extern int futex_up(futex_t *futex); 50 49 -
uspace/lib/libc/include/io/console.h
r3f085132 r3b3e776 69 69 70 70 extern int console_get_size(int phone, int *cols, int *rows); 71 extern int console_get_pos(int phone, int *col, int *row); 71 72 extern void console_goto(int phone, int col, int row); 72 73 -
uspace/lib/libc/include/ipc/bd.h
r3f085132 r3b3e776 40 40 typedef enum { 41 41 BD_GET_BLOCK_SIZE = IPC_FIRST_USER_METHOD, 42 BD_GET_NUM_BLOCKS, 42 43 BD_READ_BLOCKS, 43 44 BD_WRITE_BLOCKS -
uspace/lib/libc/include/ipc/console.h
r3f085132 r3b3e776 43 43 CONSOLE_GET_COLOR_CAP, 44 44 CONSOLE_GET_EVENT, 45 CONSOLE_GET_POS, 45 46 CONSOLE_GOTO, 46 47 CONSOLE_CLEAR, -
uspace/lib/libc/include/ipc/devmap.h
r3f085132 r3b3e776 43 43 44 44 typedef enum { 45 DEV_HANDLE_NONE, 46 DEV_HANDLE_NAMESPACE, 47 DEV_HANDLE_DEVICE 48 } devmap_handle_type_t; 49 50 typedef enum { 45 51 DEVMAP_DRIVER_REGISTER = IPC_FIRST_USER_METHOD, 46 52 DEVMAP_DRIVER_UNREGISTER, 47 53 DEVMAP_DEVICE_REGISTER, 48 54 DEVMAP_DEVICE_UNREGISTER, 49 DEVMAP_DEVICE_GET_NAME,50 55 DEVMAP_DEVICE_GET_HANDLE, 51 DEVMAP_DEVICE_NULL_CREATE, 52 DEVMAP_DEVICE_NULL_DESTROY, 53 DEVMAP_DEVICE_GET_COUNT, 54 DEVMAP_DEVICE_GET_DEVICES 56 DEVMAP_NAMESPACE_GET_HANDLE, 57 DEVMAP_HANDLE_PROBE, 58 DEVMAP_NULL_CREATE, 59 DEVMAP_NULL_DESTROY, 60 DEVMAP_GET_NAMESPACE_COUNT, 61 DEVMAP_GET_DEVICE_COUNT, 62 DEVMAP_GET_NAMESPACES, 63 DEVMAP_GET_DEVICES 55 64 } devmap_request_t; 56 65 -
uspace/lib/libc/include/ipc/services.h
r3f085132 r3b3e776 41 41 SERVICE_LOAD = 1, 42 42 SERVICE_PCI, 43 SERVICE_KEYBOARD,44 43 SERVICE_VIDEO, 45 44 SERVICE_CONSOLE, … … 47 46 SERVICE_DEVMAP, 48 47 SERVICE_FHC, 49 SERVICE_OBIO 48 SERVICE_OBIO, 49 SERVICE_CLIPBOARD 50 50 } services_t; 51 51 -
uspace/lib/libc/include/ipc/vfs.h
r3f085132 r3b3e776 86 86 VFS_OUT_MOUNTED, 87 87 VFS_OUT_UNMOUNT, 88 VFS_OUT_UNMOUNTED, 88 89 VFS_OUT_SYNC, 89 90 VFS_OUT_STAT, … … 100 101 * No lookup flags used. 101 102 */ 102 #define L_NONE 103 #define L_NONE 0 103 104 104 105 /** … … 107 108 * with L_DIRECTORY. 108 109 */ 109 #define L_FILE 110 #define L_FILE 1 110 111 111 112 /** 112 * Lookup wil succeed only if the object is a directory. If L_CREATE is113 * Lookup will succeed only if the object is a directory. If L_CREATE is 113 114 * specified, an empty directory will be created. This flag is mutually 114 115 * exclusive with L_FILE. 115 116 */ 116 #define L_DIRECTORY 2 117 #define L_DIRECTORY 2 118 119 /** 120 * Lookup will succeed only if the object is a root directory. The flag is 121 * mutually exclusive with L_FILE and L_MP. 122 */ 123 #define L_ROOT 4 124 125 /** 126 * Lookup will succeed only if the object is a mount point. The flag is mutually 127 * exclusive with L_FILE and L_ROOT. 128 */ 129 #define L_MP 8 130 117 131 118 132 /** … … 120 134 * object already exists. L_EXCLUSIVE is implied when L_DIRECTORY is used. 121 135 */ 122 #define L_EXCLUSIVE 4136 #define L_EXCLUSIVE 16 123 137 124 138 /** 125 139 * L_CREATE is used for creating both regular files and directories. 126 140 */ 127 #define L_CREATE 8141 #define L_CREATE 32 128 142 129 143 /** 130 144 * L_LINK is used for linking to an already existing nodes. 131 145 */ 132 #define L_LINK 16146 #define L_LINK 64 133 147 134 148 /** … … 137 151 * VFS_UNLINK. 138 152 */ 139 #define L_UNLINK 32153 #define L_UNLINK 128 140 154 141 155 /** 142 * L_OPEN is used to indicate that the lookup operation is a part of VFS_ OPEN156 * L_OPEN is used to indicate that the lookup operation is a part of VFS_IN_OPEN 143 157 * call from the client. This means that the server might allocate some 144 158 * resources for the opened file. This flag cannot be passed directly by the 145 159 * client. 146 160 */ 147 #define L_OPEN 64161 #define L_OPEN 256 148 162 149 163 #endif -
uspace/lib/libc/include/stdlib.h
r3f085132 r3b3e776 38 38 #include <unistd.h> 39 39 #include <malloc.h> 40 #include <stacktrace.h> 40 41 41 #define abort() _exit(1) 42 #define abort() \ 43 do { \ 44 stacktrace_print(); \ 45 _exit(1); \ 46 } while (0) 47 42 48 #define exit(status) _exit((status)) 43 49 -
uspace/lib/libc/include/string.h
r3f085132 r3b3e776 73 73 extern void str_append(char *dest, size_t size, const char *src); 74 74 75 extern void wstr_nstr(char *dst, const wchar_t *src, size_t size); 75 extern void wstr_to_str(char *dest, size_t size, const wchar_t *src); 76 extern char *wstr_to_astr(const wchar_t *src); 77 extern void str_to_wstr(wchar_t *dest, size_t dlen, const char *src); 76 78 77 79 extern char *str_chr(const char *str, wchar_t ch); … … 82 84 83 85 extern char *str_dup(const char *); 86 extern char *str_ndup(const char *, size_t max_size); 84 87 85 88 /* -
uspace/lib/libc/include/sys/stat.h
r3f085132 r3b3e776 42 42 43 43 struct stat { 44 fs_handle_t fs_handle; 45 dev_handle_t dev_handle; 46 fs_index_t index; 47 unsigned lnkcnt; 48 bool is_file; 49 off_t size; 50 union { 51 struct { 52 dev_handle_t device; 53 } devfs_stat; 54 }; 44 fs_handle_t fs_handle; 45 dev_handle_t dev_handle; 46 fs_index_t index; 47 unsigned int lnkcnt; 48 bool is_file; 49 bool is_directory; 50 off_t size; 51 dev_handle_t device; 55 52 }; 56 53 -
uspace/lib/libc/include/sys/types.h
r3f085132 r3b3e776 40 40 typedef long off_t; 41 41 typedef int mode_t; 42 typedef uint64_t bn_t; /**< Block number type. */ 42 43 43 44 typedef int32_t wchar_t; -
uspace/lib/libc/include/udebug.h
r3f085132 r3b3e776 47 47 int udebug_thread_read(int phoneid, void *buffer, size_t n, 48 48 size_t *copied, size_t *needed); 49 int udebug_name_read(int phoneid, void *buffer, size_t n, 50 size_t *copied, size_t *needed); 51 int udebug_areas_read(int phoneid, void *buffer, size_t n, 52 size_t *copied, size_t *needed); 49 53 int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n); 50 54 int udebug_args_read(int phoneid, thash_t tid, sysarg_t *buffer); 55 int udebug_regs_read(int phoneid, thash_t tid, void *buffer); 51 56 int udebug_go(int phoneid, thash_t tid, udebug_event_t *ev_type, 52 57 sysarg_t *val0, sysarg_t *val1); -
uspace/lib/libc/include/unistd.h
r3f085132 r3b3e776 51 51 #endif 52 52 53 typedef uint32_t useconds_t; 54 53 55 extern int dup2(int oldfd, int newfd); 54 56 … … 68 70 69 71 extern void _exit(int status) __attribute__ ((noreturn)); 70 extern int usleep(u nsigned long usec);71 extern unsigned int sleep(unsigned int se conds);72 extern int usleep(useconds_t uses); 73 extern unsigned int sleep(unsigned int se); 72 74 73 75 #endif -
uspace/lib/libc/include/vfs/vfs.h
r3f085132 r3b3e776 55 55 extern int mount(const char *, const char *, const char *, const char *, 56 56 unsigned int); 57 extern int unmount(const char *); 57 58 58 59 extern void __stdio_init(int filc, fdi_node_t *filv[]);
Note:
See TracChangeset
for help on using the changeset viewer.