Changeset 5f70118 in mainline for uspace/lib
- Timestamp:
- 2010-01-10T12:16:59Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c77a64f
- Parents:
- 309ede1 (diff), 1ac3a52 (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
- Files:
-
- 26 added
- 1 deleted
- 82 edited
- 4 moved
-
libblock/Makefile (modified) (1 diff)
-
libblock/Makefile.build (added)
-
libblock/Makefile.common (added)
-
libblock/libblock.c (modified) (6 diffs)
-
libblock/libblock.h (modified) (3 diffs)
-
libc/Makefile (modified) (1 diff)
-
libc/Makefile.build (added)
-
libc/Makefile.common (added)
-
libc/Makefile.toolchain (modified) (5 diffs)
-
libc/arch/amd64/Makefile.inc (modified) (1 diff)
-
libc/arch/amd64/include/atomic.h (modified) (1 diff)
-
libc/arch/amd64/include/fibril.h (modified) (1 diff)
-
libc/arch/amd64/src/entry.s (modified) (1 diff)
-
libc/arch/amd64/src/stacktrace.S (added)
-
libc/arch/amd64/src/thread_entry.s (modified) (1 diff)
-
libc/arch/arm32/Makefile.inc (modified) (1 diff)
-
libc/arch/arm32/include/atomic.h (modified) (2 diffs)
-
libc/arch/arm32/include/fibril.h (modified) (2 diffs)
-
libc/arch/arm32/src/entry.s (modified) (2 diffs)
-
libc/arch/arm32/src/stacktrace.S (added)
-
libc/arch/arm32/src/syscall.c (modified) (2 diffs)
-
libc/arch/arm32/src/thread_entry.s (modified) (1 diff)
-
libc/arch/ia32/Makefile.inc (modified) (2 diffs)
-
libc/arch/ia32/_link.ld.in (modified) (4 diffs)
-
libc/arch/ia32/include/atomic.h (modified) (1 diff)
-
libc/arch/ia32/include/fibril.h (modified) (1 diff)
-
libc/arch/ia32/include/syscall.h (modified) (1 diff)
-
libc/arch/ia32/src/entry.s (modified) (3 diffs)
-
libc/arch/ia32/src/stacktrace.S (added)
-
libc/arch/ia32/src/syscall.S (modified) (3 diffs)
-
libc/arch/ia32/src/thread_entry.s (modified) (1 diff)
-
libc/arch/ia64/Makefile.inc (modified) (1 diff)
-
libc/arch/ia64/include/atomic.h (modified) (1 diff)
-
libc/arch/ia64/src/stacktrace.S (added)
-
libc/arch/mips32/Makefile.inc (modified) (1 diff)
-
libc/arch/mips32/include/atomic.h (modified) (1 diff)
-
libc/arch/mips32/src/stacktrace.S (added)
-
libc/arch/mips32eb/Makefile.inc (modified) (1 diff)
-
libc/arch/mips32eb/include/stackarg.h (deleted)
-
libc/arch/ppc32/Makefile.inc (modified) (1 diff)
-
libc/arch/ppc32/include/atomic.h (modified) (1 diff)
-
libc/arch/ppc32/src/entry.s (modified) (1 diff)
-
libc/arch/ppc32/src/stacktrace.S (added)
-
libc/arch/ppc32/src/thread_entry.s (modified) (1 diff)
-
libc/arch/sparc64/Makefile.inc (modified) (1 diff)
-
libc/arch/sparc64/include/atomic.h (modified) (1 diff)
-
libc/arch/sparc64/include/fibril.h (modified) (1 diff)
-
libc/arch/sparc64/src/entry.s (modified) (1 diff)
-
libc/arch/sparc64/src/fibril.S (modified) (2 diffs)
-
libc/arch/sparc64/src/stacktrace.S (added)
-
libc/arch/sparc64/src/thread_entry.s (modified) (1 diff)
-
libc/generic/async.c (modified) (17 diffs)
-
libc/generic/clipboard.c (added)
-
libc/generic/devmap.c (modified) (10 diffs)
-
libc/generic/fibril_synch.c (moved) (moved from uspace/lib/libc/generic/fibril_sync.c ) (8 diffs)
-
libc/generic/futex.c (modified) (3 diffs)
-
libc/generic/io/console.c (modified) (2 diffs)
-
libc/generic/io/io.c (modified) (5 diffs)
-
libc/generic/io/klog.c (modified) (1 diff)
-
libc/generic/ipc.c (modified) (5 diffs)
-
libc/generic/libc.c (modified) (1 diff)
-
libc/generic/loader.c (modified) (4 diffs)
-
libc/generic/malloc.c (modified) (1 diff)
-
libc/generic/stacktrace.c (added)
-
libc/generic/string.c (modified) (6 diffs)
-
libc/generic/task.c (modified) (2 diffs)
-
libc/generic/time.c (modified) (3 diffs)
-
libc/generic/vfs/canonify.c (modified) (2 diffs)
-
libc/generic/vfs/vfs.c (modified) (22 diffs)
-
libc/include/assert.h (modified) (1 diff)
-
libc/include/async.h (modified) (1 diff)
-
libc/include/async_priv.h (added)
-
libc/include/atomic.h (modified) (2 diffs)
-
libc/include/atomicdflt.h (added)
-
libc/include/clipboard.h (moved) (moved from kernel/arch/amd64/include/arg.h ) (4 diffs)
-
libc/include/devmap.h (modified) (3 diffs)
-
libc/include/fcntl.h (modified) (1 diff)
-
libc/include/fibril_synch.h (moved) (moved from uspace/lib/libc/include/fibril_sync.h ) (3 diffs)
-
libc/include/futex.h (modified) (1 diff)
-
libc/include/io/console.h (modified) (1 diff)
-
libc/include/ipc/bd.h (modified) (1 diff)
-
libc/include/ipc/char.h (added)
-
libc/include/ipc/clipboard.h (added)
-
libc/include/ipc/console.h (modified) (1 diff)
-
libc/include/ipc/devmap.h (modified) (1 diff)
-
libc/include/ipc/ipc.h (modified) (1 diff)
-
libc/include/ipc/loader.h (modified) (1 diff)
-
libc/include/ipc/mouse.h (added)
-
libc/include/ipc/services.h (modified) (2 diffs)
-
libc/include/ipc/vfs.h (modified) (1 diff)
-
libc/include/loader/loader.h (modified) (1 diff)
-
libc/include/loader/pcb.h (modified) (1 diff)
-
libc/include/malloc.h (modified) (1 diff)
-
libc/include/stacktrace.h (added)
-
libc/include/stdarg.h (modified) (1 diff)
-
libc/include/stdlib.h (modified) (1 diff)
-
libc/include/string.h (modified) (2 diffs)
-
libc/include/sys/stat.h (modified) (1 diff)
-
libc/include/sys/types.h (modified) (1 diff)
-
libc/include/unistd.h (modified) (2 diffs)
-
libfs/Makefile (modified) (1 diff)
-
libfs/Makefile.build (added)
-
libfs/Makefile.common (added)
-
libfs/libfs.c (modified) (19 diffs)
-
libfs/libfs.h (modified) (1 diff)
-
softfloat/Makefile (modified) (2 diffs)
-
softfloat/Makefile.build (moved) (moved from uspace/srv/pci/Makefile ) (2 diffs)
-
softfloat/Makefile.common (added)
-
softint/Makefile (modified) (2 diffs)
-
softint/Makefile.build (added)
-
softint/Makefile.common (added)
-
softint/generic/multiplication.c (added)
-
softint/include/multiplication.h (added)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libblock/Makefile
r309ede1 r5f70118 28 28 # 29 29 30 ## Common compiler flags 31 # 30 include Makefile.common 32 31 33 LIBC_PREFIX = ../libc 32 .PHONY: all clean 34 33 35 ## Setup toolchain 36 # 37 38 include $(LIBC_PREFIX)/Makefile.toolchain 39 40 CFLAGS += -Iinclude 41 42 ## Sources 43 # 44 45 SOURCES = \ 46 libblock.c 47 48 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 49 50 .PHONY: all clean depend 51 52 all: libblock.a 53 54 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBC_PREFIX)/libc.a 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build PRECHECK=$(PRECHECK) 55 37 56 38 clean: 57 -rm -f libblock.a Makefile.depend39 rm -f $(DEPEND) $(DEPEND_PREV) $(JOB) $(LIBBLOCK) 58 40 find . -name '*.o' -follow -exec rm \{\} \; 59 60 depend:61 -makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null62 63 libblock.a: depend $(OBJECTS)64 $(AR) rc libblock.a $(OBJECTS)65 66 %.o: %.c67 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ -
uspace/lib/libblock/libblock.c
r309ede1 r5f70118 47 47 #include <as.h> 48 48 #include <assert.h> 49 #include <fibril_sync .h>49 #include <fibril_synch.h> 50 50 #include <adt/list.h> 51 51 #include <adt/hash_table.h> … … 87 87 static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt); 88 88 static int get_block_size(int dev_phone, size_t *bsize); 89 static int get_num_blocks(int dev_phone, bn_t *nblocks); 89 90 90 91 static devcon_t *devcon_search(dev_handle_t dev_handle) … … 168 169 } 169 170 170 rc = ipc_share_out_start(dev_phone, comm_area,171 rc = async_share_out_start(dev_phone, comm_area, 171 172 AS_AREA_READ | AS_AREA_WRITE); 172 173 if (rc != EOK) { … … 714 715 715 716 memcpy(devcon->comm_area, data, devcon->pblock_size * cnt); 716 rc = read_blocks(devcon, ba, cnt);717 rc = write_blocks(devcon, ba, cnt); 717 718 718 719 fibril_mutex_unlock(&devcon->comm_area_lock); … … 736 737 737 738 return get_block_size(devcon->dev_phone, bsize); 739 } 740 741 /** Get number of blocks on device. 742 * 743 * @param dev_handle Device handle of the block device. 744 * @param nblocks Output number of blocks. 745 * 746 * @return EOK on success or negative error code on failure. 747 */ 748 int block_get_nblocks(dev_handle_t dev_handle, bn_t *nblocks) 749 { 750 devcon_t *devcon; 751 752 devcon = devcon_search(dev_handle); 753 assert(devcon); 754 755 return get_num_blocks(devcon->dev_phone, nblocks); 738 756 } 739 757 … … 789 807 } 790 808 809 /** Get total number of blocks on block device. */ 810 static int get_num_blocks(int dev_phone, bn_t *nblocks) 811 { 812 ipcarg_t nb_l, nb_h; 813 int rc; 814 815 rc = async_req_0_2(dev_phone, BD_GET_NUM_BLOCKS, &nb_l, &nb_h); 816 if (rc == EOK) { 817 *nblocks = (bn_t) MERGE_LOUP32(nb_l, nb_h); 818 } 819 820 return rc; 821 } 822 791 823 /** @} 792 824 */ -
uspace/lib/libblock/libblock.h
r309ede1 r5f70118 36 36 37 37 #ifndef LIBBLOCK_LIBBLOCK_H_ 38 #define LIBBLOCK_LIBBLOCK_H_38 #define LIBBLOCK_LIBBLOCK_H_ 39 39 40 40 #include <stdint.h> 41 41 #include "../../srv/vfs/vfs.h" 42 #include <fibril_sync .h>42 #include <fibril_synch.h> 43 43 #include <adt/hash_table.h> 44 44 #include <adt/list.h> … … 59 59 */ 60 60 #define BLOCK_FLAGS_NOREAD 1 61 62 typedef uint64_t bn_t; /**< Block number type. */63 61 64 62 typedef struct block { … … 110 108 111 109 extern int block_get_bsize(dev_handle_t, size_t *); 110 extern int block_get_nblocks(dev_handle_t, bn_t *); 112 111 extern int block_read_direct(dev_handle_t, bn_t, size_t, void *); 113 112 extern int block_write_direct(dev_handle_t, bn_t, size_t, const void *); -
uspace/lib/libc/Makefile
r309ede1 r5f70118 27 27 # 28 28 29 ## Common compiler flags 30 # 29 include Makefile.common 31 30 32 LIBC_PREFIX = $(shell pwd) 33 SOFTINT_PREFIX = ../softint 31 .PHONY: all clean 34 32 35 36 ## Setup toolchain 37 # 38 39 include $(LIBC_PREFIX)/Makefile.toolchain 40 41 42 ## Sources 43 # 44 45 GENERIC_SOURCES = \ 46 generic/libc.c \ 47 generic/ddi.c \ 48 generic/as.c \ 49 generic/cap.c \ 50 generic/devmap.c \ 51 generic/event.c \ 52 generic/errno.c \ 53 generic/mem.c \ 54 generic/string.c \ 55 generic/fibril.c \ 56 generic/fibril_sync.c \ 57 generic/pcb.c \ 58 generic/smc.c \ 59 generic/thread.c \ 60 generic/tls.c \ 61 generic/task.c \ 62 generic/futex.c \ 63 generic/io/asprintf.c \ 64 generic/io/io.c \ 65 generic/io/printf.c \ 66 generic/io/klog.c \ 67 generic/io/snprintf.c \ 68 generic/io/vprintf.c \ 69 generic/io/vsnprintf.c \ 70 generic/io/printf_core.c \ 71 generic/io/console.c \ 72 generic/malloc.c \ 73 generic/sysinfo.c \ 74 generic/ipc.c \ 75 generic/async.c \ 76 generic/loader.c \ 77 generic/getopt.c \ 78 generic/adt/list.o \ 79 generic/adt/hash_table.o \ 80 generic/time.c \ 81 generic/err.c \ 82 generic/stdlib.c \ 83 generic/mman.c \ 84 generic/udebug.c \ 85 generic/vfs/vfs.c \ 86 generic/vfs/canonify.c 87 88 ARCH_SOURCES += \ 89 arch/$(UARCH)/src/entry.s \ 90 arch/$(UARCH)/src/thread_entry.s 91 92 GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) 93 ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES))) 94 OBJECTS := $(GENERIC_OBJECTS) $(ARCH_OBJECTS) 95 96 .PHONY: all clean depend kerninc 97 98 all: kerninc libc.a arch/$(UARCH)/_link.ld 99 100 kerninc: 101 ln -sfn ../../../../kernel/generic/include include/kernel 102 ln -sfn kernel/arch include/arch 103 ln -sfn ../arch/$(UARCH)/include include/libarch 104 105 -include Makefile.depend 33 all: ../../../Makefile.config ../../../config.h ../../../config.defs 34 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 35 $(MAKE) -f Makefile.build PRECHECK=$(PRECHECK) 106 36 107 37 clean: 108 -rm -f include/kernel include/arch include/libarch libc.a arch/$(UARCH)/_link.ld Makefile.depend 109 find generic/ arch/$(UARCH)/ -name '*.o' -follow -exec rm \{\} \; 110 111 depend: kerninc 112 -makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null 113 114 libc.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS) 115 $(AR) rc libc.a $(LIBS) $(ARCH_OBJECTS) $(GENERIC_OBJECTS) 116 117 arch/$(UARCH)/_link.ld: arch/$(UARCH)/_link.ld.in 118 $(CC) $(DEFS) $(CFLAGS) -DLIBC_PREFIX=$(LIBC_PREFIX) -E -x c $< | grep -v "^\#" > $@ 119 120 %.o: %.S 121 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 122 123 %.o: %.s 124 $(AS) $(AFLAGS) $< -o $@ 125 126 %.o: %.c 127 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 38 rm -f $(DEPEND) $(DEPEND_PREV) $(JOB) $(INCLUDE_KERNEL) $(INCLUDE_ARCH) $(INCLUDE_LIBARCH) $(LIBC) arch/*/_link.ld 39 find generic/ arch/*/ -name '*.o' -follow -exec rm \{\} \; -
uspace/lib/libc/Makefile.toolchain
r309ede1 r5f70118 27 27 # 28 28 29 CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \29 GCC_CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \ 30 30 -fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \ 31 -finput-charset=UTF-8 -fno-builtin -Wall -Wextra -Wno-unused-parameter \ 32 -Wmissing-prototypes -Werror-implicit-function-declaration -nostdlib \ 33 -nostdinc -pipe -g -D__$(ENDIANESS)__ 31 -finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \ 32 -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \ 33 -Werror-implicit-function-declaration -pipe -g -D__$(ENDIANESS)__ 34 35 ICC_CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \ 36 -fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \ 37 -finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \ 38 -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \ 39 -Werror-implicit-function-declaration -pipe -g -D__$(ENDIANESS)__ 40 41 CLANG_CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \ 42 -fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \ 43 -finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \ 44 -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \ 45 -Werror-implicit-function-declaration -pipe -g -arch $(CLANG_ARCH) \ 46 -D__$(ENDIANESS)__ 47 34 48 LFLAGS = -M -N $(SOFTINT_PREFIX)/libsoftint.a 35 49 AFLAGS = … … 45 59 # 46 60 47 -include $(LIBC_PREFIX)/../../../Makefile.config48 -include $(LIBC_PREFIX)/../../../config.defs49 -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 50 64 51 65 ## Simple detection of the host system … … 64 78 # 65 79 80 JOBFILE = $(LIBC_PREFIX)/../../../tools/jobfile.py 81 82 ifeq ($(COMPILER),gcc_cross) 83 CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc 84 GCC = $(CC) 85 AS = $(TOOLCHAIN_DIR)/$(TARGET)-as 86 LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld 87 AR = $(TOOLCHAIN_DIR)/$(TARGET)-ar 88 OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy 89 OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump 90 CFLAGS = $(GCC_CFLAGS) 91 DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) 92 endif 93 66 94 ifeq ($(COMPILER),gcc_native) 67 95 CC = gcc 96 GCC = $(CC) 68 97 AS = $(BINUTILS_PREFIX)as 69 98 LD = $(BINUTILS_PREFIX)ld … … 71 100 OBJCOPY = $(BINUTILS_PREFIX)objcopy 72 101 OBJDUMP = $(BINUTILS_PREFIX)objdump 102 CFLAGS = $(GCC_CFLAGS) 73 103 DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) 74 104 endif 75 105 76 ifeq ($(COMPILER),icc _native)106 ifeq ($(COMPILER),icc) 77 107 CC = icc 108 GCC = gcc 78 109 AS = as 79 110 LD = ld … … 81 112 OBJCOPY = objcopy 82 113 OBJDUMP = objdump 114 CFLAGS = $(ICC_CFLAGS) 83 115 DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) 84 116 endif 85 117 86 ifeq ($(COMPILER),gcc_cross) 87 CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc 88 AS = $(TOOLCHAIN_DIR)/$(TARGET)-as 89 LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld 90 AR = $(TOOLCHAIN_DIR)/$(TARGET)-ar 91 OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy 92 OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump 118 ifeq ($(COMPILER),clang) 119 CC = clang 120 GCC = gcc 121 AS = $(BINUTILS_PREFIX)as 122 LD = $(BINUTILS_PREFIX)ld 123 AR = $(BINUTILS_PREFIX)ar 124 OBJCOPY = $(BINUTILS_PREFIX)objcopy 125 OBJDUMP = $(BINUTILS_PREFIX)objdump 126 CFLAGS = $(CLANG_CFLAGS) 93 127 DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) 94 128 endif -
uspace/lib/libc/arch/amd64/Makefile.inc
r309ede1 r5f70118 31 31 32 32 TARGET = amd64-linux-gnu 33 CLANG_ARCH = x86_64 33 34 TOOLCHAIN_DIR = $(CROSS_PREFIX)/amd64/bin 34 35 35 36 ARCH_SOURCES += arch/$(UARCH)/src/syscall.S \ 36 37 arch/$(UARCH)/src/fibril.S \ 37 arch/$(UARCH)/src/tls.c 38 arch/$(UARCH)/src/tls.c \ 39 arch/$(UARCH)/src/stacktrace.S 38 40 41 GCC_CFLAGS += -fno-omit-frame-pointer 39 42 LFLAGS += -N 40 43 -
uspace/lib/libc/arch/amd64/include/atomic.h
r309ede1 r5f70118 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
r309ede1 r5f70118 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/src/entry.s
r309ede1 r5f70118 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
r309ede1 r5f70118 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
r309ede1 r5f70118 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.S 40 41 41 CFLAGS += -ffixed-r9 -mtp=soft 42 GCC_CFLAGS += -ffixed-r9 -mtp=soft -mapcs-frame -fno-omit-frame-pointer 42 43 LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a 43 44 -
uspace/lib/libc/arch/arm32/include/atomic.h
r309ede1 r5f70118 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
r309ede1 r5f70118 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/src/entry.s
r309ede1 r5f70118 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
r309ede1 r5f70118 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
r309ede1 r5f70118 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
r309ede1 r5f70118 31 31 32 32 TARGET = i686-pc-linux-gnu 33 CLANG_ARCH = i386 33 34 TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia32/bin 34 35 … … 36 37 arch/$(UARCH)/src/fibril.S \ 37 38 arch/$(UARCH)/src/tls.c \ 38 arch/$(UARCH)/src/setjmp.S 39 arch/$(UARCH)/src/setjmp.S \ 40 arch/$(UARCH)/src/stacktrace.S 39 41 42 GCC_CFLAGS += -march=pentium 40 43 LFLAGS += -N 41 44 -
uspace/lib/libc/arch/ia32/_link.ld.in
r309ede1 r5f70118 3 3 4 4 PHDRS { 5 text PT_LOAD FLAGS(5);5 text PT_LOAD FLAGS(5); 6 6 data PT_LOAD FLAGS(6); 7 7 } … … 9 9 SECTIONS { 10 10 . = 0x1000 + SIZEOF_HEADERS; 11 11 12 12 .init : { 13 13 *(.init); 14 14 } :text 15 15 16 .text : { 16 17 *(.text); 17 *(.rodata*);18 *(.rodata*); 18 19 } :text 19 20 20 21 . = . + 0x1000; 21 22 22 23 .data : { 23 24 *(.data); 24 25 } :data 26 25 27 .tdata : { 26 28 _tdata_start = .; 27 29 *(.tdata); 30 *(.gnu.linkonce.tb.*); 28 31 _tdata_end = .; 29 32 _tbss_start = .; … … 31 34 _tbss_end = .; 32 35 } :data 36 33 37 _tls_alignment = ALIGNOF(.tdata); 38 34 39 .bss : { 35 *(COMMON);36 *(.bss);40 *(COMMON); 41 *(.bss); 37 42 } :data 38 43 39 44 . = ALIGN(0x1000); 45 40 46 _heap = .; 41 47 … … 43 49 *(*); 44 50 } 45 46 51 } -
uspace/lib/libc/arch/ia32/include/atomic.h
r309ede1 r5f70118 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
r309ede1 r5f70118 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/syscall.h
r309ede1 r5f70118 40 40 #include <kernel/syscall/syscall.h> 41 41 42 #define __syscall0 __syscall_ sysenter43 #define __syscall1 __syscall_ sysenter44 #define __syscall2 __syscall_ sysenter45 #define __syscall3 __syscall_ sysenter46 #define __syscall4 __syscall_ sysenter47 #define __syscall5 __syscall_ int48 #define __syscall6 __syscall_ int42 #define __syscall0 __syscall_fast_func 43 #define __syscall1 __syscall_fast_func 44 #define __syscall2 __syscall_fast_func 45 #define __syscall3 __syscall_fast_func 46 #define __syscall4 __syscall_fast_func 47 #define __syscall5 __syscall_slow 48 #define __syscall6 __syscall_slow 49 49 50 50 extern sysarg_t 51 __syscall_sysenter(const sysarg_t,const sysarg_t, const sysarg_t, const sysarg_t,52 const sysarg_t, const sysarg_t, const syscall_t);51 (* __syscall_fast_func)(const sysarg_t, const sysarg_t, const sysarg_t, 52 const sysarg_t, const sysarg_t, const sysarg_t, const syscall_t); 53 53 54 54 extern sysarg_t 55 __syscall_ int(const sysarg_t, const sysarg_t, const sysarg_t, const sysarg_t,56 const sysarg_t, const sysarg_t, const syscall_t);55 __syscall_slow(const sysarg_t, const sysarg_t, const sysarg_t, const sysarg_t, 56 const sysarg_t, const sysarg_t, const syscall_t); 57 57 58 58 #endif -
uspace/lib/libc/arch/ia32/src/entry.s
r309ede1 r5f70118 27 27 # 28 28 29 INTEL_CPUID_STANDARD = 1 30 INTEL_SEP = 11 31 29 32 .section .init, "ax" 30 33 … … 35 38 ## User-space task entry point 36 39 # 37 # %e bxcontains the PCB pointer40 # %edi contains the PCB pointer 38 41 # 39 42 __entry: … … 44 47 # Do not set %gs, it contains descriptor that can see TLS 45 48 49 # Detect the mechanism used for making syscalls 50 movl $(INTEL_CPUID_STANDARD), %eax 51 cpuid 52 bt $(INTEL_SEP), %edx 53 jnc 0f 54 leal __syscall_fast_func, %eax 55 movl $__syscall_fast, (%eax) 56 0: 57 # 58 # Create the first stack frame. 59 # 60 pushl $0 61 movl %esp, %ebp 62 46 63 # Pass the PCB pointer to __main as the first argument 47 pushl %e bx64 pushl %edi 48 65 call __main 49 66 -
uspace/lib/libc/arch/ia32/src/syscall.S
r309ede1 r5f70118 27 27 # 28 28 29 .data 30 31 .global __syscall_fast_func 32 __syscall_fast_func: 33 .long __syscall_slow 34 29 35 .text 30 36 … … 35 41 * could benefit from this and not save unused registers on the stack. 36 42 */ 37 .global __syscall_ int38 __syscall_ int:43 .global __syscall_slow 44 __syscall_slow: 39 45 pushl %ebx 40 46 pushl %esi … … 64 70 * segment, otherwise the SYSENTER wouldn't work in the first place). 65 71 */ 66 .global __syscall_ sysenter67 __syscall_ sysenter:72 .global __syscall_fast 73 __syscall_fast: 68 74 pushl %ebx 69 75 pushl %esi -
uspace/lib/libc/arch/ia32/src/thread_entry.s
r309ede1 r5f70118 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
r309ede1 r5f70118 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.S 39 40 40 CFLAGS += -fno-unwind-tables41 GCC_CFLAGS += -fno-unwind-tables 41 42 LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a 42 43 -
uspace/lib/libc/arch/ia64/include/atomic.h
r309ede1 r5f70118 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/mips32/Makefile.inc
r309ede1 r5f70118 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.S 38 39 39 CFLAGS += -mips340 GCC_CFLAGS += -mips3 40 41 41 42 ENDIANESS = LE -
uspace/lib/libc/arch/mips32/include/atomic.h
r309ede1 r5f70118 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/mips32eb/Makefile.inc
r309ede1 r5f70118 34 34 35 35 ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \ 36 arch/$(UARCH)/src/fibril.S \37 arch/$(UARCH)/src/tls.c36 arch/$(UARCH)/src/fibril.S \ 37 arch/$(UARCH)/src/tls.c 38 38 39 CFLAGS += -mips339 GCC_CFLAGS += -mips3 40 40 LFLAGS += -N 41 41 -
uspace/lib/libc/arch/ppc32/Makefile.inc
r309ede1 r5f70118 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.S 38 39 39 CFLAGS += -mcpu=powerpc -msoft-float -m3240 GCC_CFLAGS += -mcpu=powerpc -msoft-float -m32 40 41 AFLAGS += -a32 41 42 LFLAGS += -N -
uspace/lib/libc/arch/ppc32/include/atomic.h
r309ede1 r5f70118 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/src/entry.s
r309ede1 r5f70118 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
r309ede1 r5f70118 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
r309ede1 r5f70118 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.S 37 38 38 CFLAGS += -mcpu=ultrasparc -m6439 GCC_CFLAGS += -mcpu=ultrasparc -m64 39 40 LFLAGS += -no-check-sections -N 40 41 -
uspace/lib/libc/arch/sparc64/include/atomic.h
r309ede1 r5f70118 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
r309ede1 r5f70118 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/src/entry.s
r309ede1 r5f70118 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
r309ede1 r5f70118 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/thread_entry.s
r309ede1 r5f70118 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/async.c
r309ede1 r5f70118 83 83 * 84 84 * callid = async_get_call(&call); 85 * handle_call(callid, call);85 * somehow_handle_the_call(callid, call); 86 86 * ipc_answer_2(callid, 1, 2, 3); 87 87 * … … 94 94 #include <futex.h> 95 95 #include <async.h> 96 #include <async_priv.h> 96 97 #include <fibril.h> 97 98 #include <stdio.h> … … 110 111 atomic_t threads_in_ipc_wait = { 0 }; 111 112 112 /** Structures of this type represent a waiting fibril. */113 typedef struct {114 /** Expiration time. */115 struct timeval expires;116 117 /** If true, this struct is in the timeout list. */118 bool inlist;119 120 /** Timeout list link. */121 link_t link;122 123 /** Identification of and link to the waiting fibril. */124 fid_t fid;125 126 /** If true, this fibril is currently active. */127 bool active;128 129 /** If true, we have timed out. */130 bool timedout;131 } awaiter_t;132 133 113 typedef struct { 134 114 awaiter_t wdata; … … 253 233 * 254 234 */ 255 static voidinsert_timeout(awaiter_t *wd)256 { 257 wd->t imedout= false;258 wd-> inlist = true;235 void async_insert_timeout(awaiter_t *wd) 236 { 237 wd->to_event.occurred = false; 238 wd->to_event.inlist = true; 259 239 260 240 link_t *tmp = timeout_list.next; 261 241 while (tmp != &timeout_list) { 262 awaiter_t *cur = list_get_instance(tmp, awaiter_t, link); 263 264 if (tv_gteq(&cur->expires, &wd->expires)) 242 awaiter_t *cur; 243 244 cur = list_get_instance(tmp, awaiter_t, to_event.link); 245 if (tv_gteq(&cur->to_event.expires, &wd->to_event.expires)) 265 246 break; 266 267 247 tmp = tmp->next; 268 248 } 269 249 270 list_append(&wd-> link, tmp);250 list_append(&wd->to_event.link, tmp); 271 251 } 272 252 … … 315 295 316 296 /* If in timeout list, remove it */ 317 if (conn->wdata. inlist) {318 conn->wdata. inlist = false;319 list_remove(&conn->wdata. link);297 if (conn->wdata.to_event.inlist) { 298 conn->wdata.to_event.inlist = false; 299 list_remove(&conn->wdata.to_event.link); 320 300 } 321 301 … … 405 385 406 386 if (usecs) { 407 gettimeofday(&conn->wdata. expires, NULL);408 tv_add(&conn->wdata. expires, usecs);387 gettimeofday(&conn->wdata.to_event.expires, NULL); 388 tv_add(&conn->wdata.to_event.expires, usecs); 409 389 } else 410 conn->wdata. inlist = false;390 conn->wdata.to_event.inlist = false; 411 391 412 392 /* If nothing in queue, wait until something arrives */ 413 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 414 408 if (usecs) 415 insert_timeout(&conn->wdata);409 async_insert_timeout(&conn->wdata); 416 410 417 411 conn->wdata.active = false; … … 430 424 */ 431 425 futex_down(&async_futex); 432 if ((usecs) && (conn->wdata.t imedout)426 if ((usecs) && (conn->wdata.to_event.occurred) 433 427 && (list_empty(&conn->msg_queue))) { 434 428 /* If we timed out -> exit */ … … 548 542 list_initialize(&conn->msg_queue); 549 543 conn->callid = callid; 550 conn->close_callid = false;544 conn->close_callid = 0; 551 545 552 546 if (call) … … 625 619 link_t *cur = timeout_list.next; 626 620 while (cur != &timeout_list) { 627 awaiter_t *waiter = list_get_instance(cur, awaiter_t, link); 628 629 if (tv_gt(&waiter->expires, &tv)) 621 awaiter_t *waiter; 622 623 waiter = list_get_instance(cur, awaiter_t, to_event.link); 624 if (tv_gt(&waiter->to_event.expires, &tv)) 630 625 break; 631 626 632 627 cur = cur->next; 633 634 list_remove(&waiter-> link);635 waiter-> inlist = false;636 waiter->t imedout= true;628 629 list_remove(&waiter->to_event.link); 630 waiter->to_event.inlist = false; 631 waiter->to_event.occurred = true; 637 632 638 633 /* … … 671 666 if (!list_empty(&timeout_list)) { 672 667 awaiter_t *waiter = list_get_instance(timeout_list.next, 673 awaiter_t, link);668 awaiter_t, to_event.link); 674 669 675 670 struct timeval tv; 676 671 gettimeofday(&tv, NULL); 677 672 678 if (tv_gteq(&tv, &waiter-> expires)) {673 if (tv_gteq(&tv, &waiter->to_event.expires)) { 679 674 futex_up(&async_futex); 680 675 handle_expired_timeouts(); 681 676 continue; 682 677 } else 683 timeout = tv_sub(&waiter->expires, &tv); 678 timeout = tv_sub(&waiter->to_event.expires, 679 &tv); 684 680 } else 685 681 timeout = SYNCH_NO_TIMEOUT; … … 782 778 783 779 /* Remove message from timeout list */ 784 if (msg->wdata. inlist)785 list_remove(&msg->wdata. link);780 if (msg->wdata.to_event.inlist) 781 list_remove(&msg->wdata.to_event.link); 786 782 787 783 msg->done = true; … … 822 818 msg->dataptr = dataptr; 823 819 824 msg->wdata. inlist = false;820 msg->wdata.to_event.inlist = false; 825 821 /* We may sleep in the next method, but it will use its own mechanism */ 826 822 msg->wdata.active = true; … … 862 858 msg->dataptr = dataptr; 863 859 864 msg->wdata. inlist = false;860 msg->wdata.to_event.inlist = false; 865 861 /* We may sleep in next method, but it will use its own mechanism */ 866 862 msg->wdata.active = true; … … 891 887 msg->wdata.fid = fibril_get_id(); 892 888 msg->wdata.active = false; 893 msg->wdata. inlist = false;889 msg->wdata.to_event.inlist = false; 894 890 895 891 /* Leave the async_futex locked when entering this function */ … … 929 925 } 930 926 931 gettimeofday(&msg->wdata. expires, NULL);932 tv_add(&msg->wdata. expires, timeout);927 gettimeofday(&msg->wdata.to_event.expires, NULL); 928 tv_add(&msg->wdata.to_event.expires, timeout); 933 929 934 930 msg->wdata.fid = fibril_get_id(); 935 931 msg->wdata.active = false; 936 insert_timeout(&msg->wdata);932 async_insert_timeout(&msg->wdata); 937 933 938 934 /* Leave the async_futex locked when entering this function */ … … 970 966 msg->wdata.active = false; 971 967 972 gettimeofday(&msg->wdata. expires, NULL);973 tv_add(&msg->wdata. expires, timeout);968 gettimeofday(&msg->wdata.to_event.expires, NULL); 969 tv_add(&msg->wdata.to_event.expires, timeout); 974 970 975 971 futex_down(&async_futex); 976 972 977 insert_timeout(&msg->wdata);973 async_insert_timeout(&msg->wdata); 978 974 979 975 /* Leave the async_futex locked when entering this function */ … … 1105 1101 } 1106 1102 1103 /** Wrapper for making IPC_M_SHARE_IN calls using the async framework. 1104 * 1105 * @param phoneid Phone that will be used to contact the receiving side. 1106 * @param dst Destination address space area base. 1107 * @param size Size of the destination address space area. 1108 * @param arg User defined argument. 1109 * @param flags Storage where the received flags will be stored. Can be 1110 * NULL. 1111 * 1112 * @return Zero on success or a negative error code from errno.h. 1113 */ 1114 int async_share_in_start(int phoneid, void *dst, size_t size, ipcarg_t arg, 1115 int *flags) 1116 { 1117 int res; 1118 sysarg_t tmp_flags; 1119 res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst, 1120 (ipcarg_t) size, arg, NULL, &tmp_flags); 1121 if (flags) 1122 *flags = tmp_flags; 1123 return res; 1124 } 1125 1126 /** Wrapper for receiving the IPC_M_SHARE_IN calls using the async framework. 1127 * 1128 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN calls 1129 * so that the user doesn't have to remember the meaning of each IPC argument. 1130 * 1131 * So far, this wrapper is to be used from within a connection fibril. 1132 * 1133 * @param callid Storage where the hash of the IPC_M_SHARE_IN call will 1134 * be stored. 1135 * @param size Destination address space area size. 1136 * 1137 * @return Non-zero on success, zero on failure. 1138 */ 1139 int async_share_in_receive(ipc_callid_t *callid, size_t *size) 1140 { 1141 ipc_call_t data; 1142 1143 assert(callid); 1144 assert(size); 1145 1146 *callid = async_get_call(&data); 1147 if (IPC_GET_METHOD(data) != IPC_M_SHARE_IN) 1148 return 0; 1149 *size = (size_t) IPC_GET_ARG2(data); 1150 return 1; 1151 } 1152 1153 /** Wrapper for answering the IPC_M_SHARE_IN calls using the async framework. 1154 * 1155 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls 1156 * so that the user doesn't have to remember the meaning of each IPC argument. 1157 * 1158 * @param callid Hash of the IPC_M_DATA_READ call to answer. 1159 * @param src Source address space base. 1160 * @param flags Flags to be used for sharing. Bits can be only cleared. 1161 * 1162 * @return Zero on success or a value from @ref errno.h on failure. 1163 */ 1164 int async_share_in_finalize(ipc_callid_t callid, void *src, int flags) 1165 { 1166 return ipc_share_in_finalize(callid, src, flags); 1167 } 1168 1169 /** Wrapper for making IPC_M_SHARE_OUT calls using the async framework. 1170 * 1171 * @param phoneid Phone that will be used to contact the receiving side. 1172 * @param src Source address space area base address. 1173 * @param flags Flags to be used for sharing. Bits can be only cleared. 1174 * 1175 * @return Zero on success or a negative error code from errno.h. 1176 */ 1177 int async_share_out_start(int phoneid, void *src, int flags) 1178 { 1179 return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0, 1180 (ipcarg_t) flags); 1181 } 1182 1183 /** Wrapper for receiving the IPC_M_SHARE_OUT calls using the async framework. 1184 * 1185 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT calls 1186 * so that the user doesn't have to remember the meaning of each IPC argument. 1187 * 1188 * So far, this wrapper is to be used from within a connection fibril. 1189 * 1190 * @param callid Storage where the hash of the IPC_M_SHARE_OUT call will 1191 * be stored. 1192 * @param size Storage where the source address space area size will be 1193 * stored. 1194 * @param flags Storage where the sharing flags will be stored. 1195 * 1196 * @return Non-zero on success, zero on failure. 1197 */ 1198 int async_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags) 1199 { 1200 ipc_call_t data; 1201 1202 assert(callid); 1203 assert(size); 1204 assert(flags); 1205 1206 *callid = async_get_call(&data); 1207 if (IPC_GET_METHOD(data) != IPC_M_SHARE_OUT) 1208 return 0; 1209 *size = (size_t) IPC_GET_ARG2(data); 1210 *flags = (int) IPC_GET_ARG3(data); 1211 return 1; 1212 } 1213 1214 /** Wrapper for answering the IPC_M_SHARE_OUT calls using the async framework. 1215 * 1216 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls 1217 * so that the user doesn't have to remember the meaning of each IPC argument. 1218 * 1219 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 1220 * @param dst Destination address space area base address. 1221 * 1222 * @return Zero on success or a value from @ref errno.h on failure. 1223 */ 1224 int async_share_out_finalize(ipc_callid_t callid, void *dst) 1225 { 1226 return ipc_share_out_finalize(callid, dst); 1227 } 1228 1229 1230 /** Wrapper for making IPC_M_DATA_READ calls using the async framework. 1231 * 1232 * @param phoneid Phone that will be used to contact the receiving side. 1233 * @param dst Address of the beginning of the destination buffer. 1234 * @param size Size of the destination buffer. 1235 * 1236 * @return Zero on success or a negative error code from errno.h. 1237 */ 1238 int async_data_read_start(int phoneid, void *dst, size_t size) 1239 { 1240 return async_req_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst, 1241 (ipcarg_t) size); 1242 } 1243 1244 /** Wrapper for receiving the IPC_M_DATA_READ calls using the async framework. 1245 * 1246 * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ calls 1247 * so that the user doesn't have to remember the meaning of each IPC argument. 1248 * 1249 * So far, this wrapper is to be used from within a connection fibril. 1250 * 1251 * @param callid Storage where the hash of the IPC_M_DATA_READ call will 1252 * be stored. 1253 * @param size Storage where the maximum size will be stored. Can be 1254 * NULL. 1255 * 1256 * @return Non-zero on success, zero on failure. 1257 */ 1258 int async_data_read_receive(ipc_callid_t *callid, size_t *size) 1259 { 1260 ipc_call_t data; 1261 1262 assert(callid); 1263 1264 *callid = async_get_call(&data); 1265 if (IPC_GET_METHOD(data) != IPC_M_DATA_READ) 1266 return 0; 1267 if (size) 1268 *size = (size_t) IPC_GET_ARG2(data); 1269 return 1; 1270 } 1271 1272 /** Wrapper for answering the IPC_M_DATA_READ calls using the async framework. 1273 * 1274 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls 1275 * so that the user doesn't have to remember the meaning of each IPC argument. 1276 * 1277 * @param callid Hash of the IPC_M_DATA_READ call to answer. 1278 * @param src Source address for the IPC_M_DATA_READ call. 1279 * @param size Size for the IPC_M_DATA_READ call. Can be smaller than 1280 * the maximum size announced by the sender. 1281 * 1282 * @return Zero on success or a value from @ref errno.h on failure. 1283 */ 1284 int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size) 1285 { 1286 return ipc_data_read_finalize(callid, src, size); 1287 } 1288 1289 /** Wrapper for making IPC_M_DATA_WRITE calls using the async framework. 1290 * 1291 * @param phoneid Phone that will be used to contact the receiving side. 1292 * @param src Address of the beginning of the source buffer. 1293 * @param size Size of the source buffer. 1294 * 1295 * @return Zero on success or a negative error code from errno.h. 1296 */ 1297 int async_data_write_start(int phoneid, const void *src, size_t size) 1298 { 1299 return async_req_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src, 1300 (ipcarg_t) size); 1301 } 1302 1303 /** Wrapper for receiving the IPC_M_DATA_WRITE calls using the async framework. 1304 * 1305 * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE calls 1306 * so that the user doesn't have to remember the meaning of each IPC argument. 1307 * 1308 * So far, this wrapper is to be used from within a connection fibril. 1309 * 1310 * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will 1311 * be stored. 1312 * @param size Storage where the suggested size will be stored. May be 1313 * NULL 1314 * 1315 * @return Non-zero on success, zero on failure. 1316 */ 1317 int async_data_write_receive(ipc_callid_t *callid, size_t *size) 1318 { 1319 ipc_call_t data; 1320 1321 assert(callid); 1322 1323 *callid = async_get_call(&data); 1324 if (IPC_GET_METHOD(data) != IPC_M_DATA_WRITE) 1325 return 0; 1326 if (size) 1327 *size = (size_t) IPC_GET_ARG2(data); 1328 return 1; 1329 } 1330 1331 /** Wrapper for answering the IPC_M_DATA_WRITE calls using the async framework. 1332 * 1333 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE calls 1334 * so that the user doesn't have to remember the meaning of each IPC argument. 1335 * 1336 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 1337 * @param dst Final destination address for the IPC_M_DATA_WRITE call. 1338 * @param size Final size for the IPC_M_DATA_WRITE call. 1339 * 1340 * @return Zero on success or a value from @ref errno.h on failure. 1341 */ 1342 int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size) 1343 { 1344 return ipc_data_write_finalize(callid, dst, size); 1345 } 1346 1347 /** Wrapper for receiving blobs via the async_data_write_* 1348 * 1349 * This wrapper only makes it more comfortable to use async_data_write_* 1350 * functions to receive blobs. 1351 * 1352 * @param blob Pointer to data pointer (which should be later disposed 1353 * by free()). If the operation fails, the pointer is not 1354 * touched. 1355 * @param max_size Maximum size (in bytes) of the blob to receive. 0 means 1356 * no limit. 1357 * @param received If not NULL, the size of the received data is stored here. 1358 * 1359 * @return Zero on success or a value from @ref errno.h on failure. 1360 * 1361 */ 1362 int async_data_blob_receive(char **blob, const size_t max_size, size_t *received) 1363 { 1364 ipc_callid_t callid; 1365 size_t size; 1366 if (!async_data_write_receive(&callid, &size)) { 1367 ipc_answer_0(callid, EINVAL); 1368 return EINVAL; 1369 } 1370 1371 if ((max_size > 0) && (size > max_size)) { 1372 ipc_answer_0(callid, EINVAL); 1373 return EINVAL; 1374 } 1375 1376 char *data = (char *) malloc(size); 1377 if (data == NULL) { 1378 ipc_answer_0(callid, ENOMEM); 1379 return ENOMEM; 1380 } 1381 1382 int rc = async_data_write_finalize(callid, data, size); 1383 if (rc != EOK) { 1384 free(data); 1385 return rc; 1386 } 1387 1388 *blob = data; 1389 if (received != NULL) 1390 *received = size; 1391 1392 return EOK; 1393 } 1394 1395 /** Wrapper for receiving strings via the async_data_write_* 1396 * 1397 * This wrapper only makes it more comfortable to use async_data_write_* 1398 * functions to receive strings. 1399 * 1400 * @param str Pointer to string pointer (which should be later disposed 1401 * by free()). If the operation fails, the pointer is not 1402 * touched. 1403 * @param max_size Maximum size (in bytes) of the string to receive. 0 means 1404 * no limit. 1405 * 1406 * @return Zero on success or a value from @ref errno.h on failure. 1407 * 1408 */ 1409 int async_data_string_receive(char **str, const size_t max_size) 1410 { 1411 ipc_callid_t callid; 1412 size_t size; 1413 if (!async_data_write_receive(&callid, &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 char *data = (char *) malloc(size + 1); 1424 if (data == NULL) { 1425 ipc_answer_0(callid, ENOMEM); 1426 return ENOMEM; 1427 } 1428 1429 int rc = async_data_write_finalize(callid, data, size); 1430 if (rc != EOK) { 1431 free(data); 1432 return rc; 1433 } 1434 1435 data[size] = 0; 1436 *str = data; 1437 return EOK; 1438 } 1439 1107 1440 /** @} 1108 1441 */ -
uspace/lib/libc/generic/devmap.c
r309ede1 r5f70118 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 = ipc_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 = ipc_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 = ipc_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 = ipc_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
r309ede1 r5f70118 33 33 */ 34 34 35 #include <fibril_sync .h>35 #include <fibril_synch.h> 36 36 #include <fibril.h> 37 37 #include <async.h> 38 #include <async_priv.h> 38 39 #include <adt/list.h> 39 40 #include <futex.h> 41 #include <sys/time.h> 42 #include <errno.h> 40 43 #include <assert.h> 41 44 … … 63 66 futex_down(&async_futex); 64 67 if (fm->counter-- <= 0) { 65 fibril_t *f = (fibril_t *) fibril_get_id(); 66 list_append(&f->link, &fm->waiters); 68 awaiter_t wdata; 69 70 wdata.fid = fibril_get_id(); 71 wdata.active = false; 72 wdata.wu_event.inlist = true; 73 link_initialize(&wdata.wu_event.link); 74 list_append(&wdata.wu_event.link, &fm->waiters); 67 75 fibril_switch(FIBRIL_TO_MANAGER); 68 76 } else { … … 90 98 if (fm->counter++ < 0) { 91 99 link_t *tmp; 92 fibril_t *f;100 awaiter_t *wdp; 93 101 94 102 assert(!list_empty(&fm->waiters)); 95 103 tmp = fm->waiters.next; 96 f = list_get_instance(tmp, fibril_t, link); 97 list_remove(&f->link); 98 fibril_add_ready((fid_t) f); 104 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 105 wdp->active = true; 106 wdp->wu_event.inlist = false; 107 list_remove(&wdp->wu_event.link); 108 fibril_add_ready(wdp->fid); 99 109 optimize_execution_power(); 100 110 } … … 120 130 if (frw->writers) { 121 131 fibril_t *f = (fibril_t *) fibril_get_id(); 132 awaiter_t wdata; 133 134 wdata.fid = (fid_t) f; 135 wdata.active = false; 136 wdata.wu_event.inlist = true; 137 link_initialize(&wdata.wu_event.link); 122 138 f->flags &= ~FIBRIL_WRITER; 123 list_append(& f->link, &frw->waiters);139 list_append(&wdata.wu_event.link, &frw->waiters); 124 140 fibril_switch(FIBRIL_TO_MANAGER); 125 141 } else { … … 134 150 if (frw->writers || frw->readers) { 135 151 fibril_t *f = (fibril_t *) fibril_get_id(); 152 awaiter_t wdata; 153 154 wdata.fid = (fid_t) f; 155 wdata.active = false; 156 wdata.wu_event.inlist = true; 157 link_initialize(&wdata.wu_event.link); 136 158 f->flags |= FIBRIL_WRITER; 137 list_append(& f->link, &frw->waiters);159 list_append(&wdata.wu_event.link, &frw->waiters); 138 160 fibril_switch(FIBRIL_TO_MANAGER); 139 161 } else { … … 158 180 while (!list_empty(&frw->waiters)) { 159 181 link_t *tmp = frw->waiters.next; 160 fibril_t *f = list_get_instance(tmp, fibril_t, link); 182 awaiter_t *wdp; 183 fibril_t *f; 184 185 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 186 f = (fibril_t *) wdp->fid; 161 187 162 188 if (f->flags & FIBRIL_WRITER) { 163 189 if (frw->readers) 164 190 break; 165 list_remove(&f->link); 166 fibril_add_ready((fid_t) f); 191 wdp->active = true; 192 wdp->wu_event.inlist = false; 193 list_remove(&wdp->wu_event.link); 194 fibril_add_ready(wdp->fid); 167 195 frw->writers++; 168 196 optimize_execution_power(); 169 197 break; 170 198 } else { 171 list_remove(&f->link); 172 fibril_add_ready((fid_t) f); 199 wdp->active = true; 200 wdp->wu_event.inlist = false; 201 list_remove(&wdp->wu_event.link); 202 fibril_add_ready(wdp->fid); 173 203 frw->readers++; 174 204 optimize_execution_power(); … … 194 224 } 195 225 196 void fibril_condvar_wait(fibril_condvar_t *fcv, fibril_mutex_t *fm) 197 { 198 fibril_t *f = (fibril_t *) fibril_get_id(); 199 200 futex_down(&async_futex); 201 list_append(&f->link, &fcv->waiters); 226 int 227 fibril_condvar_wait_timeout(fibril_condvar_t *fcv, fibril_mutex_t *fm, 228 suseconds_t timeout) 229 { 230 awaiter_t wdata; 231 232 if (timeout < 0) 233 return ETIMEOUT; 234 235 wdata.fid = fibril_get_id(); 236 wdata.active = false; 237 238 wdata.to_event.inlist = timeout > 0; 239 wdata.to_event.occurred = false; 240 link_initialize(&wdata.to_event.link); 241 242 wdata.wu_event.inlist = true; 243 link_initialize(&wdata.wu_event.link); 244 245 futex_down(&async_futex); 246 if (timeout) { 247 gettimeofday(&wdata.to_event.expires, NULL); 248 tv_add(&wdata.to_event.expires, timeout); 249 async_insert_timeout(&wdata); 250 } 251 list_append(&wdata.wu_event.link, &fcv->waiters); 202 252 _fibril_mutex_unlock_unsafe(fm); 203 253 fibril_switch(FIBRIL_TO_MANAGER); 204 254 fibril_mutex_lock(fm); 255 256 /* async_futex not held after fibril_switch() */ 257 futex_down(&async_futex); 258 if (wdata.to_event.inlist) 259 list_remove(&wdata.to_event.link); 260 if (wdata.wu_event.inlist) 261 list_remove(&wdata.wu_event.link); 262 futex_up(&async_futex); 263 264 return wdata.to_event.occurred ? ETIMEOUT : EOK; 265 } 266 267 void fibril_condvar_wait(fibril_condvar_t *fcv, fibril_mutex_t *fm) 268 { 269 int rc; 270 271 rc = fibril_condvar_wait_timeout(fcv, fm, 0); 272 assert(rc == EOK); 205 273 } 206 274 … … 208 276 { 209 277 link_t *tmp; 210 fibril_t *f;278 awaiter_t *wdp; 211 279 212 280 futex_down(&async_futex); 213 281 while (!list_empty(&fcv->waiters)) { 214 282 tmp = fcv->waiters.next; 215 f = list_get_instance(tmp, fibril_t, link); 216 list_remove(&f->link); 217 fibril_add_ready((fid_t) f); 218 optimize_execution_power(); 219 if (once) 220 break; 283 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 284 list_remove(&wdp->wu_event.link); 285 wdp->wu_event.inlist = false; 286 if (!wdp->active) { 287 wdp->active = true; 288 fibril_add_ready(wdp->fid); 289 optimize_execution_power(); 290 if (once) 291 break; 292 } 221 293 } 222 294 futex_up(&async_futex); -
uspace/lib/libc/generic/futex.c
r309ede1 r5f70118 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
r309ede1 r5f70118 45 45 } 46 46 47 int console_get_size(int phone, i pcarg_t *rows, ipcarg_t *cols)47 int console_get_size(int phone, int *cols, int *rows) 48 48 { 49 return async_req_0_2(phone, CONSOLE_GET_SIZE, rows, cols); 49 ipcarg_t cols_v; 50 ipcarg_t rows_v; 51 int rc; 52 53 rc = async_req_0_2(phone, CONSOLE_GET_SIZE, &cols_v, &rows_v); 54 55 *cols = (int) cols_v; 56 *rows = (int) rows_v; 57 return rc; 50 58 } 51 59 … … 86 94 } 87 95 88 void console_goto(int phone, ipcarg_t row, ipcarg_t col)96 int console_get_pos(int phone, int *col, int *row) 89 97 { 90 async_msg_2(phone, CONSOLE_GOTO, row, col); 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 109 void console_goto(int phone, int col, int row) 110 { 111 async_msg_2(phone, CONSOLE_GOTO, col, row); 91 112 } 92 113 -
uspace/lib/libc/generic/io/io.c
r309ede1 r5f70118 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 { -
uspace/lib/libc/generic/io/klog.c
r309ede1 r5f70118 42 42 size_t klog_write(const void *buf, size_t size) 43 43 { 44 return (size_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size); 44 ssize_t ret = (ssize_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size); 45 46 if (ret >= 0) 47 return (size_t) ret; 48 49 return 0; 45 50 } 46 51 -
uspace/lib/libc/generic/ipc.c
r309ede1 r5f70118 730 730 int res; 731 731 sysarg_t tmp_flags; 732 res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst,732 res = ipc_call_sync_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst, 733 733 (ipcarg_t) size, arg, NULL, &tmp_flags); 734 734 if (flags) … … 737 737 } 738 738 739 /** Wrapper for receiving the IPC_M_SHARE_IN calls.740 *741 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN calls742 * so that the user doesn't have to remember the meaning of each IPC argument.743 *744 * So far, this wrapper is to be used from within a connection fibril.745 *746 * @param callid Storage where the hash of the IPC_M_SHARE_IN call will747 * be stored.748 * @param size Destination address space area size.749 *750 * @return Non-zero on success, zero on failure.751 */752 int ipc_share_in_receive(ipc_callid_t *callid, size_t *size)753 {754 ipc_call_t data;755 756 assert(callid);757 assert(size);758 759 *callid = async_get_call(&data);760 if (IPC_GET_METHOD(data) != IPC_M_SHARE_IN)761 return 0;762 *size = (size_t) IPC_GET_ARG2(data);763 return 1;764 }765 766 739 /** Wrapper for answering the IPC_M_SHARE_IN calls. 767 740 * … … 790 763 int ipc_share_out_start(int phoneid, void *src, int flags) 791 764 { 792 return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0,765 return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0, 793 766 (ipcarg_t) flags); 794 }795 796 /** Wrapper for receiving the IPC_M_SHARE_OUT calls.797 *798 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT calls799 * so that the user doesn't have to remember the meaning of each IPC argument.800 *801 * So far, this wrapper is to be used from within a connection fibril.802 *803 * @param callid Storage where the hash of the IPC_M_SHARE_OUT call will804 * be stored.805 * @param size Storage where the source address space area size will be806 * stored.807 * @param flags Storage where the sharing flags will be stored.808 *809 * @return Non-zero on success, zero on failure.810 */811 int ipc_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags)812 {813 ipc_call_t data;814 815 assert(callid);816 assert(size);817 assert(flags);818 819 *callid = async_get_call(&data);820 if (IPC_GET_METHOD(data) != IPC_M_SHARE_OUT)821 return 0;822 *size = (size_t) IPC_GET_ARG2(data);823 *flags = (int) IPC_GET_ARG3(data);824 return 1;825 767 } 826 768 … … 851 793 int ipc_data_read_start(int phoneid, void *dst, size_t size) 852 794 { 853 return async_req_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst,795 return ipc_call_sync_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst, 854 796 (ipcarg_t) size); 855 }856 857 /** Wrapper for receiving the IPC_M_DATA_READ calls.858 *859 * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ calls860 * so that the user doesn't have to remember the meaning of each IPC argument.861 *862 * So far, this wrapper is to be used from within a connection fibril.863 *864 * @param callid Storage where the hash of the IPC_M_DATA_READ call will865 * be stored.866 * @param size Storage where the maximum size will be stored. Can be867 * NULL.868 *869 * @return Non-zero on success, zero on failure.870 */871 int ipc_data_read_receive(ipc_callid_t *callid, size_t *size)872 {873 ipc_call_t data;874 875 assert(callid);876 877 *callid = async_get_call(&data);878 if (IPC_GET_METHOD(data) != IPC_M_DATA_READ)879 return 0;880 if (size)881 *size = (size_t) IPC_GET_ARG2(data);882 return 1;883 797 } 884 798 … … 910 824 int ipc_data_write_start(int phoneid, const void *src, size_t size) 911 825 { 912 return async_req_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src,826 return ipc_call_sync_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src, 913 827 (ipcarg_t) size); 914 }915 916 /** Wrapper for receiving the IPC_M_DATA_WRITE calls.917 *918 * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE calls919 * so that the user doesn't have to remember the meaning of each IPC argument.920 *921 * So far, this wrapper is to be used from within a connection fibril.922 *923 * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will924 * be stored.925 * @param size Storage where the suggested size will be stored. May be926 * NULL927 *928 * @return Non-zero on success, zero on failure.929 */930 int ipc_data_write_receive(ipc_callid_t *callid, size_t *size)931 {932 ipc_call_t data;933 934 assert(callid);935 936 *callid = async_get_call(&data);937 if (IPC_GET_METHOD(data) != IPC_M_DATA_WRITE)938 return 0;939 if (size)940 *size = (size_t) IPC_GET_ARG2(data);941 return 1;942 828 } 943 829 -
uspace/lib/libc/generic/libc.c
r309ede1 r5f70118 83 83 argv = __pcb->argv; 84 84 __stdio_init(__pcb->filc, __pcb->filv); 85 (void) chdir(__pcb->cwd); 85 86 } 86 87 -
uspace/lib/libc/generic/loader.c
r309ede1 r5f70118 90 90 ipc_call_t answer; 91 91 aid_t req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer); 92 int rc = ipc_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t)); 92 int rc = async_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t)); 93 if (rc != EOK) { 94 async_wait_for(req, NULL); 95 return rc; 96 } 97 98 ipcarg_t retval; 99 async_wait_for(req, &retval); 100 return (int) retval; 101 } 102 103 /** Set current working directory for the loaded task. 104 * 105 * Sets the current working directory for the loaded task. 106 * 107 * @param ldr Loader connection structure. 108 * 109 * @return Zero on success or negative error code. 110 * 111 */ 112 int loader_set_cwd(loader_t *ldr) 113 { 114 char *cwd; 115 size_t len; 116 117 cwd = (char *) malloc(MAX_PATH_LEN + 1); 118 if (!cwd) 119 return ENOMEM; 120 if (!getcwd(cwd, MAX_PATH_LEN + 1)) 121 str_cpy(cwd, MAX_PATH_LEN + 1, "/"); 122 len = str_length(cwd); 123 124 ipc_call_t answer; 125 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_CWD, &answer); 126 int rc = async_data_write_start(ldr->phone_id, cwd, len); 127 free(cwd); 93 128 if (rc != EOK) { 94 129 async_wait_for(req, NULL); … … 123 158 ipc_call_t answer; 124 159 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer); 125 int rc = ipc_data_write_start(ldr->phone_id, (void *) pa, pa_len);160 int rc = async_data_write_start(ldr->phone_id, (void *) pa, pa_len); 126 161 if (rc != EOK) { 127 162 async_wait_for(req, NULL); … … 178 213 ipc_call_t answer; 179 214 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer); 180 ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size);215 ipcarg_t rc = async_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size); 181 216 if (rc != EOK) { 182 217 async_wait_for(req, NULL); … … 232 267 ipc_call_t answer; 233 268 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_FILES, &answer); 234 ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) files_buf,269 ipcarg_t rc = async_data_write_start(ldr->phone_id, (void *) files_buf, 235 270 count * sizeof(fdi_node_t)); 236 271 if (rc != EOK) { -
uspace/lib/libc/generic/malloc.c
r309ede1 r5f70118 353 353 } 354 354 355 void *calloc(const size_t nmemb, const size_t size) 356 { 357 void *block = malloc(nmemb * size); 358 if (block == NULL) 359 return NULL; 360 361 memset(block, 0, nmemb * size); 362 return block; 363 } 364 355 365 void *malloc(const size_t size) 356 366 { -
uspace/lib/libc/generic/string.c
r309ede1 r5f70118 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/task.c
r309ede1 r5f70118 89 89 goto error; 90 90 91 /* Send spawner's current working directory. */ 92 rc = loader_set_cwd(ldr); 93 if (rc != EOK) 94 goto error; 95 91 96 /* Send program pathname. */ 92 97 rc = loader_set_pathname(ldr, path); … … 98 103 if (rc != EOK) 99 104 goto error; 100 101 105 102 106 /* Send default files */ -
uspace/lib/libc/generic/time.c
r309ede1 r5f70118 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/vfs/canonify.c
r309ede1 r5f70118 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
r309ede1 r5f70118 57 57 static futex_t cwd_futex = FUTEX_INITIALIZER; 58 58 59 DIR *cwd_dir = NULL;60 char *cwd_path = NULL;61 s ize_t cwd_size = 0;59 static int cwd_fd = -1; 60 static char *cwd_path = NULL; 61 static size_t cwd_size = 0; 62 62 63 63 char *absolutize(const char *path, size_t *retlen) … … 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 { … … 126 126 dev_handle_t dev_handle; 127 127 128 res = devmap_device_get_handle( dev, &dev_handle, flags);128 res = devmap_device_get_handle(fqdn, &dev_handle, flags); 129 129 if (res != EOK) 130 130 return res; … … 140 140 141 141 req = async_send_2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL); 142 rc = ipc_data_write_start(vfs_phone, (void *) mpa, mpa_size);142 rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size); 143 143 if (rc != EOK) { 144 144 async_wait_for(req, &rc_orig); … … 152 152 } 153 153 154 rc = ipc_data_write_start(vfs_phone, (void *) opts, str_size(opts));154 rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts)); 155 155 if (rc != EOK) { 156 156 async_wait_for(req, &rc_orig); … … 164 164 } 165 165 166 rc = ipc_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));166 rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name)); 167 167 if (rc != EOK) { 168 168 async_wait_for(req, &rc_orig); … … 197 197 } 198 198 199 static int _open(const char *path, int lflag, int oflag, ...) 200 { 201 ipcarg_t rc; 199 static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag) 200 { 201 futex_down(&vfs_phone_futex); 202 async_serialize_start(); 203 vfs_connect(); 204 202 205 ipc_call_t answer; 203 aid_t req; 204 205 size_t pa_size; 206 char *pa = absolutize(path, &pa_size); 207 if (!pa) 208 return ENOMEM; 209 210 futex_down(&vfs_phone_futex); 211 async_serialize_start(); 212 vfs_connect(); 213 214 req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer); 215 rc = ipc_data_write_start(vfs_phone, pa, pa_size); 206 aid_t req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer); 207 ipcarg_t rc = async_data_write_start(vfs_phone, abs, abs_size); 208 216 209 if (rc != EOK) { 217 210 ipcarg_t rc_orig; 218 219 async_wait_for(req, &rc_orig);220 async_serialize_end(); 221 futex_up(&vfs_phone_futex); 222 free(pa);223 if (rc_orig == EOK) 224 return (int) rc; 225 else 226 return (int) rc_orig; 227 } 228 async_wait_for(req, &rc);229 async_ serialize_end();230 futex_up(&vfs_phone_futex);231 f ree(pa);211 async_wait_for(req, &rc_orig); 212 213 async_serialize_end(); 214 futex_up(&vfs_phone_futex); 215 216 if (rc_orig == EOK) 217 return (int) rc; 218 else 219 return (int) rc_orig; 220 } 221 222 async_wait_for(req, &rc); 223 async_serialize_end(); 224 futex_up(&vfs_phone_futex); 232 225 233 226 if (rc != EOK) … … 239 232 int open(const char *path, int oflag, ...) 240 233 { 241 return _open(path, L_FILE, oflag); 234 size_t abs_size; 235 char *abs = absolutize(path, &abs_size); 236 if (!abs) 237 return ENOMEM; 238 239 int ret = open_internal(abs, abs_size, L_FILE, oflag); 240 free(abs); 241 242 return ret; 242 243 } 243 244 … … 290 291 291 292 req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer); 292 rc = ipc_data_read_start(vfs_phone, (void *)buf, nbyte);293 rc = async_data_read_start(vfs_phone, (void *)buf, nbyte); 293 294 if (rc != EOK) { 294 295 ipcarg_t rc_orig; … … 322 323 323 324 req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer); 324 rc = ipc_data_write_start(vfs_phone, (void *)buf, nbyte);325 rc = async_data_write_start(vfs_phone, (void *)buf, nbyte); 325 326 if (rc != EOK) { 326 327 ipcarg_t rc_orig; … … 402 403 403 404 req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL); 404 rc = ipc_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat));405 rc = async_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat)); 405 406 if (rc != EOK) { 406 407 ipcarg_t rc_orig; … … 437 438 438 439 req = async_send_0(vfs_phone, VFS_IN_STAT, NULL); 439 rc = ipc_data_write_start(vfs_phone, pa, pa_size);440 rc = async_data_write_start(vfs_phone, pa, pa_size); 440 441 if (rc != EOK) { 441 442 async_wait_for(req, &rc_orig); … … 448 449 return (int) rc_orig; 449 450 } 450 rc = ipc_data_read_start(vfs_phone, stat, sizeof(struct stat));451 rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat)); 451 452 if (rc != EOK) { 452 453 async_wait_for(req, &rc_orig); … … 471 472 if (!dirp) 472 473 return NULL; 473 dirp->fd = _open(dirname, L_DIRECTORY, 0); 474 if (dirp->fd < 0) { 474 475 size_t abs_size; 476 char *abs = absolutize(dirname, &abs_size); 477 if (!abs) { 478 free(dirp); 479 return ENOMEM; 480 } 481 482 int ret = open_internal(abs, abs_size, L_DIRECTORY, 0); 483 free(abs); 484 485 if (ret < 0) { 475 486 free(dirp); 476 487 return NULL; 477 488 } 489 490 dirp->fd = ret; 478 491 return dirp; 479 492 } … … 514 527 515 528 req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL); 516 rc = ipc_data_write_start(vfs_phone, pa, pa_size);529 rc = async_data_write_start(vfs_phone, pa, pa_size); 517 530 if (rc != EOK) { 518 531 ipcarg_t rc_orig; … … 549 562 550 563 req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL); 551 rc = ipc_data_write_start(vfs_phone, pa, pa_size);564 rc = async_data_write_start(vfs_phone, pa, pa_size); 552 565 if (rc != EOK) { 553 566 ipcarg_t rc_orig; … … 602 615 603 616 req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL); 604 rc = ipc_data_write_start(vfs_phone, olda, olda_size);617 rc = async_data_write_start(vfs_phone, olda, olda_size); 605 618 if (rc != EOK) { 606 619 async_wait_for(req, &rc_orig); … … 614 627 return (int) rc_orig; 615 628 } 616 rc = ipc_data_write_start(vfs_phone, newa, newa_size);629 rc = async_data_write_start(vfs_phone, newa, newa_size); 617 630 if (rc != EOK) { 618 631 async_wait_for(req, &rc_orig); … … 636 649 int chdir(const char *path) 637 650 { 638 size_t pa_size; 639 char *pa = absolutize(path, &pa_size); 640 if (!pa) 641 return ENOMEM; 642 643 DIR *d = opendir(pa); 644 if (!d) { 645 free(pa); 651 size_t abs_size; 652 char *abs = absolutize(path, &abs_size); 653 if (!abs) 654 return ENOMEM; 655 656 int fd = open_internal(abs, abs_size, L_DIRECTORY, O_DESC); 657 658 if (fd < 0) { 659 free(abs); 646 660 return ENOENT; 647 661 } 648 662 649 663 futex_down(&cwd_futex); 650 if (cwd_dir) { 651 closedir(cwd_dir); 652 cwd_dir = NULL; 653 free(cwd_path); 654 cwd_path = NULL; 655 cwd_size = 0; 656 } 657 cwd_dir = d; 658 cwd_path = pa; 659 cwd_size = pa_size; 664 665 if (cwd_fd >= 0) 666 close(cwd_fd); 667 668 669 if (cwd_path) 670 free(cwd_path); 671 672 cwd_fd = fd; 673 cwd_path = abs; 674 cwd_size = abs_size; 675 660 676 futex_up(&cwd_futex); 661 677 return EOK; … … 664 680 char *getcwd(char *buf, size_t size) 665 681 { 666 if ( !size)682 if (size == 0) 667 683 return NULL; 684 668 685 futex_down(&cwd_futex); 669 if (size < cwd_size + 1) { 686 687 if ((cwd_size == 0) || (size < cwd_size + 1)) { 670 688 futex_up(&cwd_futex); 671 689 return NULL; 672 690 } 691 673 692 str_cpy(buf, size, cwd_path); 674 693 futex_up(&cwd_futex); 694 675 695 return buf; 676 696 } … … 683 703 rc = fstat(fildes, &stat); 684 704 685 if (!stat.dev fs_stat.device)705 if (!stat.device) 686 706 return -1; 687 707 688 return devmap_device_connect(stat.dev fs_stat.device, 0);708 return devmap_device_connect(stat.device, 0); 689 709 } 690 710 … … 705 725 } 706 726 727 int dup2(int oldfd, int newfd) 728 { 729 futex_down(&vfs_phone_futex); 730 async_serialize_start(); 731 vfs_connect(); 732 733 ipcarg_t ret; 734 ipcarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret); 735 736 async_serialize_end(); 737 futex_up(&vfs_phone_futex); 738 739 if (rc == EOK) 740 return (int) ret; 741 742 return (int) rc; 743 } 744 707 745 /** @} 708 746 */ -
uspace/lib/libc/include/assert.h
r309ede1 r5f70118 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
r309ede1 r5f70118 259 259 } 260 260 261 /* 262 * User-friendly wrappers for async_share_in_start(). 263 */ 264 #define async_share_in_start_0_0(phoneid, dst, size) \ 265 async_share_in_start((phoneid), (dst), (size), 0, NULL) 266 #define async_share_in_start_0_1(phoneid, dst, size, flags) \ 267 async_share_in_start((phoneid), (dst), (size), 0, (flags)) 268 #define async_share_in_start_1_0(phoneid, dst, size, arg) \ 269 async_share_in_start((phoneid), (dst), (size), (arg), NULL) 270 #define async_share_in_start_1_1(phoneid, dst, size, arg, flags) \ 271 async_share_in_start((phoneid), (dst), (size), (arg), (flags)) 272 273 extern int async_share_in_start(int, void *, size_t, ipcarg_t, int *); 274 extern int async_share_in_receive(ipc_callid_t *, size_t *); 275 extern int async_share_in_finalize(ipc_callid_t, void *, int ); 276 extern int async_share_out_start(int, void *, int); 277 extern int async_share_out_receive(ipc_callid_t *, size_t *, int *); 278 extern int async_share_out_finalize(ipc_callid_t, void *); 279 extern int async_data_read_start(int, void *, size_t); 280 extern int async_data_read_receive(ipc_callid_t *, size_t *); 281 extern int async_data_read_finalize(ipc_callid_t, const void *, size_t); 282 extern int async_data_write_start(int, const void *, size_t); 283 extern int async_data_write_receive(ipc_callid_t *, size_t *); 284 extern int async_data_write_finalize(ipc_callid_t, void *, size_t); 285 286 extern int async_data_blob_receive(char **, const size_t, size_t *); 287 extern int async_data_string_receive(char **, const size_t); 288 261 289 #endif 262 290 -
uspace/lib/libc/include/atomic.h
r309ede1 r5f70118 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/clipboard.h
r309ede1 r5f70118 1 1 /* 2 * Copyright (c) 200 5 Ondrej Palkovsky2 * Copyright (c) 2009 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup amd6429 /** @addtogroup libc 30 30 * @{ 31 31 */ … … 33 33 */ 34 34 35 #ifndef KERN_amd64_ARG_H_36 #define KERN_amd64_ARG_H_35 #ifndef LIBC_CLIPBOARD_H_ 36 #define LIBC_CLIPBOARD_H_ 37 37 38 #include <stdarg.h> 38 extern int clipboard_put_str(const char *); 39 extern int clipboard_get_str(char **); 39 40 40 41 #endif … … 42 43 /** @} 43 44 */ 44 -
uspace/lib/libc/include/devmap.h
r309ede1 r5f70118 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/fcntl.h
r309ede1 r5f70118 43 43 #define O_RDWR 32 44 44 #define O_WRONLY 64 45 #define O_DESC 128 45 46 46 47 extern int open(const char *, int, ...); -
uspace/lib/libc/include/fibril_synch.h
r309ede1 r5f70118 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> … … 40 40 #include <adt/list.h> 41 41 #include <libarch/tls.h> 42 #include <sys/time.h> 42 43 43 44 typedef struct { … … 95 96 96 97 extern void fibril_condvar_initialize(fibril_condvar_t *); 98 extern int fibril_condvar_wait_timeout(fibril_condvar_t *, fibril_mutex_t *, 99 suseconds_t); 97 100 extern void fibril_condvar_wait(fibril_condvar_t *, fibril_mutex_t *); 98 101 extern void fibril_condvar_signal(fibril_condvar_t *); -
uspace/lib/libc/include/futex.h
r309ede1 r5f70118 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
r309ede1 r5f70118 68 68 extern void console_clear(int phone); 69 69 70 extern int console_get_size(int phone, ipcarg_t *rows, ipcarg_t *cols); 71 extern void console_goto(int phone, ipcarg_t row, ipcarg_t col); 70 extern int console_get_size(int phone, int *cols, int *rows); 71 extern int console_get_pos(int phone, int *col, int *row); 72 extern void console_goto(int phone, int col, int row); 72 73 73 74 extern void console_set_style(int phone, int style); -
uspace/lib/libc/include/ipc/bd.h
r309ede1 r5f70118 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
r309ede1 r5f70118 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
r309ede1 r5f70118 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/ipc.h
r309ede1 r5f70118 283 283 284 284 extern int ipc_share_in_start(int, void *, size_t, ipcarg_t, int *); 285 extern int ipc_share_in_receive(ipc_callid_t *, size_t *);286 285 extern int ipc_share_in_finalize(ipc_callid_t, void *, int ); 287 286 extern int ipc_share_out_start(int, void *, int); 288 extern int ipc_share_out_receive(ipc_callid_t *, size_t *, int *);289 287 extern int ipc_share_out_finalize(ipc_callid_t, void *); 290 288 extern int ipc_data_read_start(int, void *, size_t); 291 extern int ipc_data_read_receive(ipc_callid_t *, size_t *);292 289 extern int ipc_data_read_finalize(ipc_callid_t, const void *, size_t); 293 290 extern int ipc_data_write_start(int, const void *, size_t); 294 extern int ipc_data_write_receive(ipc_callid_t *, size_t *);295 291 extern int ipc_data_write_finalize(ipc_callid_t, void *, size_t); 296 292 -
uspace/lib/libc/include/ipc/loader.h
r309ede1 r5f70118 41 41 LOADER_HELLO = IPC_FIRST_USER_METHOD, 42 42 LOADER_GET_TASKID, 43 LOADER_SET_CWD, 43 44 LOADER_SET_PATHNAME, 44 45 LOADER_SET_ARGS, -
uspace/lib/libc/include/ipc/services.h
r309ede1 r5f70118 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
r309ede1 r5f70118 73 73 VFS_IN_UNLINK, 74 74 VFS_IN_RENAME, 75 VFS_IN_STAT 75 VFS_IN_STAT, 76 VFS_IN_DUP 76 77 } vfs_in_request_t; 77 78 -
uspace/lib/libc/include/loader/loader.h
r309ede1 r5f70118 49 49 extern loader_t *loader_connect(void); 50 50 extern int loader_get_task_id(loader_t *, task_id_t *); 51 extern int loader_set_cwd(loader_t *); 51 52 extern int loader_set_pathname(loader_t *, const char *); 52 53 extern int loader_set_args(loader_t *, char *const[]); -
uspace/lib/libc/include/loader/pcb.h
r309ede1 r5f70118 52 52 /** Program entry point. */ 53 53 entry_point_t entry; 54 55 /** Current working directory. */ 56 char *cwd; 54 57 55 58 /** Number of command-line arguments. */ -
uspace/lib/libc/include/malloc.h
r309ede1 r5f70118 42 42 43 43 extern void *malloc(const size_t size); 44 extern void *calloc(const size_t nmemb, const size_t size); 44 45 extern void *memalign(const size_t align, const size_t size); 45 46 extern void *realloc(const void *addr, const size_t size); -
uspace/lib/libc/include/stdarg.h
r309ede1 r5f70118 37 37 38 38 #include <sys/types.h> 39 #include <libarch/stackarg.h>40 41 #ifndef __VARARGS_DEFINED42 # define __VARARGS_DEFINED43 39 44 40 typedef __builtin_va_list va_list; 45 41 46 # define va_start(ap, last) __builtin_va_start(ap, last) 47 # define va_arg(ap, type) __builtin_va_arg(ap, type) 48 # define va_end(ap) __builtin_va_end(ap) 49 50 # endif 42 #define va_start(ap, last) __builtin_va_start(ap, last) 43 #define va_arg(ap, type) __builtin_va_arg(ap, type) 44 #define va_end(ap) __builtin_va_end(ap) 51 45 52 46 #endif -
uspace/lib/libc/include/stdlib.h
r309ede1 r5f70118 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 stack_trace(); \ 45 _exit(1); \ 46 } while (0) 47 42 48 #define exit(status) _exit((status)) 43 49 -
uspace/lib/libc/include/string.h
r309ede1 r5f70118 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
r309ede1 r5f70118 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
r309ede1 r5f70118 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/unistd.h
r309ede1 r5f70118 51 51 #endif 52 52 53 typedef uint32_t useconds_t; 54 55 extern int dup2(int oldfd, int newfd); 56 53 57 extern ssize_t write(int, const void *, size_t); 54 58 extern ssize_t read(int, void *, size_t); … … 66 70 67 71 extern void _exit(int status) __attribute__ ((noreturn)); 68 extern int usleep(u nsigned long usec);69 extern unsigned int sleep(unsigned int se conds);72 extern int usleep(useconds_t uses); 73 extern unsigned int sleep(unsigned int se); 70 74 71 75 #endif -
uspace/lib/libfs/Makefile
r309ede1 r5f70118 28 28 # 29 29 30 ## Common compiler flags 31 # 30 include Makefile.common 32 31 33 LIBC_PREFIX = ../libc 32 .PHONY: all clean 34 33 35 ## Setup toolchain 36 # 37 38 include $(LIBC_PREFIX)/Makefile.toolchain 39 40 CFLAGS += -Iinclude 41 42 ## Sources 43 # 44 45 SOURCES = \ 46 libfs.c 47 48 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 49 50 .PHONY: all clean depend 51 52 all: libfs.a 53 54 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBC_PREFIX)/libc.a 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build PRECHECK=$(PRECHECK) 55 37 56 38 clean: 57 -rm -f libfs.a Makefile.depend39 rm -f $(DEPEND) $(DEPEND_PREV) $(JOB) $(LIBFS) 58 40 find . -name '*.o' -follow -exec rm \{\} \; 59 60 depend:61 -makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null62 63 libfs.a: depend $(OBJECTS)64 $(AR) rc libfs.a $(OBJECTS)65 66 %.o: %.c67 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ -
uspace/lib/libfs/libfs.c
r309ede1 r5f70118 1 1 /* 2 * Copyright (c) 2009 Jakub Jermar 2 * Copyright (c) 2009 Jakub Jermar 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup libfs 29 /** @addtogroup libfs 30 30 * @{ 31 */ 31 */ 32 32 /** 33 33 * @file 34 * Glue code which is common od to all FS implementations.35 */ 36 37 #include "libfs.h" 34 * Glue code which is common to all FS implementations. 35 */ 36 37 #include "libfs.h" 38 38 #include "../../srv/vfs/vfs.h" 39 39 #include <errno.h> … … 46 46 #include <sys/stat.h> 47 47 48 #define on_error(rc, action) \ 49 do { \ 50 if ((rc) != EOK) \ 51 action; \ 52 } while (0) 53 54 #define combine_rc(rc1, rc2) \ 55 ((rc1) == EOK ? (rc2) : (rc1)) 56 57 #define answer_and_return(rid, rc) \ 58 do { \ 59 ipc_answer_0((rid), (rc)); \ 60 return; \ 61 } while (0) 62 48 63 /** Register file system server. 49 64 * … … 52 67 * code. 53 68 * 54 * @param vfs_phone Open phone for communication with VFS. 55 * @param reg File system registration structure. It will be 56 * initialized by this function. 57 * @param info VFS info structure supplied by the file system 58 * implementation. 59 * @param conn Connection fibril for handling all calls originating in 60 * VFS. 61 * 62 * @return EOK on success or a non-zero error code on errror. 69 * @param vfs_phone Open phone for communication with VFS. 70 * @param reg File system registration structure. It will be 71 * initialized by this function. 72 * @param info VFS info structure supplied by the file system 73 * implementation. 74 * @param conn Connection fibril for handling all calls originating in 75 * VFS. 76 * 77 * @return EOK on success or a non-zero error code on errror. 78 * 63 79 */ 64 80 int fs_register(int vfs_phone, fs_reg_t *reg, vfs_info_t *info, … … 72 88 ipc_call_t answer; 73 89 aid_t req = async_send_0(vfs_phone, VFS_IN_REGISTER, &answer); 74 90 75 91 /* 76 92 * Send our VFS info structure to VFS. 77 93 */ 78 int rc = ipc_data_write_start(vfs_phone, info, sizeof(*info));94 int rc = async_data_write_start(vfs_phone, info, sizeof(*info)); 79 95 if (rc != EOK) { 80 96 async_wait_for(req, NULL); 81 97 return rc; 82 98 } 83 99 84 100 /* 85 101 * Ask VFS for callback connection. 86 102 */ 87 103 ipc_connect_to_me(vfs_phone, 0, 0, 0, ®->vfs_phonehash); 88 104 89 105 /* 90 106 * Allocate piece of address space for PLB. … … 95 111 return ENOMEM; 96 112 } 97 113 98 114 /* 99 115 * Request sharing the Path Lookup Buffer with VFS. 100 116 */ 101 rc = ipc_share_in_start_0_0(vfs_phone, reg->plb_ro, PLB_SIZE);117 rc = async_share_in_start_0_0(vfs_phone, reg->plb_ro, PLB_SIZE); 102 118 if (rc) { 103 119 async_wait_for(req, NULL); … … 121 137 */ 122 138 async_set_client_connection(conn); 123 139 124 140 return IPC_GET_RETVAL(answer); 125 141 } … … 139 155 int res; 140 156 ipcarg_t rc; 141 157 142 158 ipc_call_t call; 143 159 ipc_callid_t callid; 144 145 /* accept the phone */160 161 /* Accept the phone */ 146 162 callid = async_get_call(&call); 147 163 int mountee_phone = (int)IPC_GET_ARG1(call); 148 164 if ((IPC_GET_METHOD(call) != IPC_M_CONNECTION_CLONE) || 149 mountee_phone < 0) {165 (mountee_phone < 0)) { 150 166 ipc_answer_0(callid, EINVAL); 151 167 ipc_answer_0(rid, EINVAL); 152 168 return; 153 169 } 154 ipc_answer_0(callid, EOK); /* acknowledge the mountee_phone */ 155 156 res = ipc_data_write_receive(&callid, NULL); 170 171 /* Acknowledge the mountee_phone */ 172 ipc_answer_0(callid, EOK); 173 174 res = async_data_write_receive(&callid, NULL); 157 175 if (!res) { 158 176 ipc_hangup(mountee_phone); … … 161 179 return; 162 180 } 163 164 fs_node_t *fn = ops->node_get(mp_dev_handle, mp_fs_index); 165 if (!fn) { 181 182 fs_node_t *fn; 183 res = ops->node_get(&fn, mp_dev_handle, mp_fs_index); 184 if ((res != EOK) || (!fn)) { 166 185 ipc_hangup(mountee_phone); 167 ipc_answer_0(callid, ENOENT);168 ipc_answer_0(rid, ENOENT);169 return; 170 } 171 186 ipc_answer_0(callid, combine_rc(res, ENOENT)); 187 ipc_answer_0(rid, combine_rc(res, ENOENT)); 188 return; 189 } 190 172 191 if (fn->mp_data.mp_active) { 173 192 ipc_hangup(mountee_phone); 174 ops->node_put(fn);193 (void) ops->node_put(fn); 175 194 ipc_answer_0(callid, EBUSY); 176 195 ipc_answer_0(rid, EBUSY); 177 196 return; 178 197 } 179 198 180 199 rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME); 181 if (rc != 0) {200 if (rc != EOK) { 182 201 ipc_hangup(mountee_phone); 183 ops->node_put(fn);202 (void) ops->node_put(fn); 184 203 ipc_answer_0(callid, rc); 185 204 ipc_answer_0(rid, rc); … … 199 218 fn->mp_data.phone = mountee_phone; 200 219 } 220 201 221 /* 202 222 * Do not release the FS node so that it stays in memory. … … 222 242 ipc_call_t *request) 223 243 { 224 unsigned first = IPC_GET_ARG1(*request);225 unsigned last = IPC_GET_ARG2(*request);226 unsigned next = first;244 unsigned int first = IPC_GET_ARG1(*request); 245 unsigned int last = IPC_GET_ARG2(*request); 246 unsigned int next = first; 227 247 dev_handle_t dev_handle = IPC_GET_ARG3(*request); 228 248 int lflag = IPC_GET_ARG4(*request); 229 fs_index_t index = IPC_GET_ARG5(*request); /* when L_LINK specified */249 fs_index_t index = IPC_GET_ARG5(*request); 230 250 char component[NAME_MAX + 1]; 231 251 int len; 232 252 int rc; 253 233 254 if (last < next) 234 255 last += PLB_SIZE; 235 256 236 257 fs_node_t *par = NULL; 237 fs_node_t *cur = ops->root_get(dev_handle);258 fs_node_t *cur = NULL; 238 259 fs_node_t *tmp = NULL; 239 260 261 rc = ops->root_get(&cur, dev_handle); 262 on_error(rc, goto out_with_answer); 263 240 264 if (cur->mp_data.mp_active) { 241 265 ipc_forward_slow(rid, cur->mp_data.phone, VFS_OUT_LOOKUP, 242 266 next, last, cur->mp_data.dev_handle, lflag, index, 243 267 IPC_FF_ROUTE_FROM_ME); 244 ops->node_put(cur); 245 return; 246 } 247 268 (void) ops->node_put(cur); 269 return; 270 } 271 272 /* Eat slash */ 248 273 if (ops->plb_get_char(next) == '/') 249 next++; /* eat slash */ 250 251 while (next <= last && ops->has_children(cur)) { 252 /* collect the component */ 274 next++; 275 276 while (next <= last) { 277 bool has_children; 278 279 rc = ops->has_children(&has_children, cur); 280 on_error(rc, goto out_with_answer); 281 if (!has_children) 282 break; 283 284 /* Collect the component */ 253 285 len = 0; 254 while ((next <= last) && (ops->plb_get_char(next) != '/')) {286 while ((next <= last) && (ops->plb_get_char(next) != '/')) { 255 287 if (len + 1 == NAME_MAX) { 256 /* component length overflow */288 /* Component length overflow */ 257 289 ipc_answer_0(rid, ENAMETOOLONG); 258 290 goto out; 259 291 } 260 292 component[len++] = ops->plb_get_char(next); 261 next++; /* process next character */ 293 /* Process next character */ 294 next++; 262 295 } 263 296 264 297 assert(len); 265 298 component[len] = '\0'; 266 next++; /* eat slash */ 267 268 /* match the component */ 269 tmp = ops->match(cur, component); 270 if (tmp && tmp->mp_data.mp_active) { 299 /* Eat slash */ 300 next++; 301 302 /* Match the component */ 303 rc = ops->match(&tmp, cur, component); 304 on_error(rc, goto out_with_answer); 305 306 if ((tmp) && (tmp->mp_data.mp_active)) { 271 307 if (next > last) 272 308 next = last = first; 273 309 else 274 310 next--; 275 311 276 312 ipc_forward_slow(rid, tmp->mp_data.phone, 277 313 VFS_OUT_LOOKUP, next, last, tmp->mp_data.dev_handle, 278 314 lflag, index, IPC_FF_ROUTE_FROM_ME); 279 ops->node_put(cur);280 ops->node_put(tmp);315 (void) ops->node_put(cur); 316 (void) ops->node_put(tmp); 281 317 if (par) 282 ops->node_put(par);318 (void) ops->node_put(par); 283 319 return; 284 320 } 285 286 /* handle miss: match amongst siblings */321 322 /* Handle miss: match amongst siblings */ 287 323 if (!tmp) { 288 324 if (next <= last) { 289 /* there are unprocessed components */325 /* There are unprocessed components */ 290 326 ipc_answer_0(rid, ENOENT); 291 327 goto out; 292 328 } 293 /* miss in the last component */ 294 if (lflag & (L_CREATE | L_LINK)) { 295 /* request to create a new link */ 329 330 /* Miss in the last component */ 331 if (lflag & (L_CREATE | L_LINK)) { 332 /* Request to create a new link */ 296 333 if (!ops->is_directory(cur)) { 297 334 ipc_answer_0(rid, ENOTDIR); 298 335 goto out; 299 336 } 337 300 338 fs_node_t *fn; 301 339 if (lflag & L_CREATE) 302 fn = ops->create(dev_handle, lflag); 340 rc = ops->create(&fn, dev_handle, 341 lflag); 303 342 else 304 fn = ops->node_get(dev_handle,343 rc = ops->node_get(&fn, dev_handle, 305 344 index); 345 on_error(rc, goto out_with_answer); 346 306 347 if (fn) { 307 int rc;308 309 348 rc = ops->link(cur, fn, component); 310 349 if (rc != EOK) { 311 if (lflag & L_CREATE) { 312 (void)ops->destroy(fn); 313 } 350 if (lflag & L_CREATE) 351 (void) ops->destroy(fn); 314 352 ipc_answer_0(rid, rc); 315 353 } else { … … 319 357 ops->size_get(fn), 320 358 ops->lnkcnt_get(fn)); 321 ops->node_put(fn);359 (void) ops->node_put(fn); 322 360 } 323 } else {361 } else 324 362 ipc_answer_0(rid, ENOSPC); 325 }363 326 364 goto out; 327 } 365 } 366 328 367 ipc_answer_0(rid, ENOENT); 329 368 goto out; 330 369 } 331 332 if (par) 333 ops->node_put(par); 334 335 /* descend one level */ 370 371 if (par) { 372 rc = ops->node_put(par); 373 on_error(rc, goto out_with_answer); 374 } 375 376 /* Descend one level */ 336 377 par = cur; 337 378 cur = tmp; 338 379 tmp = NULL; 339 380 } 340 341 /* handle miss: excessive components */ 342 if (next <= last && !ops->has_children(cur)) { 381 382 /* Handle miss: excessive components */ 383 if (next <= last) { 384 bool has_children; 385 rc = ops->has_children(&has_children, cur); 386 on_error(rc, goto out_with_answer); 387 388 if (has_children) 389 goto skip_miss; 390 343 391 if (lflag & (L_CREATE | L_LINK)) { 344 392 if (!ops->is_directory(cur)) { … … 346 394 goto out; 347 395 } 348 349 /* collect next component */396 397 /* Collect next component */ 350 398 len = 0; 351 399 while (next <= last) { 352 400 if (ops->plb_get_char(next) == '/') { 353 /* more than one component */401 /* More than one component */ 354 402 ipc_answer_0(rid, ENOENT); 355 403 goto out; 356 404 } 405 357 406 if (len + 1 == NAME_MAX) { 358 /* component length overflow */407 /* Component length overflow */ 359 408 ipc_answer_0(rid, ENAMETOOLONG); 360 409 goto out; 361 410 } 411 362 412 component[len++] = ops->plb_get_char(next); 363 next++; /* process next character */ 413 /* Process next character */ 414 next++; 364 415 } 416 365 417 assert(len); 366 418 component[len] = '\0'; 367 419 368 420 fs_node_t *fn; 369 421 if (lflag & L_CREATE) 370 fn = ops->create(dev_handle, lflag);422 rc = ops->create(&fn, dev_handle, lflag); 371 423 else 372 fn = ops->node_get(dev_handle, index); 424 rc = ops->node_get(&fn, dev_handle, index); 425 on_error(rc, goto out_with_answer); 426 373 427 if (fn) { 374 int rc;375 376 428 rc = ops->link(cur, fn, component); 377 429 if (rc != EOK) { 378 430 if (lflag & L_CREATE) 379 (void) ops->destroy(fn);431 (void) ops->destroy(fn); 380 432 ipc_answer_0(rid, rc); 381 433 } else { … … 385 437 ops->size_get(fn), 386 438 ops->lnkcnt_get(fn)); 387 ops->node_put(fn);439 (void) ops->node_put(fn); 388 440 } 389 } else {441 } else 390 442 ipc_answer_0(rid, ENOSPC); 391 }443 392 444 goto out; 393 445 } 446 394 447 ipc_answer_0(rid, ENOENT); 395 448 goto out; 396 449 } 397 398 /* handle hit */ 450 451 skip_miss: 452 453 /* Handle hit */ 399 454 if (lflag & L_UNLINK) { 400 unsigned old_lnkcnt = ops->lnkcnt_get(cur);401 int res= ops->unlink(par, cur, component);402 ipc_answer_5(rid, (ipcarg_t) res, fs_handle, dev_handle,455 unsigned int old_lnkcnt = ops->lnkcnt_get(cur); 456 rc = ops->unlink(par, cur, component); 457 ipc_answer_5(rid, (ipcarg_t) rc, fs_handle, dev_handle, 403 458 ops->index_get(cur), ops->size_get(cur), old_lnkcnt); 404 459 goto out; 405 460 } 461 406 462 if (((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) || 407 463 (lflag & L_LINK)) { … … 409 465 goto out; 410 466 } 467 411 468 if ((lflag & L_FILE) && (ops->is_directory(cur))) { 412 469 ipc_answer_0(rid, EISDIR); 413 470 goto out; 414 471 } 472 415 473 if ((lflag & L_DIRECTORY) && (ops->is_file(cur))) { 416 474 ipc_answer_0(rid, ENOTDIR); 417 475 goto out; 418 476 } 419 420 ipc_answer_5(rid, EOK, fs_handle, dev_handle, ops->index_get(cur), 421 ops->size_get(cur), ops->lnkcnt_get(cur)); 422 477 478 out_with_answer: 479 480 if (rc == EOK) { 481 if (lflag & L_OPEN) 482 rc = ops->node_open(cur); 483 484 ipc_answer_5(rid, rc, fs_handle, dev_handle, 485 ops->index_get(cur), ops->size_get(cur), 486 ops->lnkcnt_get(cur)); 487 } else 488 ipc_answer_0(rid, rc); 489 423 490 out: 491 424 492 if (par) 425 ops->node_put(par); 493 (void) ops->node_put(par); 494 426 495 if (cur) 427 ops->node_put(cur); 496 (void) ops->node_put(cur); 497 428 498 if (tmp) 429 ops->node_put(tmp);499 (void) ops->node_put(tmp); 430 500 } 431 501 … … 435 505 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 436 506 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 437 fs_node_t *fn = ops->node_get(dev_handle, index); 438 507 508 fs_node_t *fn; 509 int rc = ops->node_get(&fn, dev_handle, index); 510 on_error(rc, answer_and_return(rid, rc)); 511 439 512 ipc_callid_t callid; 440 513 size_t size; 441 if (!ipc_data_read_receive(&callid, &size) || 442 size != sizeof(struct stat)) { 514 if ((!async_data_read_receive(&callid, &size)) || 515 (size != sizeof(struct stat))) { 516 ops->node_put(fn); 443 517 ipc_answer_0(callid, EINVAL); 444 518 ipc_answer_0(rid, EINVAL); 445 519 return; 446 520 } 447 521 448 522 struct stat stat; 449 523 memset(&stat, 0, sizeof(struct stat)); … … 452 526 stat.dev_handle = dev_handle; 453 527 stat.index = index; 454 stat.lnkcnt = ops->lnkcnt_get(fn); 528 stat.lnkcnt = ops->lnkcnt_get(fn); 455 529 stat.is_file = ops->is_file(fn); 530 stat.is_directory = ops->is_directory(fn); 456 531 stat.size = ops->size_get(fn); 457 458 ipc_data_read_finalize(callid, &stat, sizeof(struct stat)); 532 stat.device = ops->device_get(fn); 533 534 ops->node_put(fn); 535 536 async_data_read_finalize(callid, &stat, sizeof(struct stat)); 459 537 ipc_answer_0(rid, EOK); 460 538 } … … 462 540 /** Open VFS triplet. 463 541 * 464 * @param ops libfs operations structure with function pointers to465 * file system implementation466 * @param rid Request ID of the VFS_OUT_OPEN_NODE request.467 * @param request VFS_OUT_OPEN_NODE request data itself.542 * @param ops libfs operations structure with function pointers to 543 * file system implementation 544 * @param rid Request ID of the VFS_OUT_OPEN_NODE request. 545 * @param request VFS_OUT_OPEN_NODE request data itself. 468 546 * 469 547 */ … … 473 551 dev_handle_t dev_handle = IPC_GET_ARG1(*request); 474 552 fs_index_t index = IPC_GET_ARG2(*request); 475 476 fs_node_t *node = ops->node_get(dev_handle, index); 477 478 if (node == NULL) { 553 fs_node_t *fn; 554 int rc; 555 556 rc = ops->node_get(&fn, dev_handle, index); 557 on_error(rc, answer_and_return(rid, rc)); 558 559 if (fn == NULL) { 479 560 ipc_answer_0(rid, ENOENT); 480 561 return; 481 562 } 482 563 483 ipc_answer_5(rid, EOK, fs_handle, dev_handle, index, 484 ops->size_get(node), ops->lnkcnt_get(node)); 485 486 ops->node_put(node); 564 rc = ops->node_open(fn); 565 ipc_answer_3(rid, rc, ops->size_get(fn), ops->lnkcnt_get(fn), 566 (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0)); 567 568 (void) ops->node_put(fn); 487 569 } 488 570 -
uspace/lib/libfs/libfs.h
r309ede1 r5f70118 56 56 57 57 typedef struct { 58 fs_node_t * (* match)(fs_node_t *, const char *); 59 fs_node_t * (* node_get)(dev_handle_t, fs_index_t); 60 void (* node_put)(fs_node_t *); 61 fs_node_t * (* create)(dev_handle_t, int); 58 /* 59 * The first set of methods are functions that return an integer error 60 * code. If some additional return value is to be returned, the first 61 * argument holds the output argument. 62 */ 63 int (* root_get)(fs_node_t **, dev_handle_t); 64 int (* match)(fs_node_t **, fs_node_t *, const char *); 65 int (* node_get)(fs_node_t **, dev_handle_t, fs_index_t); 66 int (* node_open)(fs_node_t *); 67 int (* node_put)(fs_node_t *); 68 int (* create)(fs_node_t **, dev_handle_t, int); 62 69 int (* destroy)(fs_node_t *); 63 70 int (* link)(fs_node_t *, fs_node_t *, const char *); 64 71 int (* unlink)(fs_node_t *, fs_node_t *, const char *); 72 int (* has_children)(bool *, fs_node_t *); 73 /* 74 * The second set of methods are usually mere getters that do not return 75 * an integer error code. 76 */ 65 77 fs_index_t (* index_get)(fs_node_t *); 66 78 size_t (* size_get)(fs_node_t *); 67 unsigned (* lnkcnt_get)(fs_node_t *); 68 bool (* has_children)(fs_node_t *); 69 fs_node_t *(* root_get)(dev_handle_t); 79 unsigned int (* lnkcnt_get)(fs_node_t *); 70 80 char (* plb_get_char)(unsigned pos); 71 81 bool (* is_directory)(fs_node_t *); 72 82 bool (* is_file)(fs_node_t *); 83 dev_handle_t (* device_get)(fs_node_t *); 73 84 } libfs_ops_t; 74 85 -
uspace/lib/softfloat/Makefile
r309ede1 r5f70118 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 ## Common compiler flags 30 # 30 include Makefile.common 31 31 32 LIBC_PREFIX = ../libc 32 .PHONY: all clean 33 33 34 ## Setup toolchain 35 # 36 37 include $(LIBC_PREFIX)/Makefile.toolchain 38 39 CFLAGS += -Iinclude -Iarch/$(UARCH)/include/ 40 41 ## Sources 42 # 43 44 GENERIC_SOURCES = \ 45 generic/add.c \ 46 generic/common.c \ 47 generic/comparison.c \ 48 generic/conversion.c \ 49 generic/div.c \ 50 generic/mul.c \ 51 generic/other.c \ 52 generic/softfloat.c \ 53 generic/sub.c 54 55 ARCH_SOURCES = 56 57 GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) 58 59 .PHONY: all clean depend 60 61 all: libsoftfloat.a 62 63 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBC_PREFIX)/libc.a 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build PRECHECK=$(PRECHECK) 64 37 65 38 clean: 66 -rm -f libsoftfloat.a Makefile.depend 67 find generic/ -name '*.o' -follow -exec rm \{\} \; 68 69 depend: 70 -makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null 71 72 libsoftfloat.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS) 73 $(AR) rc libsoftfloat.a $(ARCH_OBJECTS) $(GENERIC_OBJECTS) 74 75 %.o: %.S 76 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 77 78 %.o: %.s 79 $(AS) $(AFLAGS) $< -o $@ 80 81 %.o: %.c 82 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(JOB) $(LIBSOFTFLOAT) 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/lib/softfloat/Makefile.build
r309ede1 r5f70118 1 1 # 2 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 30 31 # 31 32 32 LIBC_PREFIX = ../../lib/libc 33 SOFTINT_PREFIX = ../../lib/softint 34 33 include Makefile.common 35 34 include $(LIBC_PREFIX)/Makefile.toolchain 36 35 37 38 LIBS = libpci/libpci.a $(LIBC_PREFIX)/libc.a 36 CFLAGS += -Iinclude -Iarch/$(UARCH)/include/ 39 37 40 38 ## Sources 41 39 # 42 40 43 OUTPUT = pci44 41 SOURCES = \ 45 pci.c 42 generic/add.c \ 43 generic/common.c \ 44 generic/comparison.c \ 45 generic/conversion.c \ 46 generic/div.c \ 47 generic/mul.c \ 48 generic/other.c \ 49 generic/softfloat.c \ 50 generic/sub.c 46 51 47 52 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 48 53 49 .PHONY: all clean depend disasm54 .PHONY: all 50 55 51 all: $( OUTPUT) disasm56 all: $(LIBSOFTFLOAT) 52 57 53 -include Makefile.depend58 -include $(DEPEND) 54 59 55 clean: 56 -rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) 57 $(MAKE) -C libpci clean 60 $(LIBSOFTFLOAT): $(OBJECTS) 61 $(AR) rc $@ $(OBJECTS) 58 62 59 depend: 60 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 63 %.o: %.c $(DEPEND) 64 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 65 ifeq ($(PRECHECK),y) 66 $(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(CFLAGS) 67 endif 61 68 62 $(OUTPUT): $(OBJECTS) $(LIBS) 63 $(MAKE) -C libpci 64 $(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map 65 66 disasm: 67 $(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm 68 69 %.o: %.S 70 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 71 72 %.o: %.s 73 $(AS) $(AFLAGS) $< -o $@ 74 75 %.o: %.c 76 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 77 78 libpci/libpci.a: 79 $(MAKE) -C libpci 69 $(DEPEND): 70 makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null 71 -[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@ -
uspace/lib/softint/Makefile
r309ede1 r5f70118 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 ## Common compiler flags 30 # 30 include Makefile.common 31 31 32 LIBC_PREFIX = ../libc 32 .PHONY: all clean 33 33 34 ## Setup toolchain 35 # 36 37 include $(LIBC_PREFIX)/Makefile.toolchain 38 39 CFLAGS += -Iinclude 40 41 ## Sources 42 # 43 44 ARCH_SOURCES = 45 46 GENERIC_SOURCES = \ 47 generic/division.c 48 49 GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) 50 51 .PHONY: all clean depend 52 53 all: libsoftint.a 54 55 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBC_PREFIX)/libc.a 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build PRECHECK=$(PRECHECK) 56 37 57 38 clean: 58 -rm -f libsoftint.a Makefile.depend 59 find generic/ -name '*.o' -follow -exec rm \{\} \; 60 61 depend: 62 -makedepend -f - -- $(DEPEMD_DEFS) $(CFLAGS) -- $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null 63 64 libsoftint.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS) 65 $(AR) rc libsoftint.a $(ARCH_OBJECTS) $(GENERIC_OBJECTS) 66 67 %.o: %.S 68 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 69 70 %.o: %.s 71 $(AS) $(AFLAGS) $< -o $@ 72 73 %.o: %.c 74 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(JOB) $(LIBSOFTINT) 40 find . -name '*.o' -follow -exec rm \{\} \;
Note:
See TracChangeset
for help on using the changeset viewer.
