Changes in / [034bf0e:bc77bfa] in mainline
- Files:
-
- 1 deleted
- 37 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile
r034bf0e rbc77bfa 43 43 $(MAKE) -C kernel clean 44 44 $(MAKE) -C kernel EXTRA_TOOL=stanse 45 $(STANSE) --checker ReachabilityChecker -- jobfile kernel/kernel.job45 $(STANSE) --checker ReachabilityChecker --checker ThreadChecker:contrib/$(STANSE)/ThreadChecker.xml --jobfile kernel/kernel.job 46 46 47 47 cscope: -
kernel/arch/amd64/src/amd64.c
r034bf0e rbc77bfa 67 67 #include <ddi/irq.h> 68 68 #include <sysinfo/sysinfo.h> 69 #include <memstr.h>70 69 71 70 /** Disable I/O on non-privileged levels -
kernel/arch/arm32/include/atomic.h
r034bf0e rbc77bfa 37 37 #define KERN_arm32_ATOMIC_H_ 38 38 39 #include <arch/asm.h>40 41 39 /** Atomic addition. 42 40 * … … 49 47 static inline long atomic_add(atomic_t *val, int i) 50 48 { 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); 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 ); 61 64 62 65 return ret; -
kernel/arch/arm32/src/mm/as.c
r034bf0e rbc77bfa 36 36 #include <arch/mm/as.h> 37 37 #include <genarch/mm/as_pt.h> 38 #include <genarch/mm/page_pt.h>39 38 #include <genarch/mm/asid_fifo.h> 40 39 #include <mm/as.h> -
kernel/arch/ia32/src/ia32.c
r034bf0e rbc77bfa 68 68 #include <sysinfo/sysinfo.h> 69 69 #include <arch/boot/boot.h> 70 #include <memstr.h>71 70 72 71 #ifdef CONFIG_SMP -
kernel/arch/ia64/src/cpu/cpu.c
r034bf0e rbc77bfa 37 37 #include <arch/register.h> 38 38 #include <print.h> 39 #include <memstr.h>40 39 41 40 void cpu_arch_init(void) -
kernel/arch/ppc32/src/mm/as.c
r034bf0e rbc77bfa 35 35 #include <arch/mm/as.h> 36 36 #include <genarch/mm/as_pt.h> 37 #include <genarch/mm/page_pt.h>38 37 #include <genarch/mm/asid_fifo.h> 39 38 #include <arch.h> -
kernel/arch/ppc32/src/mm/tlb.c
r034bf0e rbc77bfa 38 38 #include <interrupt.h> 39 39 #include <mm/as.h> 40 #include <mm/page.h>41 40 #include <arch.h> 42 41 #include <print.h> -
kernel/arch/ppc32/src/ppc32.c
r034bf0e rbc77bfa 44 44 #include <genarch/ofw/pci.h> 45 45 #include <userspace.h> 46 #include <mm/page.h>47 46 #include <proc/uarg.h> 48 47 #include <console/console.h> -
kernel/arch/sparc64/src/mm/tlb.c
r034bf0e rbc77bfa 37 37 #include <mm/as.h> 38 38 #include <mm/asid.h> 39 #include <genarch/mm/page_ht.h>40 39 #include <arch/mm/frame.h> 41 40 #include <arch/mm/page.h> -
kernel/genarch/src/drivers/via-cuda/cuda.c
r034bf0e rbc77bfa 41 41 #include <ddi/device.h> 42 42 #include <synch/spinlock.h> 43 #include <memstr.h>44 43 45 44 static irq_ownership_t cuda_claim(irq_t *irq); -
kernel/genarch/src/fb/fb.c
r034bf0e rbc77bfa 41 41 #include <console/console.h> 42 42 #include <sysinfo/sysinfo.h> 43 #include <mm/page.h>44 43 #include <mm/slab.h> 45 44 #include <align.h> -
kernel/generic/include/arch.h
r034bf0e rbc77bfa 39 39 #include <proc/thread.h> 40 40 #include <proc/task.h> 41 #include <mm/as.h>42 41 43 42 #define DEFAULT_CONTEXT 0 -
kernel/generic/include/proc/task.h
r034bf0e rbc77bfa 55 55 #include <udebug/udebug.h> 56 56 #include <ipc/kbox.h> 57 #include <mm/as.h>58 57 59 58 #define TASK_NAME_BUFLEN 20 -
kernel/generic/include/proc/thread.h
r034bf0e rbc77bfa 225 225 226 226 extern void thread_init(void); 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 * );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); 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 * );234 extern void thread_create_arch(thread_t *t); 235 235 #endif 236 236 #ifndef thr_constructor_arch 237 extern void thr_constructor_arch(thread_t * );237 extern void thr_constructor_arch(thread_t *t); 238 238 #endif 239 239 #ifndef thr_destructor_arch 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 );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); 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 *, uint32_t, int); 249 extern void thread_detach(thread_t *); 250 251 extern void thread_register_call_me(void (*)(void *), void *); 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); 252 253 extern void thread_print_list(void); 253 extern void thread_destroy(thread_t * );254 extern void thread_destroy(thread_t *t); 254 255 extern void thread_update_accounting(void); 255 extern bool thread_exists(thread_t * );256 extern bool thread_exists(thread_t *t); 256 257 257 258 /** Fpu context slab cache. */ … … 259 260 260 261 /* Thread syscall prototypes. */ 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); 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); 266 266 267 267 #endif -
kernel/generic/include/synch/futex.h
r034bf0e rbc77bfa 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> 40 42 41 43 /** Kernel-side futex structure. */ … … 52 54 53 55 extern void futex_init(void); 54 extern unative_t sys_futex_sleep(uintptr_t); 55 extern unative_t sys_futex_wakeup(uintptr_t); 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); 56 59 57 60 extern void futex_cleanup(void); -
kernel/generic/include/syscall/syscall.h
r034bf0e rbc77bfa 43 43 SYS_THREAD_EXIT, 44 44 SYS_THREAD_GET_ID, 45 SYS_THREAD_USLEEP,46 45 47 46 SYS_TASK_GET_ID, -
kernel/generic/src/mm/backend_phys.c
r034bf0e rbc77bfa 40 40 #include <arch/types.h> 41 41 #include <mm/as.h> 42 #include <mm/page.h>43 42 #include <mm/frame.h> 44 43 #include <mm/slab.h> -
kernel/generic/src/proc/task.c
r034bf0e rbc77bfa 54 54 #include <func.h> 55 55 #include <string.h> 56 #include <memstr.h>57 56 #include <syscall/copy.h> 58 57 #include <macros.h> -
kernel/generic/src/proc/thread.c
r034bf0e rbc77bfa 501 501 void thread_sleep(uint32_t sec) 502 502 { 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 } 503 thread_usleep(sec * 1000000); 511 504 } 512 505 … … 582 575 { 583 576 waitq_t wq; 584 577 585 578 waitq_initialize(&wq); 586 579 587 580 (void) waitq_sleep_timeout(&wq, usec, SYNCH_FLAGS_NON_BLOCKING); 588 581 } … … 819 812 } 820 813 821 /** Syscall wrapper for sleeping. */822 unative_t sys_thread_usleep(uint32_t usec)823 {824 thread_usleep(usec);825 return 0;826 }827 828 814 /** @} 829 815 */ -
kernel/generic/src/synch/futex.c
r034bf0e rbc77bfa 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 * 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) 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) 111 113 { 112 114 futex_t *futex; … … 138 140 udebug_stoppable_begin(); 139 141 #endif 140 rc = waitq_sleep_timeout(&futex->wq, 0, SYNCH_FLAGS_INTERRUPTIBLE); 142 rc = waitq_sleep_timeout(&futex->wq, usec, flags | 143 SYNCH_FLAGS_INTERRUPTIBLE); 144 141 145 #ifdef CONFIG_UDEBUG 142 146 udebug_stoppable_end(); … … 147 151 /** Wakeup one thread waiting in futex wait queue. 148 152 * 149 * @param uaddr 150 * 151 * @return 153 * @param uaddr Userspace address of the futex counter. 154 * 155 * @return ENOENT if there is no physical mapping for uaddr. 152 156 */ 153 157 unative_t sys_futex_wakeup(uintptr_t uaddr) … … 186 190 * If the structure does not exist already, a new one is created. 187 191 * 188 * @param paddr 189 * 190 * @return 192 * @param paddr Physical address of the userspace futex counter. 193 * 194 * @return Address of the kernel futex structure. 191 195 */ 192 196 futex_t *futex_find(uintptr_t paddr) … … 280 284 /** Compute hash index into futex hash table. 281 285 * 282 * @param key Address where the key (i.e. physical address of futex283 * counter) isstored.284 * 285 * @return 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. 286 290 */ 287 291 size_t futex_ht_hash(unative_t *key) … … 292 296 /** Compare futex hash table item with a key. 293 297 * 294 * @param key Address where the key (i.e. physical address of futex295 * counter) isstored.296 * 297 * @return 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. 298 302 */ 299 303 bool futex_ht_compare(unative_t *key, size_t keys, link_t *item) … … 309 313 /** Callback for removal items from futex hash table. 310 314 * 311 * @param item 315 * @param item Item removed from the hash table. 312 316 */ 313 317 void futex_ht_remove_callback(link_t *item) -
kernel/generic/src/syscall/syscall.c
r034bf0e rbc77bfa 62 62 63 63 #ifdef CONFIG_UDEBUG 64 bool debug; 65 64 66 /* 65 67 * Early check for undebugged tasks. We do not lock anything as this 66 * test need not be precise in either direction.68 * test need not be precise in either way. 67 69 */ 68 if (THREAD->udebug.active) { 70 debug = THREAD->udebug.active; 71 72 if (debug) { 69 73 udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, 0, false); 70 74 } … … 83 87 84 88 #ifdef CONFIG_UDEBUG 85 if ( THREAD->udebug.active) {89 if (debug) { 86 90 udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc, true); 87 91 … … 107 111 (syshandler_t) sys_thread_exit, 108 112 (syshandler_t) sys_thread_get_id, 109 (syshandler_t) sys_thread_usleep,110 113 111 114 (syshandler_t) sys_task_get_id, … … 114 117 115 118 /* Synchronization related syscalls. */ 116 (syshandler_t) sys_futex_sleep ,119 (syshandler_t) sys_futex_sleep_timeout, 117 120 (syshandler_t) sys_futex_wakeup, 118 121 (syshandler_t) sys_smc_coherence, -
kernel/generic/src/udebug/udebug_ops.c
r034bf0e rbc77bfa 50 50 #include <udebug/udebug.h> 51 51 #include <udebug/udebug_ops.h> 52 #include <memstr.h>53 52 54 53 /** -
uspace/lib/libc/arch/amd64/include/atomic.h
r034bf0e rbc77bfa 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>43 39 44 40 static inline void atomic_inc(atomic_t *val) { -
uspace/lib/libc/arch/arm32/include/atomic.h
r034bf0e rbc77bfa 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 65 39 /** Atomic addition. 66 40 * … … 75 49 volatile long * mem = &(val->count); 76 50 77 /* FIXME: is not atomic, is broken */78 51 asm volatile ( 79 52 "1:\n" -
uspace/lib/libc/arch/ia32/Makefile.inc
r034bf0e rbc77bfa 39 39 arch/$(UARCH)/src/setjmp.S 40 40 41 GCC_CFLAGS += -march=pentium42 41 LFLAGS += -N 43 42 -
uspace/lib/libc/arch/ia32/include/atomic.h
r034bf0e rbc77bfa 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>41 37 42 38 static inline void atomic_inc(atomic_t *val) { -
uspace/lib/libc/arch/ia64/include/atomic.h
r034bf0e rbc77bfa 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>41 37 42 38 static inline void atomic_inc(atomic_t *val) -
uspace/lib/libc/arch/mips32/include/atomic.h
r034bf0e rbc77bfa 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>42 38 43 39 #define atomic_inc(x) ((void) atomic_add(x, 1)) -
uspace/lib/libc/arch/ppc32/include/atomic.h
r034bf0e rbc77bfa 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>41 37 42 38 static inline void atomic_inc(atomic_t *val) -
uspace/lib/libc/arch/sparc64/include/atomic.h
r034bf0e rbc77bfa 36 36 #define LIBC_sparc64_ATOMIC_H_ 37 37 38 #define LIBC_ARCH_ATOMIC_H_39 40 #include <atomicdflt.h>41 38 #include <sys/types.h> 42 39 -
uspace/lib/libc/generic/futex.c
r034bf0e rbc77bfa 36 36 #include <atomic.h> 37 37 #include <libc.h> 38 #include <stdio.h> 38 39 #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 */ 39 83 40 84 /** Initialize futex counter. … … 48 92 } 49 93 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 50 105 /** Try to down the futex. 51 106 * 52 107 * @param futex Futex. 53 * @return Non-zero if the futex was acquired. 54 * @return Zero if the futex was not acquired. 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(). 112 * 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). 55 118 */ 56 int futex_ trydown(futex_t *futex)119 int futex_down_timeout(futex_t *futex, uint32_t usec, int flags) 57 120 { 58 return cas(futex, 1, 0); 59 } 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; 60 137 61 /** Down the futex. 62 * 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. 67 */ 68 int futex_down(futex_t *futex) 69 { 70 if (atomic_predec(futex) < 0) 71 return __SYSCALL1(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count); 138 case ESYNCH_TIMEOUT: 139 atomic_inc(futex); 140 return ESYNCH_TIMEOUT; 141 break; 72 142 73 return 0; 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; 74 171 } 75 172 … … 77 174 * 78 175 * @param futex Futex. 79 * @return ENOENT if there is no such virtual address. 80 * @return Zero in the uncontended case. 176 * 177 * @return ENOENT if there is no such virtual address. Otherwise 178 * zero. 81 179 */ 82 180 int futex_up(futex_t *futex) 83 181 { 84 if (atomic_postinc(futex) < 0) 182 long val; 183 184 val = atomic_postinc(futex); 185 if (val < 0) 85 186 return __SYSCALL1(SYS_FUTEX_WAKEUP, (sysarg_t) &futex->count); 86 187 -
uspace/lib/libc/generic/io/io.c
r034bf0e rbc77bfa 341 341 size_t fread(void *buf, size_t size, size_t nmemb, FILE *stream) 342 342 { 343 size_t left, done; 344 345 if (size == 0 || nmemb == 0) 346 return 0; 347 343 size_t left = size * nmemb; 344 size_t done = 0; 345 348 346 /* Make sure no data is pending write. */ 349 347 _fflushbuf(stream); 350 351 left = size * nmemb;352 done = 0;353 348 354 349 while ((left > 0) && (!stream->error) && (!stream->eof)) { … … 370 365 static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream) 371 366 { 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 367 size_t left = size * nmemb; 368 size_t done = 0; 369 381 370 while ((left > 0) && (!stream->error)) { 382 371 ssize_t wr; … … 432 421 uint8_t b; 433 422 bool need_flush; 434 435 if (size == 0 || nmemb == 0) 436 return 0; 437 423 438 424 /* If not buffered stream, write out directly. */ 439 425 if (stream->btype == _IONBF) { -
uspace/lib/libc/generic/time.c
r034bf0e rbc77bfa 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> 42 43 #include <sysinfo.h> 43 44 #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(useconds_t usec) 192 { 193 (void) __SYSCALL1(SYS_THREAD_USLEEP, usec); 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); 194 197 return 0; 195 198 } 196 199 197 200 /** Wait unconditionally for specified number of seconds */ 198 unsigned int sleep(unsigned int sec) 199 { 201 unsigned int sleep(unsigned int seconds) 202 { 203 atomic_t futex = FUTEX_INITIALIZER; 204 205 futex_initialize(&futex, 0); 206 200 207 /* Sleep in 1000 second steps to support 201 208 full argument range */ 202 while (sec > 0) {203 unsigned int period = (sec > 1000) ? 1000 : sec;209 while (seconds > 0) { 210 unsigned int period = (seconds > 1000) ? 1000 : seconds; 204 211 205 usleep(period * 1000000);206 sec -= period;212 futex_down_timeout(&futex, period * 1000000, 0); 213 seconds -= period; 207 214 } 208 215 return 0; -
uspace/lib/libc/include/atomic.h
r034bf0e rbc77bfa 1 1 /* 2 * Copyright (c) 200 9Jakub Jermar2 * Copyright (c) 2006 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 38 42 #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 } 39 53 40 54 #endif -
uspace/lib/libc/include/futex.h
r034bf0e rbc77bfa 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); 48 49 extern int futex_up(futex_t *futex); 49 50 -
uspace/lib/libc/include/unistd.h
r034bf0e rbc77bfa 51 51 #endif 52 52 53 typedef uint32_t useconds_t;54 55 53 extern int dup2(int oldfd, int newfd); 56 54 … … 70 68 71 69 extern void _exit(int status) __attribute__ ((noreturn)); 72 extern int usleep(u seconds_t uses);73 extern unsigned int sleep(unsigned int se );70 extern int usleep(unsigned long usec); 71 extern unsigned int sleep(unsigned int seconds); 74 72 75 73 #endif
Note:
See TracChangeset
for help on using the changeset viewer.