Changeset 7bf29e5 in mainline for uspace/lib/c


Ignore:
Timestamp:
2025-01-09T11:29:38Z (6 months ago)
Author:
Miroslav Cimerman <mc@…>
Children:
a5c2960e
Parents:
bc3d695 (diff), 4e1221c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge 'upstream/master' into helenraid-para

Location:
uspace/lib/c
Files:
29 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/arch/abs32le/include/libarch/thread.h

    rbc3d695 r7bf29e5  
    3636#define _LIBC_abs32le_THREAD_H_
    3737
     38#include <align.h>
     39
     40static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     41    void (*main)(void *), void *arg)
     42{
     43        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size, 16);
     44
     45        sp[-1] = (uintptr_t) arg;
     46        sp[-2] = (uintptr_t) main;
     47
     48        return (uintptr_t) sp;
     49}
     50
    3851#endif
    3952
  • uspace/lib/c/arch/abs32le/src/thread_entry.c

    rbc3d695 r7bf29e5  
    3030 */
    3131
     32#include <stdbool.h>
    3233#include <stddef.h>
    3334#include "../../../generic/private/thread.h"
     
    3536void __thread_entry(void)
    3637{
    37         __thread_main(NULL);
     38        while (true)
     39                ;
    3840}
    3941
  • uspace/lib/c/arch/amd64/include/libarch/thread.h

    rbc3d695 r7bf29e5  
    3636#define _LIBC_amd64_THREAD_H_
    3737
     38#include <align.h>
     39#include <stddef.h>
     40#include <stdint.h>
     41
     42static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     43    void (*main)(void *), void *arg)
     44{
     45        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size, 16);
     46
     47        *--sp = (uintptr_t) arg;
     48        *--sp = (uintptr_t) main;
     49
     50        return (uintptr_t) sp;
     51}
     52
    3853#endif
    3954
  • uspace/lib/c/arch/amd64/src/thread_entry.S

    rbc3d695 r7bf29e5  
    3535#
    3636SYMBOL_BEGIN(__thread_entry)
     37        # Pop libc thread entry function and argument
     38        popq %rax
     39        popq %rdi
     40
    3741        #
    3842        # Create the first stack frame.
     
    4246        movq %rsp, %rbp
    4347
    44         #
    45         # RAX contains address of uarg
    46         #
    47         movq %rax, %rdi
    48         call FUNCTION_REF(__thread_main)
     48        call *%rax
    4949SYMBOL_END(__thread_entry)
  • uspace/lib/c/arch/arm32/include/libarch/thread.h

    rbc3d695 r7bf29e5  
    3737#define _LIBC_arm32_THREAD_H_
    3838
     39#include <align.h>
     40
     41static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     42    void (*main)(void *), void *arg)
     43{
     44        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size, 16);
     45
     46        *--sp = (uintptr_t) main;
     47        *--sp = (uintptr_t) arg;
     48
     49        return (uintptr_t) sp;
     50}
     51
    3952#endif
    4053
  • uspace/lib/c/arch/arm32/src/thread_entry.S

    rbc3d695 r7bf29e5  
    3535#
    3636SYMBOL(__thread_entry)
     37        # Pop libc entry function and its argument.
     38        pop { r0, r4 }
     39
    3740        #
    3841        # Create the first stack frame.
     
    4346        sub fp, ip, #4
    4447
    45         b __thread_main
     48        bx r4
  • uspace/lib/c/arch/arm64/include/libarch/thread.h

    rbc3d695 r7bf29e5  
    3636#define _LIBC_arm64_THREAD_H_
    3737
     38#include <align.h>
     39
     40static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     41    void (*main)(void *), void *arg)
     42{
     43        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size, 16);
     44
     45        *--sp = (uintptr_t) arg;
     46        *--sp = (uintptr_t) main;
     47
     48        return (uintptr_t) sp;
     49}
     50
    3851#endif
    3952
  • uspace/lib/c/arch/arm64/src/thread_entry.S

    rbc3d695 r7bf29e5  
    3535#
    3636SYMBOL(__thread_entry)
    37         #
     37        # Load entry function and argument from stack.
     38        ldp x1, x0, [sp], #16
     39
    3840        # Create the first stack frame.
    39         #
    4041        mov x29, #0
    4142        stp x29, x30, [sp, #-16]!
    4243        mov x29, sp
    4344
    44         b __thread_main
     45        br x1
  • uspace/lib/c/arch/ia32/include/libarch/thread.h

    rbc3d695 r7bf29e5  
    3636#define _LIBC_ia32_THREAD_H_
    3737
     38#include <align.h>
     39#include <stddef.h>
     40#include <stdint.h>
     41
     42static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     43    void (*main)(void *), void *arg)
     44{
     45        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size, 16);
     46
     47        *--sp = (uintptr_t) arg;
     48        *--sp = (uintptr_t) main;
     49
     50        return (uintptr_t) sp;
     51}
     52
    3853#endif
    3954
  • uspace/lib/c/arch/ia32/src/syscall.S

    rbc3d695 r7bf29e5  
    7777        pushl %ebp
    7878        mov %esp, %ebp
    79         lea ra, %edi
    8079        movl 20(%esp), %edx     # First argument.
    8180        movl 24(%esp), %ecx     # Second argument.
     
    8382        movl 32(%esp), %esi     # Fourth argument.
    8483        movl 44(%esp), %eax     # Syscall number.
    85         sysenter
    86 ra:
     84        call 1f
    8785        movw %cs, %cx
    8886        addw $8, %cx
     
    9593        popl %ebx
    9694        ret
     95
     96        /* Trampoline for entering kernel */
     971:
     98        pop %edi
     99        sysenter
    97100FUNCTION_END(__syscall_fast)
  • uspace/lib/c/arch/ia32/src/thread_entry.S

    rbc3d695 r7bf29e5  
    4141        # Do not set %gs, it contains descriptor that can see TLS
    4242
     43        # Pop libc thread main function.
     44        popl %eax
     45        # Pop argument.
     46        popl %ebx
     47
    4348        #
    4449        # Create the first stack frame.
     
    4853        mov %esp, %ebp
    4954
    50         #
    51         # EAX contains address of uarg.
    52         #
    53         pushl %eax
    54         call __thread_main
     55        pushl %ebx
     56        call *%eax
    5557
    5658        #
  • uspace/lib/c/arch/ia64/include/libarch/thread.h

    rbc3d695 r7bf29e5  
    3636#define _LIBC_ia64_THREAD_H_
    3737
     38#include <align.h>
     39
     40static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     41    void (*main)(void *), void *arg)
     42{
     43        uintptr_t *sp = (uintptr_t *) (ALIGN_DOWN((uintptr_t) stack + stack_size / 2, 16));
     44
     45        /* Store data under stack pointer */
     46        sp[-1] = (uintptr_t) arg;
     47        sp[-2] = (uintptr_t) main;
     48
     49        return (uintptr_t) sp;
     50}
     51
    3852#endif
    3953
  • uspace/lib/c/arch/ia64/src/thread_entry.S

    rbc3d695 r7bf29e5  
    3737        alloc loc0 = ar.pfs, 0, 1, 1, 0
    3838
    39 #ifndef CONFIG_RTLD
    40         # XXX This does not work in a shared library
    41         movl gp = __gp
    42 #endif
     39        add r8 = -8, sp ;;
     40        # Entry function argument
     41        ld8 out0 = [r8], -8 ;;
    4342
    44         #
    45         # r8 contains address of uarg structure.
    46         #
     43        # Entry function descriptor
     44        ld8 r8 = [r8] ;;
     45        # Entry function address
     46        ld8 r9 = [r8], 8 ;;
     47        # Entry function global pointer
     48        ld8 gp = [r8] ;;
    4749
    48         mov out0 = r8 ;;
    49         # XXX br.call.sptk.many b0 = FUNCTION_REF(__thread_main)
    50         br.call.sptk.many b0 = __thread_main
     50        mov b1 = r9 ;;
     51
     52        br.call.sptk.many b0 = b1 ;;
    5153
    5254        #
  • uspace/lib/c/arch/mips32/include/libarch/thread.h

    rbc3d695 r7bf29e5  
    3737#define _LIBC_mips32_THREAD_H_
    3838
     39#include <align.h>
     40
     41static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     42    void (*main)(void *), void *arg)
     43{
     44        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size, 16);
     45
     46        sp[-1] = (uintptr_t) arg;
     47        sp[-2] = (uintptr_t) main;
     48
     49        return (uintptr_t) sp;
     50}
     51
    3952#endif
    4053
  • uspace/lib/c/arch/mips32/src/thread_entry.S

    rbc3d695 r7bf29e5  
    4040#
    4141SYMBOL(__thread_entry)
    42         .ent __thread_entry
    43         .frame $sp, ABI_STACK_FRAME, $ra
    44         .cpload $t9
     42        # All registers should be zero, including $fp and $ra.
     43        # Instead of setting up a stack frame here, we leave it for __thread_main.
    4544
    46         #
    47         # v0 contains address of uarg.
    48         #
    49         add $a0, $v0, 0
     45        # Function argument.
     46        lw $a0, -4($sp)
     47        # Function pointer.
     48        lw $t0, -8($sp)
    5049
    51         # Allocate the stack frame.
    52         addiu $sp, -ABI_STACK_FRAME
    53 
    54         # Allow PIC code
    55         .cprestore 16
    56 
    57         jal __thread_main
     50        j $t0
    5851        nop
    59 
    60         #
    61         # Not reached.
    62         #
    63         addiu $sp, ABI_STACK_FRAME
    64         .end __thread_entry
  • uspace/lib/c/arch/ppc32/include/libarch/thread.h

    rbc3d695 r7bf29e5  
    3636#define _LIBC_ppc32_THREAD_H_
    3737
     38#include <align.h>
     39
     40static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     41    void (*main)(void *), void *arg)
     42{
     43        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size - sizeof(void *), 16);
     44
     45        sp[0] = 0;
     46        sp[-1] = (uintptr_t) arg;
     47        sp[-2] = (uintptr_t) main;
     48
     49        return (uintptr_t) sp;
     50}
     51
    3852#endif
    3953
  • uspace/lib/c/arch/ppc32/src/thread_entry.S

    rbc3d695 r7bf29e5  
    3535#
    3636SYMBOL(__thread_entry)
    37         #
    38         # Create the first stack frame.
    39         #
    40         li %r4, 0
    41         stw %r4, 0(%r1)
    42         stwu %r1, -16(%r1)
     37        # Load function and argument.
     38        lwz %r3, -4(%r1)
     39        lwz %r4, -8(%r1)
    4340
    44         b __thread_main
     41        # Clear LR
     42        li %r0, 0
     43        mtlr %r0
    4544
     45        mtctr %r4
     46        bctr
  • uspace/lib/c/arch/riscv64/include/libarch/thread.h

    rbc3d695 r7bf29e5  
    3636#define _LIBC_riscv64_THREAD_H_
    3737
     38#include <align.h>
     39
     40static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     41    void (*main)(void *), void *arg)
     42{
     43        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size, 16);
     44
     45        sp[-1] = (uintptr_t) arg;
     46        sp[-2] = (uintptr_t) main;
     47
     48        return (uintptr_t) sp;
     49}
     50
    3851#endif
    3952
  • uspace/lib/c/arch/riscv64/src/thread_entry.c

    rbc3d695 r7bf29e5  
    3535void __thread_entry(void)
    3636{
    37         __thread_main((void *) 0);
     37        // TODO
     38        while (true)
     39                ;
    3840}
    3941
  • uspace/lib/c/arch/sparc64/include/libarch/thread.h

    rbc3d695 r7bf29e5  
    3535#define _LIBC_sparc64_THREAD_H_
    3636
     37#include <assert.h>
     38#include <align.h>
     39#include <libarch/stack.h>
     40
     41static inline uintptr_t arch_thread_prepare(void *stack, size_t stack_size,
     42    void (*main)(void *), void *arg)
     43{
     44        /* We must leave space above the stack pointer for initial register spill area. */
     45        uintptr_t *sp = (uintptr_t *) ALIGN_DOWN((uintptr_t) stack + stack_size - STACK_WINDOW_SAVE_AREA_SIZE - STACK_ARG_SAVE_AREA_SIZE, 16);
     46
     47        sp[-1] = (uintptr_t) arg;
     48        sp[-2] = (uintptr_t) main;
     49
     50        return ((uintptr_t) sp) - STACK_BIAS;
     51}
     52
    3753#endif
    3854
  • uspace/lib/c/arch/sparc64/src/thread_entry.S

    rbc3d695 r7bf29e5  
    3535#
    3636SYMBOL(__thread_entry)
     37        add %sp, 0x7ff, %g1
     38
    3739        #
    3840        # Create the first stack frame.
     
    4345
    4446        #
    45         # Propagate the input arguments to the new window.
     47        # Load libc entry point address and argument from stack
    4648        #
     49        ldn [%g1 - 8], %o0
     50        ldn [%g1 - 16], %g1
    4751
    48         call __thread_main              ! %o0 contains address of uarg
    49         mov %i0, %o0
     52        jmpl %g1, %r0
     53        # Wipe link register
     54        xor %o7, %o7, %o7
    5055
    5156        ! not reached
  • uspace/lib/c/generic/malloc.c

    rbc3d695 r7bf29e5  
    3838#include <stdbool.h>
    3939#include <stddef.h>
     40#include <stdio.h>
    4041#include <as.h>
    4142#include <align.h>
     
    725726 *
    726727 */
    727 static void *malloc_internal(const size_t size, const size_t align)
     728static void *malloc_internal(size_t size, size_t align)
    728729{
    729730        malloc_assert(first_heap_area != NULL);
    730731
     732        if (size == 0)
     733                size = 1;
     734
    731735        if (align == 0)
    732                 return NULL;
     736                align = BASE_ALIGN;
    733737
    734738        size_t falign = lcm(align, BASE_ALIGN);
     
    821825 *
    822826 */
    823 void *realloc(void *const addr, const size_t size)
     827void *realloc(void *const addr, size_t size)
    824828{
    825829        if (size == 0) {
    826                 free(addr);
    827                 return NULL;
     830                fprintf(stderr, "realloc() called with size 0\n");
     831                size = 1;
    828832        }
    829833
     
    930934}
    931935
     936/** Reallocate memory for an array
     937 *
     938 * Same as realloc(ptr, nelem * elsize), except the multiplication is checked
     939 * for numerical overflow. Borrowed from POSIX 2024.
     940 *
     941 * @param ptr
     942 * @param nelem
     943 * @param elsize
     944 *
     945 * @return Reallocated memory or NULL.
     946 */
     947void *reallocarray(void *ptr, size_t nelem, size_t elsize)
     948{
     949        if (nelem > SIZE_MAX / elsize)
     950                return NULL;
     951
     952        return realloc(ptr, nelem * elsize);
     953}
     954
    932955/** Free a memory block
    933956 *
  • uspace/lib/c/generic/private/fibril.h

    rbc3d695 r7bf29e5  
    3333#include <context.h>
    3434#include <tls.h>
    35 #include <abi/proc/uarg.h>
    3635#include <fibril.h>
    3736#include <ipc/common.h>
     
    5049        context_t ctx;
    5150
    52         uspace_arg_t uarg;
    5351        link_t link;
    5452        void *stack;
  • uspace/lib/c/generic/private/thread.h

    rbc3d695 r7bf29e5  
    3737
    3838#include <time.h>
    39 #include <abi/proc/uarg.h>
    4039#include <libarch/thread.h>
    4140#include <abi/proc/thread.h>
    4241
    4342extern void __thread_entry(void);
    44 extern void __thread_main(uspace_arg_t *);
    4543
    46 extern errno_t thread_create(void (*)(void *), void *, const char *,
    47     thread_id_t *);
     44extern errno_t thread_create(errno_t (*)(void *), void *, const char *);
    4845extern void thread_exit(int) __attribute__((noreturn));
    49 extern void thread_detach(thread_id_t);
    5046extern thread_id_t thread_get_id(void);
    5147extern void thread_usleep(usec_t);
  • uspace/lib/c/generic/thread/fibril.c

    rbc3d695 r7bf29e5  
    781781}
    782782
    783 static void _runner_fn(void *arg)
     783static errno_t _runner_fn(void *arg)
    784784{
    785785        _helper_fibril_fn(arg);
     786        return EOK;
    786787}
    787788
     
    808809
    809810        for (int i = 0; i < n; i++) {
    810                 thread_id_t tid;
    811                 rc = thread_create(_runner_fn, NULL, "fibril runner", &tid);
     811                rc = thread_create(_runner_fn, NULL, "fibril runner");
    812812                if (rc != EOK)
    813813                        return i;
    814                 thread_detach(tid);
    815814        }
    816815
  • uspace/lib/c/generic/thread/thread.c

    rbc3d695 r7bf29e5  
    3737#include <stdlib.h>
    3838#include <libarch/faddr.h>
    39 #include <abi/proc/uarg.h>
    4039#include <fibril.h>
    4140#include <stack.h>
     
    5453 * and exit when thread returns back.
    5554 *
    56  * @param uarg Pointer to userspace argument structure.
     55 * @param arg Fibril pointer.
    5756 *
    5857 */
    59 void __thread_main(uspace_arg_t *uarg)
     58static void __thread_main(void *arg)
    6059{
     60        fibril_t *fibril = arg;
     61
    6162        assert(!__tcb_is_set());
    62 
    63         fibril_t *fibril = uarg->uspace_thread_arg;
    6463        assert(fibril);
    6564
    6665        __tcb_set(fibril->tcb);
    6766
    68         uarg->uspace_thread_function(fibril->arg);
     67        fibril->func(fibril->arg);
    6968        /*
    7069         * XXX: we cannot free the userspace stack while running on it
     
    9089 * @return Zero on success or a code from @ref errno.h on failure.
    9190 */
    92 errno_t thread_create(void (*function)(void *), void *arg, const char *name,
    93     thread_id_t *tid)
     91errno_t thread_create(errno_t (*func)(void *), void *arg, const char *name)
    9492{
    95         uspace_arg_t *uarg = calloc(1, sizeof(uspace_arg_t));
    96         if (!uarg)
     93        fibril_t *fibril = fibril_alloc();
     94        if (!fibril)
    9795                return ENOMEM;
    9896
    99         fibril_t *fibril = fibril_alloc();
    100         if (!fibril) {
    101                 free(uarg);
    102                 return ENOMEM;
    103         }
     97        fibril->func = func;
     98        fibril->arg = arg;
    10499
    105100        size_t stack_size = stack_size_get();
     
    109104        if (stack == AS_MAP_FAILED) {
    110105                fibril_teardown(fibril);
    111                 free(uarg);
    112106                return ENOMEM;
    113107        }
    114108
    115         fibril->arg = arg;
    116         uarg->uspace_entry = (void *) FADDR(__thread_entry);
    117         uarg->uspace_stack = stack;
    118         uarg->uspace_stack_size = stack_size;
    119         uarg->uspace_thread_function = function;
    120         uarg->uspace_thread_arg = fibril;
    121         uarg->uspace_uarg = uarg;
     109        uintptr_t sp = arch_thread_prepare(stack, stack_size, __thread_main,
     110            fibril);
    122111
    123         errno_t rc = (errno_t) __SYSCALL4(SYS_THREAD_CREATE, (sysarg_t) uarg,
    124             (sysarg_t) name, (sysarg_t) str_size(name), (sysarg_t) tid);
     112        errno_t rc = (errno_t) __SYSCALL4(SYS_THREAD_CREATE,
     113            (sysarg_t) FADDR(__thread_entry), sp,
     114            (sysarg_t) name, (sysarg_t) str_size(name));
    125115
    126116        if (rc != EOK) {
     
    130120                 */
    131121                as_area_destroy(stack);
    132                 free(uarg);
    133122        }
    134123
     
    148137        while (true)
    149138                ;
    150 }
    151 
    152 /** Detach thread.
    153  *
    154  * Currently not implemented.
    155  *
    156  * @param thread TID.
    157  */
    158 void thread_detach(thread_id_t thread)
    159 {
    160139}
    161140
  • uspace/lib/c/include/align.h

    rbc3d695 r7bf29e5  
    4141 * @param a             Size of alignment, must be power of 2.
    4242 */
    43 #define ALIGN_DOWN(s, a)        ((s) & ~((a) - 1))
     43#define ALIGN_DOWN(s, a)        ((s) & ~((typeof(s))(a) - 1))
    4444
    4545/** Align to the nearest higher address which is a power of two.
     
    4848 * @param a             Size of alignment, must be power of 2.
    4949 */
    50 #define ALIGN_UP(s, a)          ((long)((s) + ((a) - 1)) & ~((long) (a) - 1))
     50#define ALIGN_UP(s, a)          ((((s) + ((a) - 1)) & ~((typeof(s))(a) - 1)))
    5151
    5252/** Round up to the nearest higher boundary.
  • uspace/lib/c/meson.build

    rbc3d695 r7bf29e5  
    5959
    6060src += files(
     61        'common/adt/bitmap.c',
    6162        'common/adt/checksum.c',
    6263        'common/adt/circ_buf.c',
  • uspace/lib/c/test/double_to_str.c

    rbc3d695 r7bf29e5  
    176176        PCUT_ASSERT_INT_EQUALS(-3, dec);
    177177        PCUT_ASSERT_STR_EQUALS("1100", buf);
     178
     179        d = extract_ieee_double(768.0);
     180        ret = double_to_fixed_str(d, -1, 3, buf, size, &dec);
     181        PCUT_ASSERT_INT_EQUALS(4, ret);
     182        PCUT_ASSERT_INT_EQUALS(-3, dec);
     183        PCUT_ASSERT_STR_EQUALS("768", buf);
    178184}
    179185
Note: See TracChangeset for help on using the changeset viewer.