Changeset 3fcea34 in mainline for uspace/lib/c/generic/thread/thread.c


Ignore:
Timestamp:
2024-09-20T12:16:28Z (5 months ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
master
Children:
d3109ff
Parents:
2cf8f994
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2024-09-20 11:42:13)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2024-09-20 12:16:28)
Message:

Simplify the SYS_THREAD_CREATE syscall interface

Removed the beefy uarg structure. Instead, the syscall gets two
parameters: %pc (program counter) and %sp (stack pointer). It starts
a thread with those values in corresponding registers, with no other
fuss whatsoever.

libc initializes threads by storing any other needed arguments on
the stack and retrieving them in thread_entry. Importantly, this
includes the address of the
thread_main function which is now
called indirectly to fix dynamic linking issues on some archs.

There's a bit of weirdness on SPARC and IA-64, because of their
stacked register handling. The current solution is that we require
some space *above* the stack pointer to be available for those
architectures. I think for SPARC, it can be made more normal.

For the remaining ones, we can (probably) just set the initial
%sp to the top edge of the stack. There's some lingering offsets
on some archs just because I didn't want to accidentally break
anything. The initial thread bringup should be functionally
unchanged from the previous state, and no binaries are currently
multithreaded except thread1 test, so there should be minimal
risk of breakage. Naturally, I tested all available emulator
builds, save for msim.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/thread/thread.c

    r2cf8f994 r3fcea34  
    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
Note: See TracChangeset for help on using the changeset viewer.