Changes in / [bc77bfa:034bf0e] in mainline


Ignore:
Files:
1 added
37 edited

Legend:

Unmodified
Added
Removed
  • Makefile

    rbc77bfa r034bf0e  
    4343        $(MAKE) -C kernel clean
    4444        $(MAKE) -C kernel EXTRA_TOOL=stanse
    45         $(STANSE) --checker ReachabilityChecker --checker ThreadChecker:contrib/$(STANSE)/ThreadChecker.xml --jobfile kernel/kernel.job
     45        $(STANSE) --checker ReachabilityChecker --jobfile kernel/kernel.job
    4646
    4747cscope:
  • kernel/arch/amd64/src/amd64.c

    rbc77bfa r034bf0e  
    6767#include <ddi/irq.h>
    6868#include <sysinfo/sysinfo.h>
     69#include <memstr.h>
    6970
    7071/** Disable I/O on non-privileged levels
  • kernel/arch/arm32/include/atomic.h

    rbc77bfa r034bf0e  
    3737#define KERN_arm32_ATOMIC_H_
    3838
     39#include <arch/asm.h>
     40
    3941/** Atomic addition.
    4042 *
     
    4749static inline long atomic_add(atomic_t *val, int i)
    4850{
    49         int ret;
    50         volatile long *mem = &(val->count);
    51        
    52         asm volatile (
    53                 "1:\n"
    54                         "ldr r2, [%[mem]]\n"
    55                         "add r3, r2, %[i]\n"
    56                         "str r3, %[ret]\n"
    57                         "swp r3, r3, [%[mem]]\n"
    58                         "cmp r3, r2\n"
    59                         "bne 1b\n"
    60                 : [ret] "=m" (ret)
    61                 : [mem] "r" (mem), [i] "r" (i)
    62                 : "r3", "r2"
    63         );
     51        long ret;
     52
     53        /*
     54         * This implementation is for UP pre-ARMv6 systems where we do not have
     55         * the LDREX and STREX instructions.
     56         */
     57        ipl_t ipl = interrupts_disable();
     58        val->count += i;
     59        ret = val->count;
     60        interrupts_restore(ipl);
    6461       
    6562        return ret;
  • kernel/arch/arm32/src/mm/as.c

    rbc77bfa r034bf0e  
    3636#include <arch/mm/as.h>
    3737#include <genarch/mm/as_pt.h>
     38#include <genarch/mm/page_pt.h>
    3839#include <genarch/mm/asid_fifo.h>
    3940#include <mm/as.h>
  • kernel/arch/ia32/src/ia32.c

    rbc77bfa r034bf0e  
    6868#include <sysinfo/sysinfo.h>
    6969#include <arch/boot/boot.h>
     70#include <memstr.h>
    7071
    7172#ifdef CONFIG_SMP
  • kernel/arch/ia64/src/cpu/cpu.c

    rbc77bfa r034bf0e  
    3737#include <arch/register.h>
    3838#include <print.h>
     39#include <memstr.h>
    3940
    4041void cpu_arch_init(void)
  • kernel/arch/ppc32/src/mm/as.c

    rbc77bfa r034bf0e  
    3535#include <arch/mm/as.h>
    3636#include <genarch/mm/as_pt.h>
     37#include <genarch/mm/page_pt.h>
    3738#include <genarch/mm/asid_fifo.h>
    3839#include <arch.h>
  • kernel/arch/ppc32/src/mm/tlb.c

    rbc77bfa r034bf0e  
    3838#include <interrupt.h>
    3939#include <mm/as.h>
     40#include <mm/page.h>
    4041#include <arch.h>
    4142#include <print.h>
  • kernel/arch/ppc32/src/ppc32.c

    rbc77bfa r034bf0e  
    4444#include <genarch/ofw/pci.h>
    4545#include <userspace.h>
     46#include <mm/page.h>
    4647#include <proc/uarg.h>
    4748#include <console/console.h>
  • kernel/arch/sparc64/src/mm/tlb.c

    rbc77bfa r034bf0e  
    3737#include <mm/as.h>
    3838#include <mm/asid.h>
     39#include <genarch/mm/page_ht.h>
    3940#include <arch/mm/frame.h>
    4041#include <arch/mm/page.h>
  • kernel/genarch/src/drivers/via-cuda/cuda.c

    rbc77bfa r034bf0e  
    4141#include <ddi/device.h>
    4242#include <synch/spinlock.h>
     43#include <memstr.h>
    4344
    4445static irq_ownership_t cuda_claim(irq_t *irq);
  • kernel/genarch/src/fb/fb.c

    rbc77bfa r034bf0e  
    4141#include <console/console.h>
    4242#include <sysinfo/sysinfo.h>
     43#include <mm/page.h>
    4344#include <mm/slab.h>
    4445#include <align.h>
  • kernel/generic/include/arch.h

    rbc77bfa r034bf0e  
    3939#include <proc/thread.h>
    4040#include <proc/task.h>
     41#include <mm/as.h>
    4142
    4243#define DEFAULT_CONTEXT         0
  • kernel/generic/include/proc/task.h

    rbc77bfa r034bf0e  
    5555#include <udebug/udebug.h>
    5656#include <ipc/kbox.h>
     57#include <mm/as.h>
    5758
    5859#define TASK_NAME_BUFLEN        20
  • kernel/generic/include/proc/thread.h

    rbc77bfa r034bf0e  
    225225
    226226extern void thread_init(void);
    227 extern thread_t *thread_create(void (* func)(void *), void *arg, task_t *task,
    228     int flags, char *name, bool uncounted);
    229 extern void thread_attach(thread_t *t, task_t *task);
    230 extern void thread_ready(thread_t *t);
     227extern thread_t *thread_create(void (*)(void *), void *, task_t *, int, char *,
     228    bool);
     229extern void thread_attach(thread_t *, task_t *);
     230extern void thread_ready(thread_t *);
    231231extern void thread_exit(void) __attribute__((noreturn));
    232232
    233233#ifndef thread_create_arch
    234 extern void thread_create_arch(thread_t *t);
     234extern void thread_create_arch(thread_t *);
    235235#endif
    236236#ifndef thr_constructor_arch
    237 extern void thr_constructor_arch(thread_t *t);
     237extern void thr_constructor_arch(thread_t *);
    238238#endif
    239239#ifndef thr_destructor_arch
    240 extern void thr_destructor_arch(thread_t *t);
    241 #endif
    242 
    243 extern void thread_sleep(uint32_t sec);
    244 extern void thread_usleep(uint32_t usec);
     240extern void thr_destructor_arch(thread_t *);
     241#endif
     242
     243extern void thread_sleep(uint32_t);
     244extern void thread_usleep(uint32_t);
    245245
    246246#define thread_join(t) \
    247247        thread_join_timeout((t), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE)
    248 extern int thread_join_timeout(thread_t *t, uint32_t usec, int flags);
    249 extern void thread_detach(thread_t *t);
    250 
    251 extern void thread_register_call_me(void (* call_me)(void *),
    252     void *call_me_with);
     248extern int thread_join_timeout(thread_t *, uint32_t, int);
     249extern void thread_detach(thread_t *);
     250
     251extern void thread_register_call_me(void (*)(void *), void *);
    253252extern void thread_print_list(void);
    254 extern void thread_destroy(thread_t *t);
     253extern void thread_destroy(thread_t *);
    255254extern void thread_update_accounting(void);
    256 extern bool thread_exists(thread_t *t);
     255extern bool thread_exists(thread_t *);
    257256
    258257/** Fpu context slab cache. */
     
    260259
    261260/* Thread syscall prototypes. */
    262 extern unative_t sys_thread_create(uspace_arg_t *uspace_uarg,
    263     char *uspace_name, size_t name_len, thread_id_t *uspace_thread_id);
    264 extern unative_t sys_thread_exit(int uspace_status);
    265 extern unative_t sys_thread_get_id(thread_id_t *uspace_thread_id);
     261extern unative_t sys_thread_create(uspace_arg_t *, char *, size_t,
     262    thread_id_t *);
     263extern unative_t sys_thread_exit(int);
     264extern unative_t sys_thread_get_id(thread_id_t *);
     265extern unative_t sys_thread_usleep(uint32_t);
    266266
    267267#endif
  • kernel/generic/include/synch/futex.h

    rbc77bfa r034bf0e  
    3838#include <arch/types.h>
    3939#include <synch/waitq.h>
    40 #include <genarch/mm/page_ht.h>
    41 #include <genarch/mm/page_pt.h>
    4240
    4341/** Kernel-side futex structure. */
     
    5452
    5553extern void futex_init(void);
    56 extern unative_t sys_futex_sleep_timeout(uintptr_t uaddr, uint32_t usec,
    57     int flags);
    58 extern unative_t sys_futex_wakeup(uintptr_t uaddr);
     54extern unative_t sys_futex_sleep(uintptr_t);
     55extern unative_t sys_futex_wakeup(uintptr_t);
    5956
    6057extern void futex_cleanup(void);
  • kernel/generic/include/syscall/syscall.h

    rbc77bfa r034bf0e  
    4343        SYS_THREAD_EXIT,
    4444        SYS_THREAD_GET_ID,
     45        SYS_THREAD_USLEEP,
    4546       
    4647        SYS_TASK_GET_ID,
  • kernel/generic/src/mm/backend_phys.c

    rbc77bfa r034bf0e  
    4040#include <arch/types.h>
    4141#include <mm/as.h>
     42#include <mm/page.h>
    4243#include <mm/frame.h>
    4344#include <mm/slab.h>
  • kernel/generic/src/proc/task.c

    rbc77bfa r034bf0e  
    5454#include <func.h>
    5555#include <string.h>
     56#include <memstr.h>
    5657#include <syscall/copy.h>
    5758#include <macros.h>
  • kernel/generic/src/proc/thread.c

    rbc77bfa r034bf0e  
    501501void thread_sleep(uint32_t sec)
    502502{
    503         thread_usleep(sec * 1000000);
     503        /* Sleep in 1000 second steps to support
     504           full argument range */
     505        while (sec > 0) {
     506                uint32_t period = (sec > 1000) ? 1000 : sec;
     507       
     508                thread_usleep(period * 1000000);
     509                sec -= period;
     510        }
    504511}
    505512
     
    575582{
    576583        waitq_t wq;
    577                                  
     584       
    578585        waitq_initialize(&wq);
    579 
     586       
    580587        (void) waitq_sleep_timeout(&wq, usec, SYNCH_FLAGS_NON_BLOCKING);
    581588}
     
    812819}
    813820
     821/** Syscall wrapper for sleeping. */
     822unative_t sys_thread_usleep(uint32_t usec)
     823{
     824        thread_usleep(usec);
     825        return 0;
     826}
     827
    814828/** @}
    815829 */
  • kernel/generic/src/synch/futex.c

    rbc77bfa r034bf0e  
    9090/** Initialize kernel futex structure.
    9191 *
    92  * @param futex Kernel futex structure.
     92 * @param futex         Kernel futex structure.
    9393 */
    9494void futex_initialize(futex_t *futex)
     
    102102/** Sleep in futex wait queue.
    103103 *
    104  * @param uaddr Userspace address of the futex counter.
    105  * @param usec If non-zero, number of microseconds this thread is willing to
    106  *     sleep.
    107  * @param flags Select mode of operation.
    108  *
    109  * @return One of ESYNCH_TIMEOUT, ESYNCH_OK_ATOMIC and ESYNCH_OK_BLOCKED. See
    110  *     synch.h. If there is no physical mapping for uaddr ENOENT is returned.
    111  */
    112 unative_t sys_futex_sleep_timeout(uintptr_t uaddr, uint32_t usec, int flags)
     104 * @param uaddr         Userspace address of the futex counter.
     105 *
     106 * @return              If there is no physical mapping for uaddr ENOENT is
     107 *                      returned. Otherwise returns a wait result as defined in
     108 *                      synch.h.
     109 */
     110unative_t sys_futex_sleep(uintptr_t uaddr)
    113111{
    114112        futex_t *futex;
     
    140138        udebug_stoppable_begin();
    141139#endif
    142         rc = waitq_sleep_timeout(&futex->wq, usec, flags |
    143             SYNCH_FLAGS_INTERRUPTIBLE);
    144 
     140        rc = waitq_sleep_timeout(&futex->wq, 0, SYNCH_FLAGS_INTERRUPTIBLE);
    145141#ifdef CONFIG_UDEBUG
    146142        udebug_stoppable_end();
     
    151147/** Wakeup one thread waiting in futex wait queue.
    152148 *
    153  * @param uaddr Userspace address of the futex counter.
    154  *
    155  * @return ENOENT if there is no physical mapping for uaddr.
     149 * @param uaddr         Userspace address of the futex counter.
     150 *
     151 * @return              ENOENT if there is no physical mapping for uaddr.
    156152 */
    157153unative_t sys_futex_wakeup(uintptr_t uaddr)
     
    190186 * If the structure does not exist already, a new one is created.
    191187 *
    192  * @param paddr Physical address of the userspace futex counter.
    193  *
    194  * @return Address of the kernel futex structure.
     188 * @param paddr         Physical address of the userspace futex counter.
     189 *
     190 * @return              Address of the kernel futex structure.
    195191 */
    196192futex_t *futex_find(uintptr_t paddr)
     
    284280/** Compute hash index into futex hash table.
    285281 *
    286  * @param key Address where the key (i.e. physical address of futex counter) is
    287  *    stored.
    288  *
    289  * @return Index into futex hash table.
     282 * @param key           Address where the key (i.e. physical address of futex
     283 *                      counter) is stored.
     284 *
     285 * @return              Index into futex hash table.
    290286 */
    291287size_t futex_ht_hash(unative_t *key)
     
    296292/** Compare futex hash table item with a key.
    297293 *
    298  * @param key Address where the key (i.e. physical address of futex counter) is
    299  *    stored.
    300  *
    301  * @return True if the item matches the key. False otherwise.
     294 * @param key           Address where the key (i.e. physical address of futex
     295 *                      counter) is stored.
     296 *
     297 * @return              True if the item matches the key. False otherwise.
    302298 */
    303299bool futex_ht_compare(unative_t *key, size_t keys, link_t *item)
     
    313309/** Callback for removal items from futex hash table.
    314310 *
    315  * @param item Item removed from the hash table.
     311 * @param item          Item removed from the hash table.
    316312 */
    317313void futex_ht_remove_callback(link_t *item)
  • kernel/generic/src/syscall/syscall.c

    rbc77bfa r034bf0e  
    6262
    6363#ifdef CONFIG_UDEBUG
    64         bool debug;
    65 
    6664        /*
    6765         * Early check for undebugged tasks. We do not lock anything as this
    68          * test need not be precise in either way.
     66         * test need not be precise in either direction.
    6967         */
    70         debug = THREAD->udebug.active;
    71        
    72         if (debug) {
     68        if (THREAD->udebug.active) {
    7369                udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, 0, false);
    7470        }
     
    8783       
    8884#ifdef CONFIG_UDEBUG
    89         if (debug) {
     85        if (THREAD->udebug.active) {
    9086                udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc, true);
    9187       
     
    111107        (syshandler_t) sys_thread_exit,
    112108        (syshandler_t) sys_thread_get_id,
     109        (syshandler_t) sys_thread_usleep,
    113110       
    114111        (syshandler_t) sys_task_get_id,
     
    117114       
    118115        /* Synchronization related syscalls. */
    119         (syshandler_t) sys_futex_sleep_timeout,
     116        (syshandler_t) sys_futex_sleep,
    120117        (syshandler_t) sys_futex_wakeup,
    121118        (syshandler_t) sys_smc_coherence,
  • kernel/generic/src/udebug/udebug_ops.c

    rbc77bfa r034bf0e  
    5050#include <udebug/udebug.h>
    5151#include <udebug/udebug_ops.h>
     52#include <memstr.h>
    5253
    5354/**
  • uspace/lib/libc/arch/amd64/include/atomic.h

    rbc77bfa r034bf0e  
    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/arm32/include/atomic.h

    rbc77bfa r034bf0e  
    3737#define LIBC_arm32_ATOMIC_H_
    3838
     39#include <bool.h>
     40
     41typedef struct atomic {
     42        volatile long count;
     43} atomic_t;
     44
     45static inline void atomic_set(atomic_t *val, long i)
     46{
     47        val->count = i;
     48}
     49
     50static inline long atomic_get(atomic_t *val)
     51{
     52        return val->count;
     53}
     54
     55static inline bool cas(atomic_t *val, long ov, long nv)
     56{
     57        /* FIXME: is not atomic */
     58        if (val->count == ov) {
     59                val->count = nv;
     60                return true;
     61        }
     62        return false;
     63}
     64
    3965/** Atomic addition.
    4066 *
     
    4975        volatile long * mem = &(val->count);
    5076
     77        /* FIXME: is not atomic, is broken */
    5178        asm volatile (
    5279        "1:\n"
  • uspace/lib/libc/arch/ia32/Makefile.inc

    rbc77bfa r034bf0e  
    3939        arch/$(UARCH)/src/setjmp.S
    4040
     41GCC_CFLAGS += -march=pentium
    4142LFLAGS += -N
    4243
  • uspace/lib/libc/arch/ia32/include/atomic.h

    rbc77bfa r034bf0e  
    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/ia64/include/atomic.h

    rbc77bfa r034bf0e  
    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/include/atomic.h

    rbc77bfa r034bf0e  
    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/ppc32/include/atomic.h

    rbc77bfa r034bf0e  
    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/sparc64/include/atomic.h

    rbc77bfa r034bf0e  
    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/generic/futex.c

    rbc77bfa r034bf0e  
    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/io.c

    rbc77bfa r034bf0e  
    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) {
  • uspace/lib/libc/generic/time.c

    rbc77bfa r034bf0e  
    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/include/atomic.h

    rbc77bfa r034bf0e  
    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/futex.h

    rbc77bfa r034bf0e  
    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/unistd.h

    rbc77bfa r034bf0e  
    5151#endif
    5252
     53typedef uint32_t useconds_t;
     54
    5355extern int dup2(int oldfd, int newfd);
    5456
     
    6870
    6971extern void _exit(int status) __attribute__ ((noreturn));
    70 extern int usleep(unsigned long usec);
    71 extern unsigned int sleep(unsigned int seconds);
     72extern int usleep(useconds_t uses);
     73extern unsigned int sleep(unsigned int se);
    7274
    7375#endif
Note: See TracChangeset for help on using the changeset viewer.