Changeset 3fcea34 in mainline for kernel/generic/src/proc/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
  • kernel/generic/src/proc/thread.c

    r2cf8f994 r3fcea34  
    944944
    945945/** Process syscall to create new thread.
    946  *
    947  */
    948 sys_errno_t sys_thread_create(uspace_ptr_uspace_arg_t uspace_uarg, uspace_ptr_char uspace_name,
    949     size_t name_len, uspace_ptr_thread_id_t uspace_thread_id)
     946 * The started thread will have initial pc and sp set to the exact values passed
     947 * to the syscall. The kernel will not touch any stack data below the stack
     948 * pointer, but some architectures may require some space to be available
     949 * for use above it. See userspace() in kernel, and <libarch/thread.h> in libc.
     950 *
     951 */
     952sys_errno_t sys_thread_create(sysarg_t pc, sysarg_t sp,
     953    uspace_ptr_char uspace_name, size_t name_len)
    950954{
    951955        if (name_len > THREAD_NAME_BUFLEN - 1)
     
    963967         * In case of success, kernel_uarg will be freed in uinit().
    964968         */
    965         uspace_arg_t *kernel_uarg =
    966             (uspace_arg_t *) malloc(sizeof(uspace_arg_t));
     969        uinit_arg_t *kernel_uarg = malloc(sizeof(uinit_arg_t));
    967970        if (!kernel_uarg)
    968971                return (sys_errno_t) ENOMEM;
    969972
    970         rc = copy_from_uspace(kernel_uarg, uspace_uarg, sizeof(uspace_arg_t));
    971         if (rc != EOK) {
    972                 free(kernel_uarg);
    973                 return (sys_errno_t) rc;
    974         }
     973        kernel_uarg->pc = pc;
     974        kernel_uarg->sp = sp;
     975
     976        // TODO: fix some unnecessary inconsistencies between architectures
    975977
    976978        thread_t *thread = thread_create(uinit, kernel_uarg, TASK,
    977979            THREAD_FLAG_USPACE | THREAD_FLAG_NOATTACH, namebuf);
    978         if (thread) {
    979                 if (uspace_thread_id) {
    980                         rc = copy_to_uspace(uspace_thread_id, &thread->tid,
    981                             sizeof(thread->tid));
    982                         if (rc != EOK) {
    983                                 /*
    984                                  * We have encountered a failure, but the thread
    985                                  * has already been created. We need to undo its
    986                                  * creation now.
    987                                  */
    988 
    989                                 /*
    990                                  * The new thread structure is initialized, but
    991                                  * is still not visible to the system.
    992                                  * We can safely deallocate it.
    993                                  */
    994                                 slab_free(thread_cache, thread);
    995                                 free(kernel_uarg);
    996 
    997                                 return (sys_errno_t) rc;
    998                         }
    999                 }
     980        if (!thread) {
     981                free(kernel_uarg);
     982                return (sys_errno_t) ENOMEM;
     983        }
    1000984
    1001985#ifdef CONFIG_UDEBUG
    1002                 /*
    1003                 * Generate udebug THREAD_B event and attach the thread.
    1004                 * This must be done atomically (with the debug locks held),
    1005                 * otherwise we would either miss some thread or receive
    1006                 * THREAD_B events for threads that already existed
    1007                 * and could be detected with THREAD_READ before.
    1008                 */
    1009                 udebug_thread_b_event_attach(thread, TASK);
     986        /*
     987        * Generate udebug THREAD_B event and attach the thread.
     988        * This must be done atomically (with the debug locks held),
     989        * otherwise we would either miss some thread or receive
     990        * THREAD_B events for threads that already existed
     991        * and could be detected with THREAD_READ before.
     992        */
     993        udebug_thread_b_event_attach(thread, TASK);
    1010994#else
    1011                 thread_attach(thread, TASK);
     995        thread_attach(thread, TASK);
    1012996#endif
    1013                 thread_start(thread);
    1014                 thread_put(thread);
    1015 
    1016                 return 0;
    1017         } else
    1018                 free(kernel_uarg);
    1019 
    1020         return (sys_errno_t) ENOMEM;
     997        thread_start(thread);
     998        thread_put(thread);
     999
     1000        return (sys_errno_t) EOK;
    10211001}
    10221002
Note: See TracChangeset for help on using the changeset viewer.