Changeset 5f70118 in mainline for uspace/lib


Ignore:
Timestamp:
2010-01-10T12:16:59Z (16 years ago)
Author:
Jiri Svoboda <jiri@…>
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.
Message:

Merge mainline changes.

Location:
uspace/lib
Files:
26 added
1 deleted
82 edited
4 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/libblock/Makefile

    r309ede1 r5f70118  
    2828#
    2929
    30 ## Common compiler flags
    31 #
     30include Makefile.common
    3231
    33 LIBC_PREFIX = ../libc
     32.PHONY: all clean
    3433
    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
     34all: $(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)
    5537
    5638clean:
    57         -rm -f libblock.a Makefile.depend
     39        rm -f $(DEPEND) $(DEPEND_PREV) $(JOB) $(LIBBLOCK)
    5840        find . -name '*.o' -follow -exec rm \{\} \;
    59 
    60 depend:
    61         -makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null
    62 
    63 libblock.a: depend $(OBJECTS)
    64         $(AR) rc libblock.a $(OBJECTS)
    65 
    66 %.o: %.c
    67         $(CC) $(DEFS) $(CFLAGS) -c $< -o $@
  • uspace/lib/libblock/libblock.c

    r309ede1 r5f70118  
    4747#include <as.h>
    4848#include <assert.h>
    49 #include <fibril_sync.h>
     49#include <fibril_synch.h>
    5050#include <adt/list.h>
    5151#include <adt/hash_table.h>
     
    8787static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt);
    8888static int get_block_size(int dev_phone, size_t *bsize);
     89static int get_num_blocks(int dev_phone, bn_t *nblocks);
    8990
    9091static devcon_t *devcon_search(dev_handle_t dev_handle)
     
    168169        }
    169170
    170         rc = ipc_share_out_start(dev_phone, comm_area,
     171        rc = async_share_out_start(dev_phone, comm_area,
    171172            AS_AREA_READ | AS_AREA_WRITE);
    172173        if (rc != EOK) {
     
    714715
    715716        memcpy(devcon->comm_area, data, devcon->pblock_size * cnt);
    716         rc = read_blocks(devcon, ba, cnt);
     717        rc = write_blocks(devcon, ba, cnt);
    717718
    718719        fibril_mutex_unlock(&devcon->comm_area_lock);
     
    736737       
    737738        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 */
     748int 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);
    738756}
    739757
     
    789807}
    790808
     809/** Get total number of blocks on block device. */
     810static 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
    791823/** @}
    792824 */
  • uspace/lib/libblock/libblock.h

    r309ede1 r5f70118  
    3636
    3737#ifndef LIBBLOCK_LIBBLOCK_H_
    38 #define LIBBLOCK_LIBBLOCK_H_
     38#define LIBBLOCK_LIBBLOCK_H_
    3939
    4040#include <stdint.h>
    4141#include "../../srv/vfs/vfs.h"
    42 #include <fibril_sync.h>
     42#include <fibril_synch.h>
    4343#include <adt/hash_table.h>
    4444#include <adt/list.h>
     
    5959 */
    6060#define BLOCK_FLAGS_NOREAD      1
    61 
    62 typedef uint64_t bn_t;  /**< Block number type. */
    6361
    6462typedef struct block {
     
    110108
    111109extern int block_get_bsize(dev_handle_t, size_t *);
     110extern int block_get_nblocks(dev_handle_t, bn_t *);
    112111extern int block_read_direct(dev_handle_t, bn_t, size_t, void *);
    113112extern int block_write_direct(dev_handle_t, bn_t, size_t, const void *);
  • uspace/lib/libc/Makefile

    r309ede1 r5f70118  
    2727#
    2828
    29 ## Common compiler flags
    30 #
     29include Makefile.common
    3130
    32 LIBC_PREFIX = $(shell pwd)
    33 SOFTINT_PREFIX = ../softint
     31.PHONY: all clean
    3432
    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
     33all: ../../../Makefile.config ../../../config.h ../../../config.defs
     34        -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
     35        $(MAKE) -f Makefile.build PRECHECK=$(PRECHECK)
    10636
    10737clean:
    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  
    2727#
    2828
    29 CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \
     29GCC_CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \
    3030        -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
     35ICC_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
     41CLANG_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
    3448LFLAGS = -M -N $(SOFTINT_PREFIX)/libsoftint.a
    3549AFLAGS =
     
    4559#
    4660
    47 -include $(LIBC_PREFIX)/../../../Makefile.config
    48 -include $(LIBC_PREFIX)/../../../config.defs
    49 -include $(LIBC_PREFIX)/arch/$(UARCH)/Makefile.inc
     61include $(LIBC_PREFIX)/../../../Makefile.config
     62include $(LIBC_PREFIX)/../../../config.defs
     63include $(LIBC_PREFIX)/arch/$(UARCH)/Makefile.inc
    5064
    5165## Simple detection of the host system
     
    6478#
    6579
     80JOBFILE = $(LIBC_PREFIX)/../../../tools/jobfile.py
     81
     82ifeq ($(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)
     92endif
     93
    6694ifeq ($(COMPILER),gcc_native)
    6795        CC = gcc
     96        GCC = $(CC)
    6897        AS = $(BINUTILS_PREFIX)as
    6998        LD = $(BINUTILS_PREFIX)ld
     
    71100        OBJCOPY = $(BINUTILS_PREFIX)objcopy
    72101        OBJDUMP = $(BINUTILS_PREFIX)objdump
     102        CFLAGS = $(GCC_CFLAGS)
    73103        DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
    74104endif
    75105
    76 ifeq ($(COMPILER),icc_native)
     106ifeq ($(COMPILER),icc)
    77107        CC = icc
     108        GCC = gcc
    78109        AS = as
    79110        LD = ld
     
    81112        OBJCOPY = objcopy
    82113        OBJDUMP = objdump
     114        CFLAGS = $(ICC_CFLAGS)
    83115        DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
    84116endif
    85117
    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
     118ifeq ($(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)
    93127        DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
    94128endif
  • uspace/lib/libc/arch/amd64/Makefile.inc

    r309ede1 r5f70118  
    3131
    3232TARGET = amd64-linux-gnu
     33CLANG_ARCH = x86_64
    3334TOOLCHAIN_DIR = $(CROSS_PREFIX)/amd64/bin
    3435
    3536ARCH_SOURCES += arch/$(UARCH)/src/syscall.S \
    3637        arch/$(UARCH)/src/fibril.S \
    37         arch/$(UARCH)/src/tls.c
     38        arch/$(UARCH)/src/tls.c \
     39        arch/$(UARCH)/src/stacktrace.S
    3840
     41GCC_CFLAGS += -fno-omit-frame-pointer
    3942LFLAGS += -N
    4043
  • uspace/lib/libc/arch/amd64/include/atomic.h

    r309ede1 r5f70118  
    3737#ifndef LIBC_amd64_ATOMIC_H_
    3838#define LIBC_amd64_ATOMIC_H_
     39
     40#define LIBC_ARCH_ATOMIC_H_
     41
     42#include <atomicdflt.h>
    3943
    4044static inline void atomic_inc(atomic_t *val) {
  • uspace/lib/libc/arch/amd64/include/fibril.h

    r309ede1 r5f70118  
    4444#define SP_DELTA     16
    4545
     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
    4654/* We include only registers that must be preserved
    4755 * during function call
  • uspace/lib/libc/arch/amd64/src/entry.s

    r309ede1 r5f70118  
    3838#
    3939__entry:
     40        #
     41        # Create the first stack frame.
     42        #
     43        pushq $0
     44        mov %rsp, %rbp
     45       
    4046        # %rdi was deliberately chosen as the first argument is also in %rdi
    4147        # Pass PCB pointer to __main (no operation)
  • uspace/lib/libc/arch/amd64/src/thread_entry.s

    r309ede1 r5f70118  
    3636__thread_entry:
    3737        #
     38        # Create the first stack frame.
     39        #
     40        pushq $0
     41        movq %rsp, %rbp
     42
     43        #
    3844        # RAX contains address of uarg
    3945        #
  • uspace/lib/libc/arch/arm32/Makefile.inc

    r309ede1 r5f70118  
    3737        arch/$(UARCH)/src/fibril.S \
    3838        arch/$(UARCH)/src/tls.c \
    39         arch/$(UARCH)/src/eabi.S
     39        arch/$(UARCH)/src/eabi.S \
     40        arch/$(UARCH)/src/stacktrace.S
    4041
    41 CFLAGS += -ffixed-r9 -mtp=soft
     42GCC_CFLAGS += -ffixed-r9 -mtp=soft -mapcs-frame -fno-omit-frame-pointer
    4243LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a
    4344
  • uspace/lib/libc/arch/arm32/include/atomic.h

    r309ede1 r5f70118  
    3737#define LIBC_arm32_ATOMIC_H_
    3838
     39#define LIBC_ARCH_ATOMIC_H_
     40#define CAS
     41
     42#include <atomicdflt.h>
     43#include <bool.h>
     44#include <sys/types.h>
     45
     46extern uintptr_t *ras_page;
     47
     48static 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
    3985/** Atomic addition.
    4086 *
     
    4692static inline long atomic_add(atomic_t *val, int i)
    4793{
    48         int ret;
    49         volatile long * mem = &(val->count);
     94        long ret = 0;
    5095
     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         */
    51101        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        );
    59117
    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;
    64121
    65122        return ret;
  • uspace/lib/libc/arch/arm32/include/fibril.h

    r309ede1 r5f70118  
    5858 *  @param ptls  Pointer to the TCB.
    5959 */
    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)
    6567
    6668/** Fibril context.
     
    7981        uint32_t r7;
    8082        uint32_t r8;
    81         uint32_t tls;
     83        uint32_t tls;   /* r9 */
    8284        uint32_t r10;
    83         uint32_t r11;
     85        uint32_t fp;    /* r11 */
    8486} context_t;
    8587
  • uspace/lib/libc/arch/arm32/src/entry.s

    r309ede1 r5f70118  
    3636#
    3737# r1 contains the PCB pointer
     38# r2 contains the RAS page address
    3839#
    3940__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
    4053        # Pass pcb_ptr to __main as the first argument (in r0)
    4154        mov r0, r1
     
    4356
    4457        bl __exit
     58
     59.data
     60
     61.global ras_page
     62ras_page:
     63        .long 0
     64
  • uspace/lib/libc/arch/arm32/src/syscall.c

    r309ede1 r5f70118  
    6060        register sysarg_t __arm_reg_r5 asm("r5") = p6;
    6161        register sysarg_t __arm_reg_r6 asm("r6") = id;
    62 
    63         asm volatile ( "swi"
     62       
     63        asm volatile (
     64                "swi 0"
    6465                : "=r" (__arm_reg_r0)
    6566                : "r" (__arm_reg_r0),
     
    7172                  "r" (__arm_reg_r6)
    7273        );
    73 
     74       
    7475        return __arm_reg_r0;
    7576}
  • uspace/lib/libc/arch/arm32/src/thread_entry.s

    r309ede1 r5f70118  
    3535#
    3636__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
    3745        b __thread_main
  • uspace/lib/libc/arch/ia32/Makefile.inc

    r309ede1 r5f70118  
    3131
    3232TARGET = i686-pc-linux-gnu
     33CLANG_ARCH = i386
    3334TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia32/bin
    3435
     
    3637        arch/$(UARCH)/src/fibril.S \
    3738        arch/$(UARCH)/src/tls.c \
    38         arch/$(UARCH)/src/setjmp.S
     39        arch/$(UARCH)/src/setjmp.S \
     40        arch/$(UARCH)/src/stacktrace.S
    3941
     42GCC_CFLAGS += -march=pentium
    4043LFLAGS += -N
    4144
  • uspace/lib/libc/arch/ia32/_link.ld.in

    r309ede1 r5f70118  
    33
    44PHDRS {
    5         text PT_LOAD FLAGS(5);
     5        text PT_LOAD FLAGS(5);
    66        data PT_LOAD FLAGS(6);
    77}
     
    99SECTIONS {
    1010        . = 0x1000 + SIZEOF_HEADERS;
    11 
     11       
    1212        .init : {
    1313                *(.init);
    1414        } :text
     15       
    1516        .text : {
    1617                *(.text);
    17                 *(.rodata*);
     18                *(.rodata*);
    1819        } :text
    19 
     20       
    2021        . = . + 0x1000;
    21 
     22       
    2223        .data : {
    2324                *(.data);
    2425        } :data
     26       
    2527        .tdata : {
    2628                _tdata_start = .;
    2729                *(.tdata);
     30                *(.gnu.linkonce.tb.*);
    2831                _tdata_end = .;
    2932                _tbss_start = .;
     
    3134                _tbss_end = .;
    3235        } :data
     36       
    3337        _tls_alignment = ALIGNOF(.tdata);
     38       
    3439        .bss : {
    35                 *(COMMON);
    36                 *(.bss);
     40                *(COMMON);
     41                *(.bss);
    3742        } :data
    3843       
    3944        . = ALIGN(0x1000);
     45       
    4046        _heap = .;
    4147       
     
    4349                *(*);
    4450        }
    45 
    4651}
  • uspace/lib/libc/arch/ia32/include/atomic.h

    r309ede1 r5f70118  
    3535#ifndef LIBC_ia32_ATOMIC_H_
    3636#define LIBC_ia32_ATOMIC_H_
     37
     38#define LIBC_ARCH_ATOMIC_H_
     39
     40#include <atomicdflt.h>
    3741
    3842static inline void atomic_inc(atomic_t *val) {
  • uspace/lib/libc/arch/ia32/include/fibril.h

    r309ede1 r5f70118  
    4444#define SP_DELTA     (12)
    4545
     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       
    4654/* We include only registers that must be preserved
    4755 * during function call
  • uspace/lib/libc/arch/ia32/include/syscall.h

    r309ede1 r5f70118  
    4040#include <kernel/syscall/syscall.h>
    4141
    42 #define __syscall0      __syscall_sysenter
    43 #define __syscall1      __syscall_sysenter
    44 #define __syscall2      __syscall_sysenter
    45 #define __syscall3      __syscall_sysenter
    46 #define __syscall4      __syscall_sysenter
    47 #define __syscall5      __syscall_int
    48 #define __syscall6      __syscall_int
     42#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
    4949
    5050extern 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);
    5353
    5454extern 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);
    5757
    5858#endif
  • uspace/lib/libc/arch/ia32/src/entry.s

    r309ede1 r5f70118  
    2727#
    2828
     29INTEL_CPUID_STANDARD = 1
     30INTEL_SEP = 11
     31
    2932.section .init, "ax"
    3033
     
    3538## User-space task entry point
    3639#
    37 # %ebx contains the PCB pointer
     40# %edi contains the PCB pointer
    3841#
    3942__entry:
     
    4447        # Do not set %gs, it contains descriptor that can see TLS
    4548
     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)
     560:
     57        #
     58        # Create the first stack frame.
     59        #
     60        pushl $0
     61        movl %esp, %ebp
     62
    4663        # Pass the PCB pointer to __main as the first argument
    47         pushl %ebx
     64        pushl %edi
    4865        call __main
    4966
  • uspace/lib/libc/arch/ia32/src/syscall.S

    r309ede1 r5f70118  
    2727#
    2828
     29.data
     30
     31.global __syscall_fast_func
     32__syscall_fast_func:
     33        .long __syscall_slow
     34
    2935.text
    3036
     
    3541 * could benefit from this and not save unused registers on the stack.
    3642 */
    37 .global __syscall_int
    38 __syscall_int:
     43.global __syscall_slow
     44__syscall_slow:
    3945        pushl %ebx
    4046        pushl %esi
     
    6470 * segment, otherwise the SYSENTER wouldn't work in the first place).
    6571 */
    66 .global __syscall_sysenter
    67 __syscall_sysenter:
     72.global __syscall_fast
     73__syscall_fast:
    6874        pushl %ebx
    6975        pushl %esi
  • uspace/lib/libc/arch/ia32/src/thread_entry.s

    r309ede1 r5f70118  
    4242
    4343        #
     44        # Create the first stack frame.
     45        #
     46        pushl $0
     47        mov %esp, %ebp
     48
     49        #
    4450        # EAX contains address of uarg.
    4551        #
  • uspace/lib/libc/arch/ia64/Makefile.inc

    r309ede1 r5f70118  
    3636        arch/$(UARCH)/src/fibril.S \
    3737        arch/$(UARCH)/src/tls.c \
    38         arch/$(UARCH)/src/ddi.c
     38        arch/$(UARCH)/src/ddi.c \
     39        arch/$(UARCH)/src/stacktrace.S
    3940
    40 CFLAGS += -fno-unwind-tables
     41GCC_CFLAGS += -fno-unwind-tables
    4142LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a
    4243
  • uspace/lib/libc/arch/ia64/include/atomic.h

    r309ede1 r5f70118  
    3535#ifndef LIBC_ia64_ATOMIC_H_
    3636#define LIBC_ia64_ATOMIC_H_
     37
     38#define LIBC_ARCH_ATOMIC_H_
     39
     40#include <atomicdflt.h>
    3741
    3842static inline void atomic_inc(atomic_t *val)
  • uspace/lib/libc/arch/mips32/Makefile.inc

    r309ede1 r5f70118  
    3535ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \
    3636        arch/$(UARCH)/src/fibril.S \
    37         arch/$(UARCH)/src/tls.c
     37        arch/$(UARCH)/src/tls.c \
     38        arch/$(UARCH)/src/stacktrace.S
    3839
    39 CFLAGS += -mips3
     40GCC_CFLAGS += -mips3
    4041
    4142ENDIANESS = LE
  • uspace/lib/libc/arch/mips32/include/atomic.h

    r309ede1 r5f70118  
    3636#ifndef LIBC_mips32_ATOMIC_H_
    3737#define LIBC_mips32_ATOMIC_H_
     38
     39#define LIBC_ARCH_ATOMIC_H_
     40
     41#include <atomicdflt.h>
    3842
    3943#define atomic_inc(x)   ((void) atomic_add(x, 1))
  • uspace/lib/libc/arch/mips32eb/Makefile.inc

    r309ede1 r5f70118  
    3434
    3535ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \
    36                 arch/$(UARCH)/src/fibril.S \
    37                 arch/$(UARCH)/src/tls.c
     36        arch/$(UARCH)/src/fibril.S \
     37        arch/$(UARCH)/src/tls.c
    3838
    39 CFLAGS += -mips3
     39GCC_CFLAGS += -mips3
    4040LFLAGS += -N
    4141
  • uspace/lib/libc/arch/ppc32/Makefile.inc

    r309ede1 r5f70118  
    3535ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \
    3636        arch/$(UARCH)/src/fibril.S \
    37         arch/$(UARCH)/src/tls.c
     37        arch/$(UARCH)/src/tls.c \
     38        arch/$(UARCH)/src/stacktrace.S
    3839
    39 CFLAGS += -mcpu=powerpc -msoft-float -m32
     40GCC_CFLAGS += -mcpu=powerpc -msoft-float -m32
    4041AFLAGS += -a32
    4142LFLAGS += -N
  • uspace/lib/libc/arch/ppc32/include/atomic.h

    r309ede1 r5f70118  
    3535#ifndef LIBC_ppc32_ATOMIC_H_
    3636#define LIBC_ppc32_ATOMIC_H_
     37
     38#define LIBC_ARCH_ATOMIC_H_
     39
     40#include <atomicdflt.h>
    3741
    3842static inline void atomic_inc(atomic_t *val)
  • uspace/lib/libc/arch/ppc32/src/entry.s

    r309ede1 r5f70118  
    3838#
    3939__entry:
     40        #
     41        # Create the first stack frame.
     42        #
     43        li %r3, 0
     44        stw %r3, 0(%r1)
     45        stwu %r1, -16(%r1)
     46
    4047        # Pass the PCB pointer to __main() as the first argument.
    4148        # The first argument is passed in r3.
  • uspace/lib/libc/arch/ppc32/src/thread_entry.s

    r309ede1 r5f70118  
    3535#
    3636__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
    3744        b __thread_main
    3845
  • uspace/lib/libc/arch/sparc64/Makefile.inc

    r309ede1 r5f70118  
    3434
    3535ARCH_SOURCES += arch/$(UARCH)/src/fibril.S \
    36         arch/$(UARCH)/src/tls.c
     36        arch/$(UARCH)/src/tls.c \
     37        arch/$(UARCH)/src/stacktrace.S
    3738
    38 CFLAGS += -mcpu=ultrasparc -m64
     39GCC_CFLAGS += -mcpu=ultrasparc -m64
    3940LFLAGS += -no-check-sections -N
    4041
  • uspace/lib/libc/arch/sparc64/include/atomic.h

    r309ede1 r5f70118  
    3636#define LIBC_sparc64_ATOMIC_H_
    3737
     38#define LIBC_ARCH_ATOMIC_H_
     39
     40#include <atomicdflt.h>
    3841#include <sys/types.h>
    3942
  • uspace/lib/libc/arch/sparc64/include/fibril.h

    r309ede1 r5f70118  
    4646#endif
    4747
    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)
    5456       
    5557/*
  • uspace/lib/libc/arch/sparc64/src/entry.s

    r309ede1 r5f70118  
    3939#
    4040__entry:
     41        #
     42        # Create the first stack frame.
     43        #
     44        save %sp, -176, %sp
     45        flushw
     46        add %g0, -0x7ff, %fp
     47
    4148        # Pass pcb_ptr as the first argument to __main()
    42         mov %o1, %o0
     49        mov %i1, %o0
    4350        sethi %hi(_gp), %l7
    4451        call __main
  • uspace/lib/libc/arch/sparc64/src/fibril.S

    r309ede1 r5f70118  
    3535
    3636context_save:
     37        #
     38        # We rely on the kernel to flush our active register windows to memory
     39        # should a thread switch occur.
     40        #
    3741        CONTEXT_SAVE_ARCH_CORE %o0
    3842        retl
     
    4246        #
    4347        # 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        #
    4952        flushw
    5053       
  • uspace/lib/libc/arch/sparc64/src/thread_entry.s

    r309ede1 r5f70118  
    3535#
    3636__thread_entry:
     37        #
     38        # Create the first stack frame.
     39        #
     40        save %sp, -176, %sp
     41        flushw
     42        add %g0, -0x7ff, %fp
     43
    3744        sethi %hi(_gp), %l7
    3845        call __thread_main              ! %o0 contains address of uarg
  • uspace/lib/libc/generic/async.c

    r309ede1 r5f70118  
    8383 *
    8484 *     callid = async_get_call(&call);
    85  *     handle_call(callid, call);
     85 *     somehow_handle_the_call(callid, call);
    8686 *     ipc_answer_2(callid, 1, 2, 3);
    8787 *
     
    9494#include <futex.h>
    9595#include <async.h>
     96#include <async_priv.h>
    9697#include <fibril.h>
    9798#include <stdio.h>
     
    110111atomic_t threads_in_ipc_wait = { 0 };
    111112
    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 
    133113typedef struct {
    134114        awaiter_t wdata;
     
    253233 *
    254234 */
    255 static void insert_timeout(awaiter_t *wd)
    256 {
    257         wd->timedout = false;
    258         wd->inlist = true;
     235void async_insert_timeout(awaiter_t *wd)
     236{
     237        wd->to_event.occurred = false;
     238        wd->to_event.inlist = true;
    259239       
    260240        link_t *tmp = timeout_list.next;
    261241        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))
    265246                        break;
    266                
    267247                tmp = tmp->next;
    268248        }
    269249       
    270         list_append(&wd->link, tmp);
     250        list_append(&wd->to_event.link, tmp);
    271251}
    272252
     
    315295               
    316296                /* 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);
    320300                }
    321301               
     
    405385       
    406386        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);
    409389        } else
    410                 conn->wdata.inlist = false;
     390                conn->wdata.to_event.inlist = false;
    411391       
    412392        /* If nothing in queue, wait until something arrives */
    413393        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
    414408                if (usecs)
    415                         insert_timeout(&conn->wdata);
     409                        async_insert_timeout(&conn->wdata);
    416410               
    417411                conn->wdata.active = false;
     
    430424                 */
    431425                futex_down(&async_futex);
    432                 if ((usecs) && (conn->wdata.timedout)
     426                if ((usecs) && (conn->wdata.to_event.occurred)
    433427                    && (list_empty(&conn->msg_queue))) {
    434428                        /* If we timed out -> exit */
     
    548542        list_initialize(&conn->msg_queue);
    549543        conn->callid = callid;
    550         conn->close_callid = false;
     544        conn->close_callid = 0;
    551545       
    552546        if (call)
     
    625619        link_t *cur = timeout_list.next;
    626620        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))
    630625                        break;
    631                
     626
    632627                cur = cur->next;
    633                
    634                 list_remove(&waiter->link);
    635                 waiter->inlist = false;
    636                 waiter->timedout = true;
     628
     629                list_remove(&waiter->to_event.link);
     630                waiter->to_event.inlist = false;
     631                waiter->to_event.occurred = true;
    637632               
    638633                /*
     
    671666                if (!list_empty(&timeout_list)) {
    672667                        awaiter_t *waiter = list_get_instance(timeout_list.next,
    673                             awaiter_t, link);
     668                            awaiter_t, to_event.link);
    674669                       
    675670                        struct timeval tv;
    676671                        gettimeofday(&tv, NULL);
    677672                       
    678                         if (tv_gteq(&tv, &waiter->expires)) {
     673                        if (tv_gteq(&tv, &waiter->to_event.expires)) {
    679674                                futex_up(&async_futex);
    680675                                handle_expired_timeouts();
    681676                                continue;
    682677                        } else
    683                                 timeout = tv_sub(&waiter->expires, &tv);
     678                                timeout = tv_sub(&waiter->to_event.expires,
     679                                    &tv);
    684680                } else
    685681                        timeout = SYNCH_NO_TIMEOUT;
     
    782778       
    783779        /* 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);
    786782       
    787783        msg->done = true;
     
    822818        msg->dataptr = dataptr;
    823819       
    824         msg->wdata.inlist = false;
     820        msg->wdata.to_event.inlist = false;
    825821        /* We may sleep in the next method, but it will use its own mechanism */
    826822        msg->wdata.active = true;
     
    862858        msg->dataptr = dataptr;
    863859       
    864         msg->wdata.inlist = false;
     860        msg->wdata.to_event.inlist = false;
    865861        /* We may sleep in next method, but it will use its own mechanism */
    866862        msg->wdata.active = true;
     
    891887        msg->wdata.fid = fibril_get_id();
    892888        msg->wdata.active = false;
    893         msg->wdata.inlist = false;
     889        msg->wdata.to_event.inlist = false;
    894890       
    895891        /* Leave the async_futex locked when entering this function */
     
    929925        }
    930926       
    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);
    933929       
    934930        msg->wdata.fid = fibril_get_id();
    935931        msg->wdata.active = false;
    936         insert_timeout(&msg->wdata);
     932        async_insert_timeout(&msg->wdata);
    937933       
    938934        /* Leave the async_futex locked when entering this function */
     
    970966        msg->wdata.active = false;
    971967       
    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);
    974970       
    975971        futex_down(&async_futex);
    976972       
    977         insert_timeout(&msg->wdata);
     973        async_insert_timeout(&msg->wdata);
    978974       
    979975        /* Leave the async_futex locked when entering this function */
     
    11051101}
    11061102
     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 */
     1114int 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 */
     1139int 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 */
     1164int 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 */
     1177int 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 */
     1198int 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 */
     1224int 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 */
     1238int 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 */
     1258int 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 */
     1284int 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 */
     1297int 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 */
     1317int 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 */
     1342int 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 */
     1362int 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 */
     1409int 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
    11071440/** @}
    11081441 */
  • uspace/lib/libc/generic/devmap.c

    r309ede1 r5f70118  
    3535#include <async.h>
    3636#include <errno.h>
     37#include <malloc.h>
     38#include <bool.h>
    3739
    3840static int devmap_phone_driver = -1;
     
    105107        aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
    106108       
    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));
    109110        if (retval != EOK) {
    110111                async_wait_for(req, NULL);
     
    126127/** Register new device.
    127128 *
    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.
    130132 *
    131133 */
    132 int devmap_device_register(const char *name, dev_handle_t *handle)
     134int devmap_device_register(const char *fqdn, dev_handle_t *handle)
    133135{
    134136        int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
     
    143145            &answer);
    144146       
    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));
    147148        if (retval != EOK) {
    148149                async_wait_for(req, NULL);
     
    167168}
    168169
    169 int devmap_device_get_handle(const char *name, dev_handle_t *handle, unsigned int flags)
     170int devmap_device_get_handle(const char *fqdn, dev_handle_t *handle, unsigned int flags)
    170171{
    171172        int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
     
    180181            &answer);
    181182       
    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));
    184184        if (retval != EOK) {
    185185                async_wait_for(req, NULL);
     
    202202       
    203203        return retval;
     204}
     205
     206int 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
     242devmap_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;
    204255}
    205256
     
    227278       
    228279        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);
    230281        if (retval != EOK)
    231282                return -1;
     
    241292                return;
    242293       
    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
     297static size_t devmap_count_namespaces_internal(int phone)
     298{
    253299        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);
    255301        if (retval != EOK)
    256302                return 0;
     
    259305}
    260306
    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        
     307static 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);
    285311        if (retval != EOK)
    286312                return 0;
    287313       
    288         return IPC_GET_ARG1(answer);
    289 }
     314        return count;
     315}
     316
     317size_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
     327size_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
     337size_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
     389size_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  
    3333 */
    3434
    35 #include <fibril_sync.h>
     35#include <fibril_synch.h>
    3636#include <fibril.h>
    3737#include <async.h>
     38#include <async_priv.h>
    3839#include <adt/list.h>
    3940#include <futex.h>
     41#include <sys/time.h>
     42#include <errno.h>
    4043#include <assert.h>
    4144
     
    6366        futex_down(&async_futex);
    6467        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);
    6775                fibril_switch(FIBRIL_TO_MANAGER);
    6876        } else {
     
    9098        if (fm->counter++ < 0) {
    9199                link_t *tmp;
    92                 fibril_t *f;
     100                awaiter_t *wdp;
    93101       
    94102                assert(!list_empty(&fm->waiters));
    95103                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);
    99109                optimize_execution_power();
    100110        }
     
    120130        if (frw->writers) {
    121131                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);
    122138                f->flags &= ~FIBRIL_WRITER;
    123                 list_append(&f->link, &frw->waiters);
     139                list_append(&wdata.wu_event.link, &frw->waiters);
    124140                fibril_switch(FIBRIL_TO_MANAGER);
    125141        } else {
     
    134150        if (frw->writers || frw->readers) {
    135151                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);
    136158                f->flags |= FIBRIL_WRITER;
    137                 list_append(&f->link, &frw->waiters);
     159                list_append(&wdata.wu_event.link, &frw->waiters);
    138160                fibril_switch(FIBRIL_TO_MANAGER);
    139161        } else {
     
    158180        while (!list_empty(&frw->waiters)) {
    159181                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;
    161187               
    162188                if (f->flags & FIBRIL_WRITER) {
    163189                        if (frw->readers)
    164190                                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);
    167195                        frw->writers++;
    168196                        optimize_execution_power();
    169197                        break;
    170198                } 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);
    173203                        frw->readers++;
    174204                        optimize_execution_power();
     
    194224}
    195225
    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);
     226int
     227fibril_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);
    202252        _fibril_mutex_unlock_unsafe(fm);
    203253        fibril_switch(FIBRIL_TO_MANAGER);
    204254        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
     267void 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);
    205273}
    206274
     
    208276{
    209277        link_t *tmp;
    210         fibril_t *f;
     278        awaiter_t *wdp;
    211279
    212280        futex_down(&async_futex);
    213281        while (!list_empty(&fcv->waiters)) {
    214282                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                }
    221293        }
    222294        futex_up(&async_futex);
  • uspace/lib/libc/generic/futex.c

    r309ede1 r5f70118  
    3636#include <atomic.h>
    3737#include <libc.h>
    38 #include <stdio.h>
    3938#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 the
    45  * 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 == -1
    51  *    (ie. thread A sleeping, thread B in the critical section)
    52  * 2. A receives timeout and gets removed from the wait queue
    53  * 3. B wants to leave the critical section and calls futex_up()
    54  * 4. B thus changes futex->count from -1 to 0
    55  * 5. B has to call SYS_FUTEX_WAKEUP syscall to wake up the sleeping thread
    56  * 6. B finds the wait queue empty and changes wq->missed_wakeups from 0 to 1
    57  * 7. A fixes futex->count (i.e. the number of waiting threads) by changing it
    58  *    from 0 to 1
    59  *
    60  * Scenario 2 (conditional down operation vs. futex_up)
    61  * 1. assume wq->missed_wakeups == 0 && futex->count == 0
    62  *    (i.e. thread A is in the critical section)
    63  * 2. thread B performs futex_trydown() operation and changes futex->count from
    64  *    0 to -1
    65  *    B is now obliged to call SYS_FUTEX_SLEEP syscall
    66  * 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_WAKEUP
    68  *    syscall
    69  * 5. B finds the wait queue empty and immediatelly aborts the conditional sleep
    70  * 6. No thread is queueing in the wait queue so wq->missed_wakeups changes from
    71  *    0 to 1
    72  * 6. B fixes futex->count (i.e. the number of waiting threads) by changing it
    73  *    from 0 to 1
    74  *
    75  * Both scenarios allow two threads to be in the critical section
    76  * simultaneously. One without kernel intervention and the other through
    77  * wq->missed_wakeups being 1.
    78  *
    79  * To mitigate this problem, futex_down_timeout() detects that the syscall
    80  * didn't sleep in the wait queue, fixes the futex counter and RETRIES the
    81  * whole operation again.
    82  */
    8339
    8440/** Initialize futex counter.
     
    9248}
    9349
    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 
    10550/** Try to down the futex.
    10651 *
    10752 * @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 */
     56int futex_trydown(futex_t *futex)
     57{
     58        return cas(futex, 1, 0);
     59}
     60
     61/** Down the futex.
    11262 *
    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.
    11867 */
    119 int futex_down_timeout(futex_t *futex, uint32_t usec, int flags)
     68int futex_down(futex_t *futex)
    12069{
    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);
    13772
    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;
    17174}
    17275
     
    17477 *
    17578 * @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.
    17981 */
    18082int futex_up(futex_t *futex)
    18183{
    182         long val;
    183        
    184         val = atomic_postinc(futex);
    185         if (val < 0)
     84        if (atomic_postinc(futex) < 0)
    18685                return __SYSCALL1(SYS_FUTEX_WAKEUP, (sysarg_t) &futex->count);
    18786               
  • uspace/lib/libc/generic/io/console.c

    r309ede1 r5f70118  
    4545}
    4646
    47 int console_get_size(int phone, ipcarg_t *rows, ipcarg_t *cols)
     47int console_get_size(int phone, int *cols, int *rows)
    4848{
    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;
    5058}
    5159
     
    8694}
    8795
    88 void console_goto(int phone, ipcarg_t row, ipcarg_t col)
     96int console_get_pos(int phone, int *col, int *row)
    8997{
    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
     109void console_goto(int phone, int col, int row)
     110{
     111        async_msg_2(phone, CONSOLE_GOTO, col, row);
    91112}
    92113
  • uspace/lib/libc/generic/io/io.c

    r309ede1 r5f70118  
    341341size_t fread(void *buf, size_t size, size_t nmemb, FILE *stream)
    342342{
    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
    346348        /* Make sure no data is pending write. */
    347349        _fflushbuf(stream);
     350
     351        left = size * nmemb;
     352        done = 0;
    348353       
    349354        while ((left > 0) && (!stream->error) && (!stream->eof)) {
     
    365370static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
    366371{
    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
    370381        while ((left > 0) && (!stream->error)) {
    371382                ssize_t wr;
     
    421432        uint8_t b;
    422433        bool need_flush;
    423        
     434
     435        if (size == 0 || nmemb == 0)
     436                return 0;
     437
    424438        /* If not buffered stream, write out directly. */
    425439        if (stream->btype == _IONBF) {
     
    480494       
    481495        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);
    483497               
    484498                if (wr < sz)
     
    540554}
    541555
     556int 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
    542567void rewind(FILE *stream)
    543568{
  • uspace/lib/libc/generic/io/klog.c

    r309ede1 r5f70118  
    4242size_t klog_write(const void *buf, size_t size)
    4343{
    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;
    4550}
    4651
  • uspace/lib/libc/generic/ipc.c

    r309ede1 r5f70118  
    730730        int res;
    731731        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,
    733733            (ipcarg_t) size, arg, NULL, &tmp_flags);
    734734        if (flags)
     
    737737}
    738738
    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 calls
    742  * 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 will
    747  *                      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 
    766739/** Wrapper for answering the IPC_M_SHARE_IN calls.
    767740 *
     
    790763int ipc_share_out_start(int phoneid, void *src, int flags)
    791764{
    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,
    793766            (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 calls
    799  * 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 will
    804  *                      be stored.
    805  * @param size          Storage where the source address space area size will be
    806  *                      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;
    825767}
    826768
     
    851793int ipc_data_read_start(int phoneid, void *dst, size_t size)
    852794{
    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,
    854796            (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 calls
    860  * 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 will
    865  *                      be stored.
    866  * @param size          Storage where the maximum size will be stored. Can be
    867  *                      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;
    883797}
    884798
     
    910824int ipc_data_write_start(int phoneid, const void *src, size_t size)
    911825{
    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,
    913827            (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 calls
    919  * 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 will
    924  *                      be stored.
    925  * @param size          Storage where the suggested size will be stored. May be
    926  *                      NULL
    927  *
    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;
    942828}
    943829
  • uspace/lib/libc/generic/libc.c

    r309ede1 r5f70118  
    8383                argv = __pcb->argv;
    8484                __stdio_init(__pcb->filc, __pcb->filv);
     85                (void) chdir(__pcb->cwd);
    8586        }
    8687       
  • uspace/lib/libc/generic/loader.c

    r309ede1 r5f70118  
    9090        ipc_call_t answer;
    9191        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 */
     112int 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);
    93128        if (rc != EOK) {
    94129                async_wait_for(req, NULL);
     
    123158        ipc_call_t answer;
    124159        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);
    126161        if (rc != EOK) {
    127162                async_wait_for(req, NULL);
     
    178213        ipc_call_t answer;
    179214        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);
    181216        if (rc != EOK) {
    182217                async_wait_for(req, NULL);
     
    232267        ipc_call_t answer;
    233268        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,
    235270            count * sizeof(fdi_node_t));
    236271        if (rc != EOK) {
  • uspace/lib/libc/generic/malloc.c

    r309ede1 r5f70118  
    353353}
    354354
     355void *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
    355365void *malloc(const size_t size)
    356366{
  • uspace/lib/libc/generic/string.c

    r309ede1 r5f70118  
    471471 * null-terminated and containing only complete characters.
    472472 *
    473  * @param dst   Destination buffer.
     473 * @param dest   Destination buffer.
    474474 * @param count Size of the destination buffer (must be > 0).
    475475 * @param src   Source string.
     
    505505 * have to be null-terminated.
    506506 *
    507  * @param dst   Destination buffer.
     507 * @param dest   Destination buffer.
    508508 * @param count Size of the destination buffer (must be > 0).
    509509 * @param src   Source string.
     
    537537 * null-terminated and containing only complete characters.
    538538 *
    539  * @param dst   Destination buffer.
     539 * @param dest   Destination buffer.
    540540 * @param count Size of the destination buffer.
    541541 * @param src   Source string.
     
    549549}
    550550
    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 */
     561void wstr_to_str(char *dest, size_t size, const wchar_t *src)
     562{
    570563        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
    574573        while ((ch = src[src_idx++]) != 0) {
    575                 if (chr_encode(ch, dst, &dst_off, size) != EOK)
     574                if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
    576575                        break;
    577576        }
    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 */
     589char *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 */
     640void 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';
    583660}
    584661
     
    819896}
    820897
     898char *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
     909char *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
    821925
    822926/** Convert initial part of string to unsigned long according to given base.
     
    843947}
    844948
    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 
    856949char *strtok(char *s, const char *delim)
    857950{
  • uspace/lib/libc/generic/task.c

    r309ede1 r5f70118  
    8989                goto error;
    9090       
     91        /* Send spawner's current working directory. */
     92        rc = loader_set_cwd(ldr);
     93        if (rc != EOK)
     94                goto error;
     95       
    9196        /* Send program pathname. */
    9297        rc = loader_set_pathname(ldr, path);
     
    98103        if (rc != EOK)
    99104                goto error;
    100        
    101105       
    102106        /* Send default files */
  • uspace/lib/libc/generic/time.c

    r309ede1 r5f70118  
    3131 */
    3232/** @file
    33  */ 
     33 */
    3434
    3535#include <sys/time.h>
     
    4040#include <unistd.h>
    4141#include <atomic.h>
    42 #include <futex.h>
    4342#include <sysinfo.h>
    4443#include <ipc/services.h>
     44#include <libc.h>
    4545
    4646#include <sysinfo.h>
     
    189189
    190190/** 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);
     191int usleep(useconds_t usec)
     192{
     193        (void) __SYSCALL1(SYS_THREAD_USLEEP, usec);
    197194        return 0;
    198195}
    199196
    200197/** 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        
     198unsigned int sleep(unsigned int sec)
     199{
    207200        /* Sleep in 1000 second steps to support
    208201           full argument range */
    209         while (seconds > 0) {
    210                 unsigned int period = (seconds > 1000) ? 1000 : seconds;
     202        while (sec > 0) {
     203                unsigned int period = (sec > 1000) ? 1000 : sec;
    211204       
    212                 futex_down_timeout(&futex, period * 1000000, 0);
    213                 seconds -= period;
     205                usleep(period * 1000000);
     206                sec -= period;
    214207        }
    215208        return 0;
  • uspace/lib/libc/generic/vfs/canonify.c

    r309ede1 r5f70118  
    142142        t->start[-1] = '\0';
    143143}
    144 /** Eat the extra '/'..
     144/** Eat the extra '/'.
    145145 *
    146146 * @param t             The current TK_SLASH token.
     
    288288 *
    289289 * 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)
    295301 *
    296302 * This function makes a potentially non-canonical file system path canonical.
  • uspace/lib/libc/generic/vfs/vfs.c

    r309ede1 r5f70118  
    5757static futex_t cwd_futex = FUTEX_INITIALIZER;
    5858
    59 DIR *cwd_dir = NULL;
    60 char *cwd_path = NULL;
    61 size_t cwd_size = 0;
     59static int cwd_fd = -1;
     60static char *cwd_path = NULL;
     61static size_t cwd_size = 0;
    6262
    6363char *absolutize(const char *path, size_t *retlen)
     
    117117}
    118118
    119 int mount(const char *fs_name, const char *mp, const char *dev,
     119int mount(const char *fs_name, const char *mp, const char *fqdn,
    120120    const char *opts, unsigned int flags)
    121121{
     
    126126        dev_handle_t dev_handle;
    127127       
    128         res = devmap_device_get_handle(dev, &dev_handle, flags);
     128        res = devmap_device_get_handle(fqdn, &dev_handle, flags);
    129129        if (res != EOK)
    130130                return res;
     
    140140       
    141141        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);
    143143        if (rc != EOK) {
    144144                async_wait_for(req, &rc_orig);
     
    152152        }
    153153       
    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));
    155155        if (rc != EOK) {
    156156                async_wait_for(req, &rc_orig);
     
    164164        }
    165165
    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));
    167167        if (rc != EOK) {
    168168                async_wait_for(req, &rc_orig);
     
    197197}
    198198
    199 static int _open(const char *path, int lflag, int oflag, ...)
    200 {
    201         ipcarg_t rc;
     199static 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       
    202205        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       
    216209        if (rc != EOK) {
    217210                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         free(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);
    232225       
    233226        if (rc != EOK)
     
    239232int open(const char *path, int oflag, ...)
    240233{
    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;
    242243}
    243244
     
    290291       
    291292        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);
    293294        if (rc != EOK) {
    294295                ipcarg_t rc_orig;
     
    322323       
    323324        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);
    325326        if (rc != EOK) {
    326327                ipcarg_t rc_orig;
     
    402403       
    403404        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));
    405406        if (rc != EOK) {
    406407                ipcarg_t rc_orig;
     
    437438       
    438439        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);
    440441        if (rc != EOK) {
    441442                async_wait_for(req, &rc_orig);
     
    448449                        return (int) rc_orig;
    449450        }
    450         rc = ipc_data_read_start(vfs_phone, stat, sizeof(struct stat));
     451        rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
    451452        if (rc != EOK) {
    452453                async_wait_for(req, &rc_orig);
     
    471472        if (!dirp)
    472473                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) {
    475486                free(dirp);
    476487                return NULL;
    477488        }
     489       
     490        dirp->fd = ret;
    478491        return dirp;
    479492}
     
    514527       
    515528        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);
    517530        if (rc != EOK) {
    518531                ipcarg_t rc_orig;
     
    549562       
    550563        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);
    552565        if (rc != EOK) {
    553566                ipcarg_t rc_orig;
     
    602615       
    603616        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);
    605618        if (rc != EOK) {
    606619                async_wait_for(req, &rc_orig);
     
    614627                        return (int) rc_orig;
    615628        }
    616         rc = ipc_data_write_start(vfs_phone, newa, newa_size);
     629        rc = async_data_write_start(vfs_phone, newa, newa_size);
    617630        if (rc != EOK) {
    618631                async_wait_for(req, &rc_orig);
     
    636649int chdir(const char *path)
    637650{
    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);
    646660                return ENOENT;
    647661        }
    648 
     662       
    649663        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       
    660676        futex_up(&cwd_futex);
    661677        return EOK;
     
    664680char *getcwd(char *buf, size_t size)
    665681{
    666         if (!size)
     682        if (size == 0)
    667683                return NULL;
     684       
    668685        futex_down(&cwd_futex);
    669         if (size < cwd_size + 1) {
     686       
     687        if ((cwd_size == 0) || (size < cwd_size + 1)) {
    670688                futex_up(&cwd_futex);
    671689                return NULL;
    672690        }
     691       
    673692        str_cpy(buf, size, cwd_path);
    674693        futex_up(&cwd_futex);
     694       
    675695        return buf;
    676696}
     
    683703        rc = fstat(fildes, &stat);
    684704
    685         if (!stat.devfs_stat.device)
     705        if (!stat.device)
    686706                return -1;
    687707       
    688         return devmap_device_connect(stat.devfs_stat.device, 0);
     708        return devmap_device_connect(stat.device, 0);
    689709}
    690710
     
    705725}
    706726
     727int 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
    707745/** @}
    708746 */
  • uspace/lib/libc/include/assert.h

    r309ede1 r5f70118  
    5151
    5252#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)
    5461#else
    5562#       define assert(expr)
  • uspace/lib/libc/include/async.h

    r309ede1 r5f70118  
    259259}
    260260
     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
     273extern int async_share_in_start(int, void *, size_t, ipcarg_t, int *);
     274extern int async_share_in_receive(ipc_callid_t *, size_t *);
     275extern int async_share_in_finalize(ipc_callid_t, void *, int );
     276extern int async_share_out_start(int, void *, int);
     277extern int async_share_out_receive(ipc_callid_t *, size_t *, int *);
     278extern int async_share_out_finalize(ipc_callid_t, void *);
     279extern int async_data_read_start(int, void *, size_t);
     280extern int async_data_read_receive(ipc_callid_t *, size_t *);
     281extern int async_data_read_finalize(ipc_callid_t, const void *, size_t);
     282extern int async_data_write_start(int, const void *, size_t);
     283extern int async_data_write_receive(ipc_callid_t *, size_t *);
     284extern int async_data_write_finalize(ipc_callid_t, void *, size_t);
     285
     286extern int async_data_blob_receive(char **, const size_t, size_t *);
     287extern int async_data_string_receive(char **, const size_t);
     288
    261289#endif
    262290
  • uspace/lib/libc/include/atomic.h

    r309ede1 r5f70118  
    11/*
    2  * Copyright (c) 2006 Jakub Jermar
     2 * Copyright (c) 2009 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    3636#define LIBC_ATOMIC_H_
    3737
    38 typedef struct atomic {
    39         volatile long count;
    40 } atomic_t;
    41 
    4238#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 }
    5339
    5440#endif
  • uspace/lib/libc/include/clipboard.h

    r309ede1 r5f70118  
    11/*
    2  * Copyright (c) 2005 Ondrej Palkovsky
     2 * Copyright (c) 2009 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup amd64   
     29/** @addtogroup libc
    3030 * @{
    3131 */
     
    3333 */
    3434
    35 #ifndef KERN_amd64_ARG_H_
    36 #define KERN_amd64_ARG_H_
     35#ifndef LIBC_CLIPBOARD_H_
     36#define LIBC_CLIPBOARD_H_
    3737
    38 #include <stdarg.h>
     38extern int clipboard_put_str(const char *);
     39extern int clipboard_get_str(char **);
    3940
    4041#endif
     
    4243/** @}
    4344 */
    44 
  • uspace/lib/libc/include/devmap.h

    r309ede1 r5f70118  
    3838#include <ipc/devmap.h>
    3939#include <async.h>
     40#include <bool.h>
    4041
    4142extern int devmap_get_phone(devmap_interface_t, unsigned int);
     
    4647
    4748extern int devmap_device_get_handle(const char *, dev_handle_t *, unsigned int);
     49extern int devmap_namespace_get_handle(const char *, dev_handle_t *, unsigned int);
     50extern devmap_handle_type_t devmap_handle_probe(dev_handle_t);
     51
    4852extern int devmap_device_connect(dev_handle_t, unsigned int);
    4953
     
    5155extern void devmap_null_destroy(int);
    5256
    53 extern ipcarg_t devmap_device_get_count(void);
    54 extern ipcarg_t devmap_device_get_devices(ipcarg_t, dev_desc_t *);
     57extern size_t devmap_count_namespaces(void);
     58extern size_t devmap_count_devices(dev_handle_t);
     59
     60extern size_t devmap_get_namespaces(dev_desc_t **);
     61extern size_t devmap_get_devices(dev_handle_t, dev_desc_t **);
    5562
    5663#endif
  • uspace/lib/libc/include/fcntl.h

    r309ede1 r5f70118  
    4343#define O_RDWR    32
    4444#define O_WRONLY  64
     45#define O_DESC    128
    4546
    4647extern int open(const char *, int, ...);
  • uspace/lib/libc/include/fibril_synch.h

    r309ede1 r5f70118  
    3333 */
    3434
    35 #ifndef LIBC_FIBRIL_SYNC_H_
    36 #define LIBC_FIBRIL_SYNC_H_
     35#ifndef LIBC_FIBRIL_SYNCH_H_
     36#define LIBC_FIBRIL_SYNCH_H_
    3737
    3838#include <async.h>
     
    4040#include <adt/list.h>
    4141#include <libarch/tls.h>
     42#include <sys/time.h>
    4243
    4344typedef struct {
     
    9596
    9697extern void fibril_condvar_initialize(fibril_condvar_t *);
     98extern int fibril_condvar_wait_timeout(fibril_condvar_t *, fibril_mutex_t *,
     99    suseconds_t);
    97100extern void fibril_condvar_wait(fibril_condvar_t *, fibril_mutex_t *);
    98101extern void fibril_condvar_signal(fibril_condvar_t *);
  • uspace/lib/libc/include/futex.h

    r309ede1 r5f70118  
    4646extern int futex_down(futex_t *futex);
    4747extern int futex_trydown(futex_t *futex);
    48 extern int futex_down_timeout(futex_t *futex, uint32_t usec, int flags);
    4948extern int futex_up(futex_t *futex);
    5049
  • uspace/lib/libc/include/io/console.h

    r309ede1 r5f70118  
    6868extern void console_clear(int phone);
    6969
    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);
     70extern int console_get_size(int phone, int *cols, int *rows);
     71extern int console_get_pos(int phone, int *col, int *row);
     72extern void console_goto(int phone, int col, int row);
    7273
    7374extern void console_set_style(int phone, int style);
  • uspace/lib/libc/include/ipc/bd.h

    r309ede1 r5f70118  
    4040typedef enum {
    4141        BD_GET_BLOCK_SIZE = IPC_FIRST_USER_METHOD,
     42        BD_GET_NUM_BLOCKS,
    4243        BD_READ_BLOCKS,
    4344        BD_WRITE_BLOCKS
  • uspace/lib/libc/include/ipc/console.h

    r309ede1 r5f70118  
    4343        CONSOLE_GET_COLOR_CAP,
    4444        CONSOLE_GET_EVENT,
     45        CONSOLE_GET_POS,
    4546        CONSOLE_GOTO,
    4647        CONSOLE_CLEAR,
  • uspace/lib/libc/include/ipc/devmap.h

    r309ede1 r5f70118  
    4343
    4444typedef enum {
     45        DEV_HANDLE_NONE,
     46        DEV_HANDLE_NAMESPACE,
     47        DEV_HANDLE_DEVICE
     48} devmap_handle_type_t;
     49
     50typedef enum {
    4551        DEVMAP_DRIVER_REGISTER = IPC_FIRST_USER_METHOD,
    4652        DEVMAP_DRIVER_UNREGISTER,
    4753        DEVMAP_DEVICE_REGISTER,
    4854        DEVMAP_DEVICE_UNREGISTER,
    49         DEVMAP_DEVICE_GET_NAME,
    5055        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
    5564} devmap_request_t;
    5665
  • uspace/lib/libc/include/ipc/ipc.h

    r309ede1 r5f70118  
    283283
    284284extern int ipc_share_in_start(int, void *, size_t, ipcarg_t, int *);
    285 extern int ipc_share_in_receive(ipc_callid_t *, size_t *);
    286285extern int ipc_share_in_finalize(ipc_callid_t, void *, int );
    287286extern int ipc_share_out_start(int, void *, int);
    288 extern int ipc_share_out_receive(ipc_callid_t *, size_t *, int *);
    289287extern int ipc_share_out_finalize(ipc_callid_t, void *);
    290288extern int ipc_data_read_start(int, void *, size_t);
    291 extern int ipc_data_read_receive(ipc_callid_t *, size_t *);
    292289extern int ipc_data_read_finalize(ipc_callid_t, const void *, size_t);
    293290extern int ipc_data_write_start(int, const void *, size_t);
    294 extern int ipc_data_write_receive(ipc_callid_t *, size_t *);
    295291extern int ipc_data_write_finalize(ipc_callid_t, void *, size_t);
    296292
  • uspace/lib/libc/include/ipc/loader.h

    r309ede1 r5f70118  
    4141        LOADER_HELLO = IPC_FIRST_USER_METHOD,
    4242        LOADER_GET_TASKID,
     43        LOADER_SET_CWD,
    4344        LOADER_SET_PATHNAME,
    4445        LOADER_SET_ARGS,
  • uspace/lib/libc/include/ipc/services.h

    r309ede1 r5f70118  
    4141        SERVICE_LOAD = 1,
    4242        SERVICE_PCI,
    43         SERVICE_KEYBOARD,
    4443        SERVICE_VIDEO,
    4544        SERVICE_CONSOLE,
     
    4746        SERVICE_DEVMAP,
    4847        SERVICE_FHC,
    49         SERVICE_OBIO
     48        SERVICE_OBIO,
     49        SERVICE_CLIPBOARD
    5050} services_t;
    5151
  • uspace/lib/libc/include/ipc/vfs.h

    r309ede1 r5f70118  
    7373        VFS_IN_UNLINK,
    7474        VFS_IN_RENAME,
    75         VFS_IN_STAT
     75        VFS_IN_STAT,
     76        VFS_IN_DUP
    7677} vfs_in_request_t;
    7778
  • uspace/lib/libc/include/loader/loader.h

    r309ede1 r5f70118  
    4949extern loader_t *loader_connect(void);
    5050extern int loader_get_task_id(loader_t *, task_id_t *);
     51extern int loader_set_cwd(loader_t *);
    5152extern int loader_set_pathname(loader_t *, const char *);
    5253extern int loader_set_args(loader_t *, char *const[]);
  • uspace/lib/libc/include/loader/pcb.h

    r309ede1 r5f70118  
    5252        /** Program entry point. */
    5353        entry_point_t entry;
     54
     55        /** Current working directory. */
     56        char *cwd;
    5457       
    5558        /** Number of command-line arguments. */
  • uspace/lib/libc/include/malloc.h

    r309ede1 r5f70118  
    4242
    4343extern void *malloc(const size_t size);
     44extern void *calloc(const size_t nmemb, const size_t size);
    4445extern void *memalign(const size_t align, const size_t size);
    4546extern void *realloc(const void *addr, const size_t size);
  • uspace/lib/libc/include/stdarg.h

    r309ede1 r5f70118  
    3737
    3838#include <sys/types.h>
    39 #include <libarch/stackarg.h>
    40 
    41 #ifndef __VARARGS_DEFINED
    42 # define __VARARGS_DEFINED
    4339
    4440typedef __builtin_va_list va_list;
    4541
    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)
    5145
    5246#endif
  • uspace/lib/libc/include/stdlib.h

    r309ede1 r5f70118  
    3838#include <unistd.h>
    3939#include <malloc.h>
     40#include <stacktrace.h>
    4041
    41 #define abort()       _exit(1)
     42#define abort() \
     43        do { \
     44                stack_trace(); \
     45                _exit(1); \
     46        } while (0)
     47
    4248#define exit(status)  _exit((status))
    4349
  • uspace/lib/libc/include/string.h

    r309ede1 r5f70118  
    7373extern void str_append(char *dest, size_t size, const char *src);
    7474
    75 extern void wstr_nstr(char *dst, const wchar_t *src, size_t size);
     75extern void wstr_to_str(char *dest, size_t size, const wchar_t *src);
     76extern char *wstr_to_astr(const wchar_t *src);
     77extern void str_to_wstr(wchar_t *dest, size_t dlen, const char *src);
    7678
    7779extern char *str_chr(const char *str, wchar_t ch);
     
    8284
    8385extern char *str_dup(const char *);
     86extern char *str_ndup(const char *, size_t max_size);
    8487
    8588/*
  • uspace/lib/libc/include/sys/stat.h

    r309ede1 r5f70118  
    4242
    4343struct 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;
    5552};
    5653
  • uspace/lib/libc/include/sys/types.h

    r309ede1 r5f70118  
    4040typedef long off_t;
    4141typedef int mode_t;
     42typedef uint64_t bn_t;  /**< Block number type. */
    4243
    4344typedef int32_t wchar_t;
  • uspace/lib/libc/include/unistd.h

    r309ede1 r5f70118  
    5151#endif
    5252
     53typedef uint32_t useconds_t;
     54
     55extern int dup2(int oldfd, int newfd);
     56
    5357extern ssize_t write(int, const void *, size_t);
    5458extern ssize_t read(int, void *, size_t);
     
    6670
    6771extern void _exit(int status) __attribute__ ((noreturn));
    68 extern int usleep(unsigned long usec);
    69 extern unsigned int sleep(unsigned int seconds);
     72extern int usleep(useconds_t uses);
     73extern unsigned int sleep(unsigned int se);
    7074
    7175#endif
  • uspace/lib/libfs/Makefile

    r309ede1 r5f70118  
    2828#
    2929
    30 ## Common compiler flags
    31 #
     30include Makefile.common
    3231
    33 LIBC_PREFIX = ../libc
     32.PHONY: all clean
    3433
    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
     34all: $(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)
    5537
    5638clean:
    57         -rm -f libfs.a Makefile.depend
     39        rm -f $(DEPEND) $(DEPEND_PREV) $(JOB) $(LIBFS)
    5840        find . -name '*.o' -follow -exec rm \{\} \;
    59 
    60 depend:
    61         -makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null
    62 
    63 libfs.a: depend $(OBJECTS)
    64         $(AR) rc libfs.a $(OBJECTS)
    65 
    66 %.o: %.c
    67         $(CC) $(DEFS) $(CFLAGS) -c $< -o $@
  • uspace/lib/libfs/libfs.c

    r309ede1 r5f70118  
    11/*
    2  * Copyright (c) 2009 Jakub Jermar 
     2 * Copyright (c) 2009 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libfs 
     29/** @addtogroup libfs
    3030 * @{
    31  */ 
     31 */
    3232/**
    3333 * @file
    34  * Glue code which is commonod 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"
    3838#include "../../srv/vfs/vfs.h"
    3939#include <errno.h>
     
    4646#include <sys/stat.h>
    4747
     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
    4863/** Register file system server.
    4964 *
     
    5267 * code.
    5368 *
    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 *
    6379 */
    6480int fs_register(int vfs_phone, fs_reg_t *reg, vfs_info_t *info,
     
    7288        ipc_call_t answer;
    7389        aid_t req = async_send_0(vfs_phone, VFS_IN_REGISTER, &answer);
    74 
     90       
    7591        /*
    7692         * Send our VFS info structure to VFS.
    7793         */
    78         int rc = ipc_data_write_start(vfs_phone, info, sizeof(*info));
     94        int rc = async_data_write_start(vfs_phone, info, sizeof(*info));
    7995        if (rc != EOK) {
    8096                async_wait_for(req, NULL);
    8197                return rc;
    8298        }
    83 
     99       
    84100        /*
    85101         * Ask VFS for callback connection.
    86102         */
    87103        ipc_connect_to_me(vfs_phone, 0, 0, 0, &reg->vfs_phonehash);
    88 
     104       
    89105        /*
    90106         * Allocate piece of address space for PLB.
     
    95111                return ENOMEM;
    96112        }
    97 
     113       
    98114        /*
    99115         * Request sharing the Path Lookup Buffer with VFS.
    100116         */
    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);
    102118        if (rc) {
    103119                async_wait_for(req, NULL);
     
    121137         */
    122138        async_set_client_connection(conn);
    123 
     139       
    124140        return IPC_GET_RETVAL(answer);
    125141}
     
    139155        int res;
    140156        ipcarg_t rc;
    141 
     157       
    142158        ipc_call_t call;
    143159        ipc_callid_t callid;
    144 
    145         /* accept the phone */
     160       
     161        /* Accept the phone */
    146162        callid = async_get_call(&call);
    147163        int mountee_phone = (int)IPC_GET_ARG1(call);
    148164        if ((IPC_GET_METHOD(call) != IPC_M_CONNECTION_CLONE) ||
    149             mountee_phone < 0) {
     165            (mountee_phone < 0)) {
    150166                ipc_answer_0(callid, EINVAL);
    151167                ipc_answer_0(rid, EINVAL);
    152168                return;
    153169        }
    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);
    157175        if (!res) {
    158176                ipc_hangup(mountee_phone);
     
    161179                return;
    162180        }
    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)) {
    166185                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       
    172191        if (fn->mp_data.mp_active) {
    173192                ipc_hangup(mountee_phone);
    174                 ops->node_put(fn);
     193                (void) ops->node_put(fn);
    175194                ipc_answer_0(callid, EBUSY);
    176195                ipc_answer_0(rid, EBUSY);
    177196                return;
    178197        }
    179 
     198       
    180199        rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME);
    181         if (rc != 0) {
     200        if (rc != EOK) {
    182201                ipc_hangup(mountee_phone);
    183                 ops->node_put(fn);
     202                (void) ops->node_put(fn);
    184203                ipc_answer_0(callid, rc);
    185204                ipc_answer_0(rid, rc);
     
    199218                fn->mp_data.phone = mountee_phone;
    200219        }
     220       
    201221        /*
    202222         * Do not release the FS node so that it stays in memory.
     
    222242    ipc_call_t *request)
    223243{
    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;
    227247        dev_handle_t dev_handle = IPC_GET_ARG3(*request);
    228248        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);
    230250        char component[NAME_MAX + 1];
    231251        int len;
    232 
     252        int rc;
     253       
    233254        if (last < next)
    234255                last += PLB_SIZE;
    235 
     256       
    236257        fs_node_t *par = NULL;
    237         fs_node_t *cur = ops->root_get(dev_handle);
     258        fs_node_t *cur = NULL;
    238259        fs_node_t *tmp = NULL;
    239 
     260       
     261        rc = ops->root_get(&cur, dev_handle);
     262        on_error(rc, goto out_with_answer);
     263       
    240264        if (cur->mp_data.mp_active) {
    241265                ipc_forward_slow(rid, cur->mp_data.phone, VFS_OUT_LOOKUP,
    242266                    next, last, cur->mp_data.dev_handle, lflag, index,
    243267                    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 */
    248273        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 */
    253285                len = 0;
    254                 while ((next <= last) &&  (ops->plb_get_char(next) != '/')) {
     286                while ((next <= last) && (ops->plb_get_char(next) != '/')) {
    255287                        if (len + 1 == NAME_MAX) {
    256                                 /* component length overflow */
     288                                /* Component length overflow */
    257289                                ipc_answer_0(rid, ENAMETOOLONG);
    258290                                goto out;
    259291                        }
    260292                        component[len++] = ops->plb_get_char(next);
    261                         next++; /* process next character */
     293                        /* Process next character */
     294                        next++;
    262295                }
    263 
     296               
    264297                assert(len);
    265298                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)) {
    271307                        if (next > last)
    272308                                next = last = first;
    273309                        else
    274310                                next--;
    275                                
     311                       
    276312                        ipc_forward_slow(rid, tmp->mp_data.phone,
    277313                            VFS_OUT_LOOKUP, next, last, tmp->mp_data.dev_handle,
    278314                            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);
    281317                        if (par)
    282                                 ops->node_put(par);
     318                                (void) ops->node_put(par);
    283319                        return;
    284320                }
    285 
    286                 /* handle miss: match amongst siblings */
     321               
     322                /* Handle miss: match amongst siblings */
    287323                if (!tmp) {
    288324                        if (next <= last) {
    289                                 /* there are unprocessed components */
     325                                /* There are unprocessed components */
    290326                                ipc_answer_0(rid, ENOENT);
    291327                                goto out;
    292328                        }
    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 */
    296333                                if (!ops->is_directory(cur)) {
    297334                                        ipc_answer_0(rid, ENOTDIR);
    298335                                        goto out;
    299336                                }
     337                               
    300338                                fs_node_t *fn;
    301339                                if (lflag & L_CREATE)
    302                                         fn = ops->create(dev_handle, lflag);
     340                                        rc = ops->create(&fn, dev_handle,
     341                                            lflag);
    303342                                else
    304                                         fn = ops->node_get(dev_handle,
     343                                        rc = ops->node_get(&fn, dev_handle,
    305344                                            index);
     345                                on_error(rc, goto out_with_answer);
     346                               
    306347                                if (fn) {
    307                                         int rc;
    308 
    309348                                        rc = ops->link(cur, fn, component);
    310349                                        if (rc != EOK) {
    311                                                 if (lflag & L_CREATE) {
    312                                                         (void)ops->destroy(fn);
    313                                                 }
     350                                                if (lflag & L_CREATE)
     351                                                        (void) ops->destroy(fn);
    314352                                                ipc_answer_0(rid, rc);
    315353                                        } else {
     
    319357                                                    ops->size_get(fn),
    320358                                                    ops->lnkcnt_get(fn));
    321                                                 ops->node_put(fn);
     359                                                (void) ops->node_put(fn);
    322360                                        }
    323                                 } else {
     361                                } else
    324362                                        ipc_answer_0(rid, ENOSPC);
    325                                 }
     363                               
    326364                                goto out;
    327                         }
     365                        }
     366                       
    328367                        ipc_answer_0(rid, ENOENT);
    329368                        goto out;
    330369                }
    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 */
    336377                par = cur;
    337378                cur = tmp;
    338379                tmp = NULL;
    339380        }
    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               
    343391                if (lflag & (L_CREATE | L_LINK)) {
    344392                        if (!ops->is_directory(cur)) {
     
    346394                                goto out;
    347395                        }
    348 
    349                         /* collect next component */
     396                       
     397                        /* Collect next component */
    350398                        len = 0;
    351399                        while (next <= last) {
    352400                                if (ops->plb_get_char(next) == '/') {
    353                                         /* more than one component */
     401                                        /* More than one component */
    354402                                        ipc_answer_0(rid, ENOENT);
    355403                                        goto out;
    356404                                }
     405                               
    357406                                if (len + 1 == NAME_MAX) {
    358                                         /* component length overflow */
     407                                        /* Component length overflow */
    359408                                        ipc_answer_0(rid, ENAMETOOLONG);
    360409                                        goto out;
    361410                                }
     411                               
    362412                                component[len++] = ops->plb_get_char(next);
    363                                 next++; /* process next character */
     413                                /* Process next character */
     414                                next++;
    364415                        }
     416                       
    365417                        assert(len);
    366418                        component[len] = '\0';
    367                                
     419                       
    368420                        fs_node_t *fn;
    369421                        if (lflag & L_CREATE)
    370                                 fn = ops->create(dev_handle, lflag);
     422                                rc = ops->create(&fn, dev_handle, lflag);
    371423                        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                       
    373427                        if (fn) {
    374                                 int rc;
    375 
    376428                                rc = ops->link(cur, fn, component);
    377429                                if (rc != EOK) {
    378430                                        if (lflag & L_CREATE)
    379                                                 (void)ops->destroy(fn);
     431                                                (void) ops->destroy(fn);
    380432                                        ipc_answer_0(rid, rc);
    381433                                } else {
     
    385437                                            ops->size_get(fn),
    386438                                            ops->lnkcnt_get(fn));
    387                                         ops->node_put(fn);
     439                                        (void) ops->node_put(fn);
    388440                                }
    389                         } else {
     441                        } else
    390442                                ipc_answer_0(rid, ENOSPC);
    391                         }
     443                       
    392444                        goto out;
    393445                }
     446               
    394447                ipc_answer_0(rid, ENOENT);
    395448                goto out;
    396449        }
    397 
    398         /* handle hit */
     450       
     451skip_miss:
     452       
     453        /* Handle hit */
    399454        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,
    403458                    ops->index_get(cur), ops->size_get(cur), old_lnkcnt);
    404459                goto out;
    405460        }
     461       
    406462        if (((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) ||
    407463            (lflag & L_LINK)) {
     
    409465                goto out;
    410466        }
     467       
    411468        if ((lflag & L_FILE) && (ops->is_directory(cur))) {
    412469                ipc_answer_0(rid, EISDIR);
    413470                goto out;
    414471        }
     472       
    415473        if ((lflag & L_DIRECTORY) && (ops->is_file(cur))) {
    416474                ipc_answer_0(rid, ENOTDIR);
    417475                goto out;
    418476        }
    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       
     478out_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       
    423490out:
     491       
    424492        if (par)
    425                 ops->node_put(par);
     493                (void) ops->node_put(par);
     494       
    426495        if (cur)
    427                 ops->node_put(cur);
     496                (void) ops->node_put(cur);
     497       
    428498        if (tmp)
    429                 ops->node_put(tmp);
     499                (void) ops->node_put(tmp);
    430500}
    431501
     
    435505        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
    436506        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       
    439512        ipc_callid_t callid;
    440513        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);
    443517                ipc_answer_0(callid, EINVAL);
    444518                ipc_answer_0(rid, EINVAL);
    445519                return;
    446520        }
    447 
     521       
    448522        struct stat stat;
    449523        memset(&stat, 0, sizeof(struct stat));
     
    452526        stat.dev_handle = dev_handle;
    453527        stat.index = index;
    454         stat.lnkcnt = ops->lnkcnt_get(fn); 
     528        stat.lnkcnt = ops->lnkcnt_get(fn);
    455529        stat.is_file = ops->is_file(fn);
     530        stat.is_directory = ops->is_directory(fn);
    456531        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));
    459537        ipc_answer_0(rid, EOK);
    460538}
     
    462540/** Open VFS triplet.
    463541 *
    464  * @param ops       libfs operations structure with function pointers to
    465  *                  file system implementation
    466  * @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.
    468546 *
    469547 */
     
    473551        dev_handle_t dev_handle = IPC_GET_ARG1(*request);
    474552        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) {
    479560                ipc_answer_0(rid, ENOENT);
    480561                return;
    481562        }
    482563       
    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);
    487569}
    488570
  • uspace/lib/libfs/libfs.h

    r309ede1 r5f70118  
    5656
    5757typedef 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);
    6269        int (* destroy)(fs_node_t *);
    6370        int (* link)(fs_node_t *, fs_node_t *, const char *);
    6471        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         */
    6577        fs_index_t (* index_get)(fs_node_t *);
    6678        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 *);
    7080        char (* plb_get_char)(unsigned pos);
    7181        bool (* is_directory)(fs_node_t *);
    7282        bool (* is_file)(fs_node_t *);
     83        dev_handle_t (* device_get)(fs_node_t *);
    7384} libfs_ops_t;
    7485
  • uspace/lib/softfloat/Makefile

    r309ede1 r5f70118  
    11#
    22# Copyright (c) 2005 Martin Decky
     3# Copyright (c) 2007 Jakub Jermar
    34# All rights reserved.
    45#
     
    2728#
    2829
    29 ## Common compiler flags
    30 #
     30include Makefile.common
    3131
    32 LIBC_PREFIX = ../libc
     32.PHONY: all clean
    3333
    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
     34all: $(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)
    6437
    6538clean:
    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  
    11#
    22# Copyright (c) 2005 Martin Decky
     3# Copyright (c) 2007 Jakub Jermar
    34# All rights reserved.
    45#
     
    3031#
    3132
    32 LIBC_PREFIX = ../../lib/libc
    33 SOFTINT_PREFIX = ../../lib/softint
    34 
     33include Makefile.common
    3534include $(LIBC_PREFIX)/Makefile.toolchain
    3635
    37 
    38 LIBS = libpci/libpci.a $(LIBC_PREFIX)/libc.a
     36CFLAGS += -Iinclude -Iarch/$(UARCH)/include/
    3937
    4038## Sources
    4139#
    4240
    43 OUTPUT = pci
    4441SOURCES = \
    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
    4651
    4752OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
    4853
    49 .PHONY: all clean depend disasm
     54.PHONY: all
    5055
    51 all: $(OUTPUT) disasm
     56all: $(LIBSOFTFLOAT)
    5257
    53 -include Makefile.depend
     58-include $(DEPEND)
    5459
    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)
    5862
    59 depend:
    60         $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
     63%.o: %.c $(DEPEND)
     64        $(CC) $(DEFS) $(CFLAGS) -c $< -o $@
     65ifeq ($(PRECHECK),y)
     66        $(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(CFLAGS)
     67endif
    6168
    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  
    11#
    22# Copyright (c) 2005 Martin Decky
     3# Copyright (c) 2007 Jakub Jermar
    34# All rights reserved.
    45#
     
    2728#
    2829
    29 ## Common compiler flags
    30 #
     30include Makefile.common
    3131
    32 LIBC_PREFIX = ../libc
     32.PHONY: all clean
    3333
    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
     34all: $(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)
    5637
    5738clean:
    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.