Changeset 387416b in mainline for uspace/lib/libc
- Timestamp:
- 2009-12-12T10:11:35Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 99de22b
- Parents:
- 58d5803d (diff), 1e4cada (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/lib/libc
- Files:
-
- 4 added
- 23 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/Makefile.build
r58d5803d r387416b 50 50 generic/as.c \ 51 51 generic/cap.c \ 52 generic/clipboard.c \ 52 53 generic/devmap.c \ 53 54 generic/event.c \ … … 56 57 generic/string.c \ 57 58 generic/fibril.c \ 58 generic/fibril_sync .c \59 generic/fibril_synch.c \ 59 60 generic/pcb.c \ 60 61 generic/smc.c \ -
uspace/lib/libc/arch/amd64/include/atomic.h
r58d5803d r387416b 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
r58d5803d r387416b 37 37 #define LIBC_arm32_ATOMIC_H_ 38 38 39 #define LIBC_ARCH_ATOMIC_H_ 40 #define CAS 41 42 #include <atomicdflt.h> 43 #include <bool.h> 44 #include <sys/types.h> 45 46 extern uintptr_t *ras_page; 47 48 static inline bool cas(atomic_t *val, long ov, long nv) 49 { 50 long ret = 0; 51 52 /* 53 * The following instructions between labels 1 and 2 constitute a 54 * Restartable Atomic Seqeunce. Should the sequence be non-atomic, 55 * the kernel will restart it. 56 */ 57 asm volatile ( 58 "1:\n" 59 " adr %[ret], 1b\n" 60 " str %[ret], %[rp0]\n" 61 " adr %[ret], 2f\n" 62 " str %[ret], %[rp1]\n" 63 " ldr %[ret], %[addr]\n" 64 " cmp %[ret], %[ov]\n" 65 " streq %[nv], %[addr]\n" 66 "2:\n" 67 " moveq %[ret], #1\n" 68 " movne %[ret], #0\n" 69 : [ret] "+&r" (ret), 70 [rp0] "=m" (ras_page[0]), 71 [rp1] "=m" (ras_page[1]), 72 [addr] "+m" (val->count) 73 : [ov] "r" (ov), 74 [nv] "r" (nv) 75 : "memory" 76 ); 77 78 ras_page[0] = 0; 79 asm volatile ("" ::: "memory"); 80 ras_page[1] = 0xffffffff; 81 82 return (bool) ret; 83 } 84 39 85 /** Atomic addition. 40 86 * … … 46 92 static inline long atomic_add(atomic_t *val, int i) 47 93 { 48 int ret; 49 volatile long * mem = &(val->count); 94 long ret = 0; 50 95 96 /* 97 * The following instructions between labels 1 and 2 constitute a 98 * Restartable Atomic Seqeunce. Should the sequence be non-atomic, 99 * the kernel will restart it. 100 */ 51 101 asm volatile ( 52 "1:\n" 53 "ldr r2, [%1]\n" 54 "add r3, r2, %2\n" 55 "str r3, %0\n" 56 "swp r3, r3, [%1]\n" 57 "cmp r3, r2\n" 58 "bne 1b\n" 102 "1:\n" 103 " adr %[ret], 1b\n" 104 " str %[ret], %[rp0]\n" 105 " adr %[ret], 2f\n" 106 " str %[ret], %[rp1]\n" 107 " ldr %[ret], %[addr]\n" 108 " add %[ret], %[ret], %[imm]\n" 109 " str %[ret], %[addr]\n" 110 "2:\n" 111 : [ret] "+&r" (ret), 112 [rp0] "=m" (ras_page[0]), 113 [rp1] "=m" (ras_page[1]), 114 [addr] "+m" (val->count) 115 : [imm] "r" (i) 116 ); 59 117 60 : "=m" (ret) 61 : "r" (mem), "r" (i) 62 : "r3", "r2" 63 ); 118 ras_page[0] = 0; 119 asm volatile ("" ::: "memory"); 120 ras_page[1] = 0xffffffff; 64 121 65 122 return ret; -
uspace/lib/libc/arch/arm32/src/entry.s
r58d5803d r387416b 36 36 # 37 37 # r1 contains the PCB pointer 38 # r2 contains the RAS page address 38 39 # 39 40 __entry: 41 # Store the RAS page address into the ras_page variable 42 ldr r0, =ras_page 43 str r2, [r0] 44 40 45 # Pass pcb_ptr to __main as the first argument (in r0) 41 46 mov r0, r1 … … 43 48 44 49 bl __exit 50 51 .data 52 53 .global ras_page 54 ras_page: 55 .long 0 56 -
uspace/lib/libc/arch/arm32/src/syscall.c
r58d5803d r387416b 60 60 register sysarg_t __arm_reg_r5 asm("r5") = p6; 61 61 register sysarg_t __arm_reg_r6 asm("r6") = id; 62 63 asm volatile ( "swi" 62 63 asm volatile ( 64 "swi 0" 64 65 : "=r" (__arm_reg_r0) 65 66 : "r" (__arm_reg_r0), … … 71 72 "r" (__arm_reg_r6) 72 73 ); 73 74 74 75 return __arm_reg_r0; 75 76 } -
uspace/lib/libc/arch/ia32/Makefile.inc
r58d5803d r387416b 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
r58d5803d r387416b 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
r58d5803d r387416b 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
r58d5803d r387416b 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
r58d5803d r387416b 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
r58d5803d r387416b 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/fibril_synch.c
r58d5803d r387416b 33 33 */ 34 34 35 #include <fibril_sync .h>35 #include <fibril_synch.h> 36 36 #include <fibril.h> 37 37 #include <async.h> -
uspace/lib/libc/generic/futex.c
r58d5803d r387416b 36 36 #include <atomic.h> 37 37 #include <libc.h> 38 #include <stdio.h>39 38 #include <sys/types.h> 40 #include <kernel/synch/synch.h>41 42 /*43 * Note about race conditions.44 * Because of non-atomic nature of operations performed sequentially on the45 * futex counter and the futex wait queue, there is a race condition:46 *47 * (wq->missed_wakeups == 1) && (futex->count = 1)48 *49 * Scenario 1 (wait queue timeout vs. futex_up()):50 * 1. assume wq->missed_wakeups == 0 && futex->count == -151 * (ie. thread A sleeping, thread B in the critical section)52 * 2. A receives timeout and gets removed from the wait queue53 * 3. B wants to leave the critical section and calls futex_up()54 * 4. B thus changes futex->count from -1 to 055 * 5. B has to call SYS_FUTEX_WAKEUP syscall to wake up the sleeping thread56 * 6. B finds the wait queue empty and changes wq->missed_wakeups from 0 to 157 * 7. A fixes futex->count (i.e. the number of waiting threads) by changing it58 * from 0 to 159 *60 * Scenario 2 (conditional down operation vs. futex_up)61 * 1. assume wq->missed_wakeups == 0 && futex->count == 062 * (i.e. thread A is in the critical section)63 * 2. thread B performs futex_trydown() operation and changes futex->count from64 * 0 to -165 * B is now obliged to call SYS_FUTEX_SLEEP syscall66 * 3. A wants to leave the critical section and does futex_up()67 * 4. A thus changes futex->count from -1 to 0 and must call SYS_FUTEX_WAKEUP68 * syscall69 * 5. B finds the wait queue empty and immediatelly aborts the conditional sleep70 * 6. No thread is queueing in the wait queue so wq->missed_wakeups changes from71 * 0 to 172 * 6. B fixes futex->count (i.e. the number of waiting threads) by changing it73 * from 0 to 174 *75 * Both scenarios allow two threads to be in the critical section76 * simultaneously. One without kernel intervention and the other through77 * wq->missed_wakeups being 1.78 *79 * To mitigate this problem, futex_down_timeout() detects that the syscall80 * didn't sleep in the wait queue, fixes the futex counter and RETRIES the81 * whole operation again.82 */83 39 84 40 /** Initialize futex counter. … … 92 48 } 93 49 94 int futex_down(futex_t *futex)95 {96 return futex_down_timeout(futex, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);97 }98 99 int futex_trydown(futex_t *futex)100 {101 return futex_down_timeout(futex, SYNCH_NO_TIMEOUT,102 SYNCH_FLAGS_NON_BLOCKING);103 }104 105 50 /** Try to down the futex. 106 51 * 107 52 * @param futex Futex. 108 * @param usec Microseconds to wait. Zero value means sleep without 109 * timeout. 110 * @param flags Select mode of operation. See comment for 111 * waitq_sleep_timeout(). 53 * @return Non-zero if the futex was acquired. 54 * @return Zero if the futex was not acquired. 55 */ 56 int futex_trydown(futex_t *futex) 57 { 58 return cas(futex, 1, 0); 59 } 60 61 /** Down the futex. 112 62 * 113 * @return ENOENT if there is no such virtual address. One of 114 * ESYNCH_OK_ATOMIC and ESYNCH_OK_BLOCKED on success or 115 * ESYNCH_TIMEOUT if the lock was not acquired because of 116 * a timeout or ESYNCH_WOULD_BLOCK if the operation could 117 * not be carried out atomically (if requested so). 63 * @param futex Futex. 64 * @return ENOENT if there is no such virtual address. 65 * @return Zero in the uncontended case. 66 * @return Otherwise one of ESYNCH_OK_ATOMIC or ESYNCH_OK_BLOCKED. 118 67 */ 119 int futex_down _timeout(futex_t *futex, uint32_t usec, int flags)68 int futex_down(futex_t *futex) 120 69 { 121 int rc; 122 123 while (atomic_predec(futex) < 0) { 124 rc = __SYSCALL3(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count, 125 (sysarg_t) usec, (sysarg_t) flags); 126 127 switch (rc) { 128 case ESYNCH_OK_ATOMIC: 129 /* 130 * Because of a race condition between timeout and 131 * futex_up() and between conditional 132 * futex_down_timeout() and futex_up(), we have to give 133 * up and try again in this special case. 134 */ 135 atomic_inc(futex); 136 break; 70 if (atomic_predec(futex) < 0) 71 return __SYSCALL1(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count); 137 72 138 case ESYNCH_TIMEOUT: 139 atomic_inc(futex); 140 return ESYNCH_TIMEOUT; 141 break; 142 143 case ESYNCH_WOULD_BLOCK: 144 /* 145 * The conditional down operation should be implemented 146 * this way. The userspace-only variant tends to 147 * accumulate missed wakeups in the kernel futex wait 148 * queue. 149 */ 150 atomic_inc(futex); 151 return ESYNCH_WOULD_BLOCK; 152 break; 153 154 case ESYNCH_OK_BLOCKED: 155 /* 156 * Enter the critical section. 157 * The futex counter has already been incremented for 158 * us. 159 */ 160 return ESYNCH_OK_BLOCKED; 161 break; 162 default: 163 return rc; 164 } 165 } 166 167 /* 168 * Enter the critical section. 169 */ 170 return ESYNCH_OK_ATOMIC; 73 return 0; 171 74 } 172 75 … … 174 77 * 175 78 * @param futex Futex. 176 * 177 * @return ENOENT if there is no such virtual address. Otherwise 178 * zero. 79 * @return ENOENT if there is no such virtual address. 80 * @return Zero in the uncontended case. 179 81 */ 180 82 int futex_up(futex_t *futex) 181 83 { 182 long val; 183 184 val = atomic_postinc(futex); 185 if (val < 0) 84 if (atomic_postinc(futex) < 0) 186 85 return __SYSCALL1(SYS_FUTEX_WAKEUP, (sysarg_t) &futex->count); 187 86 -
uspace/lib/libc/generic/io/console.c
r58d5803d r387416b 94 94 } 95 95 96 int console_get_pos(int phone, int *col, int *row) 97 { 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 96 109 void console_goto(int phone, int col, int row) 97 110 { -
uspace/lib/libc/generic/io/io.c
r58d5803d r387416b 341 341 size_t fread(void *buf, size_t size, size_t nmemb, FILE *stream) 342 342 { 343 size_t left = size * nmemb; 344 size_t done = 0; 345 343 size_t left, done; 344 345 if (size == 0 || nmemb == 0) 346 return 0; 347 346 348 /* Make sure no data is pending write. */ 347 349 _fflushbuf(stream); 350 351 left = size * nmemb; 352 done = 0; 348 353 349 354 while ((left > 0) && (!stream->error) && (!stream->eof)) { … … 365 370 static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream) 366 371 { 367 size_t left = size * nmemb; 368 size_t done = 0; 369 372 size_t left; 373 size_t done; 374 375 if (size == 0 || nmemb == 0) 376 return 0; 377 378 left = size * nmemb; 379 done = 0; 380 370 381 while ((left > 0) && (!stream->error)) { 371 382 ssize_t wr; … … 421 432 uint8_t b; 422 433 bool need_flush; 423 434 435 if (size == 0 || nmemb == 0) 436 return 0; 437 424 438 /* If not buffered stream, write out directly. */ 425 439 if (stream->btype == _IONBF) { … … 480 494 481 495 if (chr_encode(c, buf, &sz, STR_BOUNDS(1)) == EOK) { 482 size_t wr = fwrite(buf, sz, 1, stream);496 size_t wr = fwrite(buf, 1, sz, stream); 483 497 484 498 if (wr < sz) -
uspace/lib/libc/generic/string.c
r58d5803d r387416b 471 471 * null-terminated and containing only complete characters. 472 472 * 473 * @param d st Destination buffer.473 * @param dest Destination buffer. 474 474 * @param count Size of the destination buffer (must be > 0). 475 475 * @param src Source string. … … 505 505 * have to be null-terminated. 506 506 * 507 * @param d st Destination buffer.507 * @param dest Destination buffer. 508 508 * @param count Size of the destination buffer (must be > 0). 509 509 * @param src Source string. … … 537 537 * null-terminated and containing only complete characters. 538 538 * 539 * @param d st Destination buffer.539 * @param dest Destination buffer. 540 540 * @param count Size of the destination buffer. 541 541 * @param src Source string. … … 549 549 } 550 550 551 /** Copy NULL-terminated wide string to string 552 * 553 * Copy source wide string @a src to destination buffer @a dst. 554 * No more than @a size bytes are written. NULL-terminator is always 555 * written after the last succesfully copied character (i.e. if the 556 * destination buffer is has at least 1 byte, it will be always 557 * NULL-terminated). 558 * 559 * @param src Source wide string. 560 * @param dst Destination buffer. 561 * @param count Size of the destination buffer. 562 * 563 */ 564 void wstr_nstr(char *dst, const wchar_t *src, size_t size) 565 { 566 /* No space for the NULL-terminator in the buffer */ 567 if (size == 0) 568 return; 569 551 /** Convert wide string to string. 552 * 553 * Convert wide string @a src to string. The output is written to the buffer 554 * specified by @a dest and @a size. @a size must be non-zero and the string 555 * written will always be well-formed. 556 * 557 * @param dest Destination buffer. 558 * @param size Size of the destination buffer. 559 * @param src Source wide string. 560 */ 561 void wstr_to_str(char *dest, size_t size, const wchar_t *src) 562 { 570 563 wchar_t ch; 571 size_t src_idx = 0; 572 size_t dst_off = 0; 573 564 size_t src_idx; 565 size_t dest_off; 566 567 /* There must be space for a null terminator in the buffer. */ 568 assert(size > 0); 569 570 src_idx = 0; 571 dest_off = 0; 572 574 573 while ((ch = src[src_idx++]) != 0) { 575 if (chr_encode(ch, d st, &dst_off, size) != EOK)574 if (chr_encode(ch, dest, &dest_off, size - 1) != EOK) 576 575 break; 577 576 } 578 579 if (dst_off >= size) 580 dst[size - 1] = 0; 581 else 582 dst[dst_off] = 0; 577 578 dest[dest_off] = '\0'; 579 } 580 581 /** Convert wide string to new string. 582 * 583 * Convert wide string @a src to string. Space for the new string is allocated 584 * on the heap. 585 * 586 * @param src Source wide string. 587 * @return New string. 588 */ 589 char *wstr_to_astr(const wchar_t *src) 590 { 591 char dbuf[STR_BOUNDS(1)]; 592 char *str; 593 wchar_t ch; 594 595 size_t src_idx; 596 size_t dest_off; 597 size_t dest_size; 598 599 /* Compute size of encoded string. */ 600 601 src_idx = 0; 602 dest_size = 0; 603 604 while ((ch = src[src_idx++]) != 0) { 605 dest_off = 0; 606 if (chr_encode(ch, dbuf, &dest_off, STR_BOUNDS(1)) != EOK) 607 break; 608 dest_size += dest_off; 609 } 610 611 str = malloc(dest_size + 1); 612 if (str == NULL) 613 return NULL; 614 615 /* Encode string. */ 616 617 src_idx = 0; 618 dest_off = 0; 619 620 while ((ch = src[src_idx++]) != 0) { 621 if (chr_encode(ch, str, &dest_off, dest_size) != EOK) 622 break; 623 } 624 625 str[dest_size] = '\0'; 626 return str; 627 } 628 629 630 /** Convert string to wide string. 631 * 632 * Convert string @a src to wide string. The output is written to the 633 * buffer specified by @a dest and @a dlen. @a dlen must be non-zero 634 * and the wide string written will always be null-terminated. 635 * 636 * @param dest Destination buffer. 637 * @param dlen Length of destination buffer (number of wchars). 638 * @param src Source string. 639 */ 640 void str_to_wstr(wchar_t *dest, size_t dlen, const char *src) 641 { 642 size_t offset; 643 size_t di; 644 wchar_t c; 645 646 assert(dlen > 0); 647 648 offset = 0; 649 di = 0; 650 651 do { 652 if (di >= dlen - 1) 653 break; 654 655 c = str_decode(src, &offset, STR_NO_LIMIT); 656 dest[di++] = c; 657 } while (c != '\0'); 658 659 dest[dlen - 1] = '\0'; 583 660 } 584 661 -
uspace/lib/libc/generic/time.c
r58d5803d r387416b 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
r58d5803d r387416b 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/fibril_synch.h
r58d5803d r387416b 33 33 */ 34 34 35 #ifndef LIBC_FIBRIL_SYNC _H_36 #define LIBC_FIBRIL_SYNC _H_35 #ifndef LIBC_FIBRIL_SYNCH_H_ 36 #define LIBC_FIBRIL_SYNCH_H_ 37 37 38 38 #include <async.h> -
uspace/lib/libc/include/futex.h
r58d5803d r387416b 46 46 extern int futex_down(futex_t *futex); 47 47 extern int futex_trydown(futex_t *futex); 48 extern int futex_down_timeout(futex_t *futex, uint32_t usec, int flags);49 48 extern int futex_up(futex_t *futex); 50 49 -
uspace/lib/libc/include/io/console.h
r58d5803d r387416b 69 69 70 70 extern int console_get_size(int phone, int *cols, int *rows); 71 extern int console_get_pos(int phone, int *col, int *row); 71 72 extern void console_goto(int phone, int col, int row); 72 73 -
uspace/lib/libc/include/ipc/console.h
r58d5803d r387416b 43 43 CONSOLE_GET_COLOR_CAP, 44 44 CONSOLE_GET_EVENT, 45 CONSOLE_GET_POS, 45 46 CONSOLE_GOTO, 46 47 CONSOLE_CLEAR, -
uspace/lib/libc/include/ipc/services.h
r58d5803d r387416b 47 47 SERVICE_DEVMAP, 48 48 SERVICE_FHC, 49 SERVICE_OBIO 49 SERVICE_OBIO, 50 SERVICE_CLIPBOARD 50 51 } services_t; 51 52 -
uspace/lib/libc/include/string.h
r58d5803d r387416b 73 73 extern void str_append(char *dest, size_t size, const char *src); 74 74 75 extern void wstr_nstr(char *dst, const wchar_t *src, size_t size); 75 extern void wstr_to_str(char *dest, size_t size, const wchar_t *src); 76 extern char *wstr_to_astr(const wchar_t *src); 77 extern void str_to_wstr(wchar_t *dest, size_t dlen, const char *src); 76 78 77 79 extern char *str_chr(const char *str, wchar_t ch); -
uspace/lib/libc/include/unistd.h
r58d5803d r387416b 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.