Changes in / [bc77bfa:034bf0e] in mainline
- Files:
-
- 1 added
- 37 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile
rbc77bfa r034bf0e 43 43 $(MAKE) -C kernel clean 44 44 $(MAKE) -C kernel EXTRA_TOOL=stanse 45 $(STANSE) --checker ReachabilityChecker -- checker ThreadChecker:contrib/$(STANSE)/ThreadChecker.xml --jobfile kernel/kernel.job45 $(STANSE) --checker ReachabilityChecker --jobfile kernel/kernel.job 46 46 47 47 cscope: -
kernel/arch/amd64/src/amd64.c
rbc77bfa r034bf0e 67 67 #include <ddi/irq.h> 68 68 #include <sysinfo/sysinfo.h> 69 #include <memstr.h> 69 70 70 71 /** Disable I/O on non-privileged levels -
kernel/arch/arm32/include/atomic.h
rbc77bfa r034bf0e 37 37 #define KERN_arm32_ATOMIC_H_ 38 38 39 #include <arch/asm.h> 40 39 41 /** Atomic addition. 40 42 * … … 47 49 static inline long atomic_add(atomic_t *val, int i) 48 50 { 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); 64 61 65 62 return ret; -
kernel/arch/arm32/src/mm/as.c
rbc77bfa r034bf0e 36 36 #include <arch/mm/as.h> 37 37 #include <genarch/mm/as_pt.h> 38 #include <genarch/mm/page_pt.h> 38 39 #include <genarch/mm/asid_fifo.h> 39 40 #include <mm/as.h> -
kernel/arch/ia32/src/ia32.c
rbc77bfa r034bf0e 68 68 #include <sysinfo/sysinfo.h> 69 69 #include <arch/boot/boot.h> 70 #include <memstr.h> 70 71 71 72 #ifdef CONFIG_SMP -
kernel/arch/ia64/src/cpu/cpu.c
rbc77bfa r034bf0e 37 37 #include <arch/register.h> 38 38 #include <print.h> 39 #include <memstr.h> 39 40 40 41 void cpu_arch_init(void) -
kernel/arch/ppc32/src/mm/as.c
rbc77bfa r034bf0e 35 35 #include <arch/mm/as.h> 36 36 #include <genarch/mm/as_pt.h> 37 #include <genarch/mm/page_pt.h> 37 38 #include <genarch/mm/asid_fifo.h> 38 39 #include <arch.h> -
kernel/arch/ppc32/src/mm/tlb.c
rbc77bfa r034bf0e 38 38 #include <interrupt.h> 39 39 #include <mm/as.h> 40 #include <mm/page.h> 40 41 #include <arch.h> 41 42 #include <print.h> -
kernel/arch/ppc32/src/ppc32.c
rbc77bfa r034bf0e 44 44 #include <genarch/ofw/pci.h> 45 45 #include <userspace.h> 46 #include <mm/page.h> 46 47 #include <proc/uarg.h> 47 48 #include <console/console.h> -
kernel/arch/sparc64/src/mm/tlb.c
rbc77bfa r034bf0e 37 37 #include <mm/as.h> 38 38 #include <mm/asid.h> 39 #include <genarch/mm/page_ht.h> 39 40 #include <arch/mm/frame.h> 40 41 #include <arch/mm/page.h> -
kernel/genarch/src/drivers/via-cuda/cuda.c
rbc77bfa r034bf0e 41 41 #include <ddi/device.h> 42 42 #include <synch/spinlock.h> 43 #include <memstr.h> 43 44 44 45 static irq_ownership_t cuda_claim(irq_t *irq); -
kernel/genarch/src/fb/fb.c
rbc77bfa r034bf0e 41 41 #include <console/console.h> 42 42 #include <sysinfo/sysinfo.h> 43 #include <mm/page.h> 43 44 #include <mm/slab.h> 44 45 #include <align.h> -
kernel/generic/include/arch.h
rbc77bfa r034bf0e 39 39 #include <proc/thread.h> 40 40 #include <proc/task.h> 41 #include <mm/as.h> 41 42 42 43 #define DEFAULT_CONTEXT 0 -
kernel/generic/include/proc/task.h
rbc77bfa r034bf0e 55 55 #include <udebug/udebug.h> 56 56 #include <ipc/kbox.h> 57 #include <mm/as.h> 57 58 58 59 #define TASK_NAME_BUFLEN 20 -
kernel/generic/include/proc/thread.h
rbc77bfa r034bf0e 225 225 226 226 extern 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);227 extern thread_t *thread_create(void (*)(void *), void *, task_t *, int, char *, 228 bool); 229 extern void thread_attach(thread_t *, task_t *); 230 extern void thread_ready(thread_t *); 231 231 extern void thread_exit(void) __attribute__((noreturn)); 232 232 233 233 #ifndef thread_create_arch 234 extern void thread_create_arch(thread_t * t);234 extern void thread_create_arch(thread_t *); 235 235 #endif 236 236 #ifndef thr_constructor_arch 237 extern void thr_constructor_arch(thread_t * t);237 extern void thr_constructor_arch(thread_t *); 238 238 #endif 239 239 #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);240 extern void thr_destructor_arch(thread_t *); 241 #endif 242 243 extern void thread_sleep(uint32_t); 244 extern void thread_usleep(uint32_t); 245 245 246 246 #define thread_join(t) \ 247 247 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); 248 extern int thread_join_timeout(thread_t *, uint32_t, int); 249 extern void thread_detach(thread_t *); 250 251 extern void thread_register_call_me(void (*)(void *), void *); 253 252 extern void thread_print_list(void); 254 extern void thread_destroy(thread_t * t);253 extern void thread_destroy(thread_t *); 255 254 extern void thread_update_accounting(void); 256 extern bool thread_exists(thread_t * t);255 extern bool thread_exists(thread_t *); 257 256 258 257 /** Fpu context slab cache. */ … … 260 259 261 260 /* 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); 261 extern unative_t sys_thread_create(uspace_arg_t *, char *, size_t, 262 thread_id_t *); 263 extern unative_t sys_thread_exit(int); 264 extern unative_t sys_thread_get_id(thread_id_t *); 265 extern unative_t sys_thread_usleep(uint32_t); 266 266 267 267 #endif -
kernel/generic/include/synch/futex.h
rbc77bfa r034bf0e 38 38 #include <arch/types.h> 39 39 #include <synch/waitq.h> 40 #include <genarch/mm/page_ht.h>41 #include <genarch/mm/page_pt.h>42 40 43 41 /** Kernel-side futex structure. */ … … 54 52 55 53 extern 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); 54 extern unative_t sys_futex_sleep(uintptr_t); 55 extern unative_t sys_futex_wakeup(uintptr_t); 59 56 60 57 extern void futex_cleanup(void); -
kernel/generic/include/syscall/syscall.h
rbc77bfa r034bf0e 43 43 SYS_THREAD_EXIT, 44 44 SYS_THREAD_GET_ID, 45 SYS_THREAD_USLEEP, 45 46 46 47 SYS_TASK_GET_ID, -
kernel/generic/src/mm/backend_phys.c
rbc77bfa r034bf0e 40 40 #include <arch/types.h> 41 41 #include <mm/as.h> 42 #include <mm/page.h> 42 43 #include <mm/frame.h> 43 44 #include <mm/slab.h> -
kernel/generic/src/proc/task.c
rbc77bfa r034bf0e 54 54 #include <func.h> 55 55 #include <string.h> 56 #include <memstr.h> 56 57 #include <syscall/copy.h> 57 58 #include <macros.h> -
kernel/generic/src/proc/thread.c
rbc77bfa r034bf0e 501 501 void thread_sleep(uint32_t sec) 502 502 { 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 } 504 511 } 505 512 … … 575 582 { 576 583 waitq_t wq; 577 584 578 585 waitq_initialize(&wq); 579 586 580 587 (void) waitq_sleep_timeout(&wq, usec, SYNCH_FLAGS_NON_BLOCKING); 581 588 } … … 812 819 } 813 820 821 /** Syscall wrapper for sleeping. */ 822 unative_t sys_thread_usleep(uint32_t usec) 823 { 824 thread_usleep(usec); 825 return 0; 826 } 827 814 828 /** @} 815 829 */ -
kernel/generic/src/synch/futex.c
rbc77bfa r034bf0e 90 90 /** Initialize kernel futex structure. 91 91 * 92 * @param futex 92 * @param futex Kernel futex structure. 93 93 */ 94 94 void futex_initialize(futex_t *futex) … … 102 102 /** Sleep in futex wait queue. 103 103 * 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 */ 110 unative_t sys_futex_sleep(uintptr_t uaddr) 113 111 { 114 112 futex_t *futex; … … 140 138 udebug_stoppable_begin(); 141 139 #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); 145 141 #ifdef CONFIG_UDEBUG 146 142 udebug_stoppable_end(); … … 151 147 /** Wakeup one thread waiting in futex wait queue. 152 148 * 153 * @param uaddr 154 * 155 * @return 149 * @param uaddr Userspace address of the futex counter. 150 * 151 * @return ENOENT if there is no physical mapping for uaddr. 156 152 */ 157 153 unative_t sys_futex_wakeup(uintptr_t uaddr) … … 190 186 * If the structure does not exist already, a new one is created. 191 187 * 192 * @param paddr 193 * 194 * @return 188 * @param paddr Physical address of the userspace futex counter. 189 * 190 * @return Address of the kernel futex structure. 195 191 */ 196 192 futex_t *futex_find(uintptr_t paddr) … … 284 280 /** Compute hash index into futex hash table. 285 281 * 286 * @param key Address where the key (i.e. physical address of futex counter) is287 * 288 * 289 * @return 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. 290 286 */ 291 287 size_t futex_ht_hash(unative_t *key) … … 296 292 /** Compare futex hash table item with a key. 297 293 * 298 * @param key Address where the key (i.e. physical address of futex counter) is299 * 300 * 301 * @return 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. 302 298 */ 303 299 bool futex_ht_compare(unative_t *key, size_t keys, link_t *item) … … 313 309 /** Callback for removal items from futex hash table. 314 310 * 315 * @param item 311 * @param item Item removed from the hash table. 316 312 */ 317 313 void futex_ht_remove_callback(link_t *item) -
kernel/generic/src/syscall/syscall.c
rbc77bfa r034bf0e 62 62 63 63 #ifdef CONFIG_UDEBUG 64 bool debug;65 66 64 /* 67 65 * 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. 69 67 */ 70 debug = THREAD->udebug.active; 71 72 if (debug) { 68 if (THREAD->udebug.active) { 73 69 udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, 0, false); 74 70 } … … 87 83 88 84 #ifdef CONFIG_UDEBUG 89 if ( debug) {85 if (THREAD->udebug.active) { 90 86 udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc, true); 91 87 … … 111 107 (syshandler_t) sys_thread_exit, 112 108 (syshandler_t) sys_thread_get_id, 109 (syshandler_t) sys_thread_usleep, 113 110 114 111 (syshandler_t) sys_task_get_id, … … 117 114 118 115 /* Synchronization related syscalls. */ 119 (syshandler_t) sys_futex_sleep _timeout,116 (syshandler_t) sys_futex_sleep, 120 117 (syshandler_t) sys_futex_wakeup, 121 118 (syshandler_t) sys_smc_coherence, -
kernel/generic/src/udebug/udebug_ops.c
rbc77bfa r034bf0e 50 50 #include <udebug/udebug.h> 51 51 #include <udebug/udebug_ops.h> 52 #include <memstr.h> 52 53 53 54 /** -
uspace/lib/libc/arch/amd64/include/atomic.h
rbc77bfa r034bf0e 37 37 #ifndef LIBC_amd64_ATOMIC_H_ 38 38 #define LIBC_amd64_ATOMIC_H_ 39 40 #define LIBC_ARCH_ATOMIC_H_ 41 42 #include <atomicdflt.h> 39 43 40 44 static inline void atomic_inc(atomic_t *val) { -
uspace/lib/libc/arch/arm32/include/atomic.h
rbc77bfa r034bf0e 37 37 #define LIBC_arm32_ATOMIC_H_ 38 38 39 #include <bool.h> 40 41 typedef struct atomic { 42 volatile long count; 43 } atomic_t; 44 45 static inline void atomic_set(atomic_t *val, long i) 46 { 47 val->count = i; 48 } 49 50 static inline long atomic_get(atomic_t *val) 51 { 52 return val->count; 53 } 54 55 static 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 39 65 /** Atomic addition. 40 66 * … … 49 75 volatile long * mem = &(val->count); 50 76 77 /* FIXME: is not atomic, is broken */ 51 78 asm volatile ( 52 79 "1:\n" -
uspace/lib/libc/arch/ia32/Makefile.inc
rbc77bfa r034bf0e 39 39 arch/$(UARCH)/src/setjmp.S 40 40 41 GCC_CFLAGS += -march=pentium 41 42 LFLAGS += -N 42 43 -
uspace/lib/libc/arch/ia32/include/atomic.h
rbc77bfa r034bf0e 35 35 #ifndef LIBC_ia32_ATOMIC_H_ 36 36 #define LIBC_ia32_ATOMIC_H_ 37 38 #define LIBC_ARCH_ATOMIC_H_ 39 40 #include <atomicdflt.h> 37 41 38 42 static inline void atomic_inc(atomic_t *val) { -
uspace/lib/libc/arch/ia64/include/atomic.h
rbc77bfa r034bf0e 35 35 #ifndef LIBC_ia64_ATOMIC_H_ 36 36 #define LIBC_ia64_ATOMIC_H_ 37 38 #define LIBC_ARCH_ATOMIC_H_ 39 40 #include <atomicdflt.h> 37 41 38 42 static inline void atomic_inc(atomic_t *val) -
uspace/lib/libc/arch/mips32/include/atomic.h
rbc77bfa r034bf0e 36 36 #ifndef LIBC_mips32_ATOMIC_H_ 37 37 #define LIBC_mips32_ATOMIC_H_ 38 39 #define LIBC_ARCH_ATOMIC_H_ 40 41 #include <atomicdflt.h> 38 42 39 43 #define atomic_inc(x) ((void) atomic_add(x, 1)) -
uspace/lib/libc/arch/ppc32/include/atomic.h
rbc77bfa r034bf0e 35 35 #ifndef LIBC_ppc32_ATOMIC_H_ 36 36 #define LIBC_ppc32_ATOMIC_H_ 37 38 #define LIBC_ARCH_ATOMIC_H_ 39 40 #include <atomicdflt.h> 37 41 38 42 static inline void atomic_inc(atomic_t *val) -
uspace/lib/libc/arch/sparc64/include/atomic.h
rbc77bfa r034bf0e 36 36 #define LIBC_sparc64_ATOMIC_H_ 37 37 38 #define LIBC_ARCH_ATOMIC_H_ 39 40 #include <atomicdflt.h> 38 41 #include <sys/types.h> 39 42 -
uspace/lib/libc/generic/futex.c
rbc77bfa r034bf0e 36 36 #include <atomic.h> 37 37 #include <libc.h> 38 #include <stdio.h>39 38 #include <sys/types.h> 40 #include <kernel/synch/synch.h>41 42 /*43 * Note about race conditions.44 * Because of non-atomic nature of operations performed sequentially on the45 * futex counter and the futex wait queue, there is a race condition:46 *47 * (wq->missed_wakeups == 1) && (futex->count = 1)48 *49 * Scenario 1 (wait queue timeout vs. futex_up()):50 * 1. assume wq->missed_wakeups == 0 && futex->count == -151 * (ie. thread A sleeping, thread B in the critical section)52 * 2. A receives timeout and gets removed from the wait queue53 * 3. B wants to leave the critical section and calls futex_up()54 * 4. B thus changes futex->count from -1 to 055 * 5. B has to call SYS_FUTEX_WAKEUP syscall to wake up the sleeping thread56 * 6. B finds the wait queue empty and changes wq->missed_wakeups from 0 to 157 * 7. A fixes futex->count (i.e. the number of waiting threads) by changing it58 * from 0 to 159 *60 * Scenario 2 (conditional down operation vs. futex_up)61 * 1. assume wq->missed_wakeups == 0 && futex->count == 062 * (i.e. thread A is in the critical section)63 * 2. thread B performs futex_trydown() operation and changes futex->count from64 * 0 to -165 * B is now obliged to call SYS_FUTEX_SLEEP syscall66 * 3. A wants to leave the critical section and does futex_up()67 * 4. A thus changes futex->count from -1 to 0 and must call SYS_FUTEX_WAKEUP68 * syscall69 * 5. B finds the wait queue empty and immediatelly aborts the conditional sleep70 * 6. No thread is queueing in the wait queue so wq->missed_wakeups changes from71 * 0 to 172 * 6. B fixes futex->count (i.e. the number of waiting threads) by changing it73 * from 0 to 174 *75 * Both scenarios allow two threads to be in the critical section76 * simultaneously. One without kernel intervention and the other through77 * wq->missed_wakeups being 1.78 *79 * To mitigate this problem, futex_down_timeout() detects that the syscall80 * didn't sleep in the wait queue, fixes the futex counter and RETRIES the81 * whole operation again.82 */83 39 84 40 /** Initialize futex counter. … … 92 48 } 93 49 94 int futex_down(futex_t *futex)95 {96 return futex_down_timeout(futex, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);97 }98 99 int futex_trydown(futex_t *futex)100 {101 return futex_down_timeout(futex, SYNCH_NO_TIMEOUT,102 SYNCH_FLAGS_NON_BLOCKING);103 }104 105 50 /** Try to down the futex. 106 51 * 107 52 * @param futex Futex. 108 * @param usec Microseconds to wait. Zero value means sleep without 109 * timeout. 110 * @param flags Select mode of operation. See comment for 111 * waitq_sleep_timeout(). 53 * @return Non-zero if the futex was acquired. 54 * @return Zero if the futex was not acquired. 55 */ 56 int futex_trydown(futex_t *futex) 57 { 58 return cas(futex, 1, 0); 59 } 60 61 /** Down the futex. 112 62 * 113 * @return ENOENT if there is no such virtual address. One of 114 * ESYNCH_OK_ATOMIC and ESYNCH_OK_BLOCKED on success or 115 * ESYNCH_TIMEOUT if the lock was not acquired because of 116 * a timeout or ESYNCH_WOULD_BLOCK if the operation could 117 * not be carried out atomically (if requested so). 63 * @param futex Futex. 64 * @return ENOENT if there is no such virtual address. 65 * @return Zero in the uncontended case. 66 * @return Otherwise one of ESYNCH_OK_ATOMIC or ESYNCH_OK_BLOCKED. 118 67 */ 119 int futex_down _timeout(futex_t *futex, uint32_t usec, int flags)68 int futex_down(futex_t *futex) 120 69 { 121 int rc; 122 123 while (atomic_predec(futex) < 0) { 124 rc = __SYSCALL3(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count, 125 (sysarg_t) usec, (sysarg_t) flags); 126 127 switch (rc) { 128 case ESYNCH_OK_ATOMIC: 129 /* 130 * Because of a race condition between timeout and 131 * futex_up() and between conditional 132 * futex_down_timeout() and futex_up(), we have to give 133 * up and try again in this special case. 134 */ 135 atomic_inc(futex); 136 break; 70 if (atomic_predec(futex) < 0) 71 return __SYSCALL1(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count); 137 72 138 case ESYNCH_TIMEOUT: 139 atomic_inc(futex); 140 return ESYNCH_TIMEOUT; 141 break; 142 143 case ESYNCH_WOULD_BLOCK: 144 /* 145 * The conditional down operation should be implemented 146 * this way. The userspace-only variant tends to 147 * accumulate missed wakeups in the kernel futex wait 148 * queue. 149 */ 150 atomic_inc(futex); 151 return ESYNCH_WOULD_BLOCK; 152 break; 153 154 case ESYNCH_OK_BLOCKED: 155 /* 156 * Enter the critical section. 157 * The futex counter has already been incremented for 158 * us. 159 */ 160 return ESYNCH_OK_BLOCKED; 161 break; 162 default: 163 return rc; 164 } 165 } 166 167 /* 168 * Enter the critical section. 169 */ 170 return ESYNCH_OK_ATOMIC; 73 return 0; 171 74 } 172 75 … … 174 77 * 175 78 * @param futex Futex. 176 * 177 * @return ENOENT if there is no such virtual address. Otherwise 178 * zero. 79 * @return ENOENT if there is no such virtual address. 80 * @return Zero in the uncontended case. 179 81 */ 180 82 int futex_up(futex_t *futex) 181 83 { 182 long val; 183 184 val = atomic_postinc(futex); 185 if (val < 0) 84 if (atomic_postinc(futex) < 0) 186 85 return __SYSCALL1(SYS_FUTEX_WAKEUP, (sysarg_t) &futex->count); 187 86 -
uspace/lib/libc/generic/io/io.c
rbc77bfa r034bf0e 341 341 size_t fread(void *buf, size_t size, size_t nmemb, FILE *stream) 342 342 { 343 size_t left = size * nmemb; 344 size_t done = 0; 345 343 size_t left, done; 344 345 if (size == 0 || nmemb == 0) 346 return 0; 347 346 348 /* Make sure no data is pending write. */ 347 349 _fflushbuf(stream); 350 351 left = size * nmemb; 352 done = 0; 348 353 349 354 while ((left > 0) && (!stream->error) && (!stream->eof)) { … … 365 370 static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream) 366 371 { 367 size_t left = size * nmemb; 368 size_t done = 0; 369 372 size_t left; 373 size_t done; 374 375 if (size == 0 || nmemb == 0) 376 return 0; 377 378 left = size * nmemb; 379 done = 0; 380 370 381 while ((left > 0) && (!stream->error)) { 371 382 ssize_t wr; … … 421 432 uint8_t b; 422 433 bool need_flush; 423 434 435 if (size == 0 || nmemb == 0) 436 return 0; 437 424 438 /* If not buffered stream, write out directly. */ 425 439 if (stream->btype == _IONBF) { -
uspace/lib/libc/generic/time.c
rbc77bfa r034bf0e 31 31 */ 32 32 /** @file 33 */ 33 */ 34 34 35 35 #include <sys/time.h> … … 40 40 #include <unistd.h> 41 41 #include <atomic.h> 42 #include <futex.h>43 42 #include <sysinfo.h> 44 43 #include <ipc/services.h> 44 #include <libc.h> 45 45 46 46 #include <sysinfo.h> … … 189 189 190 190 /** Wait unconditionally for specified number of microseconds */ 191 int usleep(unsigned long usec) 192 { 193 atomic_t futex = FUTEX_INITIALIZER; 194 195 futex_initialize(&futex, 0); 196 futex_down_timeout(&futex, usec, 0); 191 int usleep(useconds_t usec) 192 { 193 (void) __SYSCALL1(SYS_THREAD_USLEEP, usec); 197 194 return 0; 198 195 } 199 196 200 197 /** Wait unconditionally for specified number of seconds */ 201 unsigned int sleep(unsigned int seconds) 202 { 203 atomic_t futex = FUTEX_INITIALIZER; 204 205 futex_initialize(&futex, 0); 206 198 unsigned int sleep(unsigned int sec) 199 { 207 200 /* Sleep in 1000 second steps to support 208 201 full argument range */ 209 while (sec onds> 0) {210 unsigned int period = (sec onds > 1000) ? 1000 : seconds;202 while (sec > 0) { 203 unsigned int period = (sec > 1000) ? 1000 : sec; 211 204 212 futex_down_timeout(&futex, period * 1000000,0);213 sec onds-= period;205 usleep(period * 1000000); 206 sec -= period; 214 207 } 215 208 return 0; -
uspace/lib/libc/include/atomic.h
rbc77bfa r034bf0e 1 1 /* 2 * Copyright (c) 200 6Jakub Jermar2 * Copyright (c) 2009 Jakub Jermar 3 3 * All rights reserved. 4 4 * … … 36 36 #define LIBC_ATOMIC_H_ 37 37 38 typedef struct atomic {39 volatile long count;40 } atomic_t;41 42 38 #include <libarch/atomic.h> 43 44 static inline void atomic_set(atomic_t *val, long i)45 {46 val->count = i;47 }48 49 static inline long atomic_get(atomic_t *val)50 {51 return val->count;52 }53 39 54 40 #endif -
uspace/lib/libc/include/futex.h
rbc77bfa r034bf0e 46 46 extern int futex_down(futex_t *futex); 47 47 extern int futex_trydown(futex_t *futex); 48 extern int futex_down_timeout(futex_t *futex, uint32_t usec, int flags);49 48 extern int futex_up(futex_t *futex); 50 49 -
uspace/lib/libc/include/unistd.h
rbc77bfa r034bf0e 51 51 #endif 52 52 53 typedef uint32_t useconds_t; 54 53 55 extern int dup2(int oldfd, int newfd); 54 56 … … 68 70 69 71 extern void _exit(int status) __attribute__ ((noreturn)); 70 extern int usleep(u nsigned long usec);71 extern unsigned int sleep(unsigned int se conds);72 extern int usleep(useconds_t uses); 73 extern unsigned int sleep(unsigned int se); 72 74 73 75 #endif
Note:
See TracChangeset
for help on using the changeset viewer.