Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/proc/thread.c

    r3fcea34 rdfa4be62  
    944944
    945945/** Process syscall to create new thread.
    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  */
    952 sys_errno_t sys_thread_create(sysarg_t pc, sysarg_t sp,
    953     uspace_ptr_char uspace_name, size_t name_len)
     946 *
     947 */
     948sys_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)
    954950{
    955951        if (name_len > THREAD_NAME_BUFLEN - 1)
     
    967963         * In case of success, kernel_uarg will be freed in uinit().
    968964         */
    969         uinit_arg_t *kernel_uarg = malloc(sizeof(uinit_arg_t));
     965        uspace_arg_t *kernel_uarg =
     966            (uspace_arg_t *) malloc(sizeof(uspace_arg_t));
    970967        if (!kernel_uarg)
    971968                return (sys_errno_t) ENOMEM;
    972969
    973         kernel_uarg->pc = pc;
    974         kernel_uarg->sp = sp;
    975 
    976         // TODO: fix some unnecessary inconsistencies between architectures
     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        }
    977975
    978976        thread_t *thread = thread_create(uinit, kernel_uarg, TASK,
    979977            THREAD_FLAG_USPACE | THREAD_FLAG_NOATTACH, namebuf);
    980         if (!thread) {
     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                }
     1000
     1001#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);
     1010#else
     1011                thread_attach(thread, TASK);
     1012#endif
     1013                thread_start(thread);
     1014                thread_put(thread);
     1015
     1016                return 0;
     1017        } else
    9811018                free(kernel_uarg);
    982                 return (sys_errno_t) ENOMEM;
    983         }
    984 
    985 #ifdef CONFIG_UDEBUG
    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);
    994 #else
    995         thread_attach(thread, TASK);
    996 #endif
    997         thread_start(thread);
    998         thread_put(thread);
    999 
    1000         return (sys_errno_t) EOK;
     1019
     1020        return (sys_errno_t) ENOMEM;
    10011021}
    10021022
Note: See TracChangeset for help on using the changeset viewer.