Ignore:
Timestamp:
Jun 18, 2017, 10:06:41 PM (5 years ago)
Author:
alain
Message:

Introduce syscalls.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/syscalls/sys_thread_create.c

    r14 r23  
    22 * sys_thread_create.c - creates a new user thread
    33 *
    4  * Author  Ghassan Almaless (2008,2009,2010,2011,2012)
    5  *         Mohamed lamine Karaoui (2015)
    6  *         Alain Greiner (2016)
     4 * Author     Alain Greiner (2016,2017)
    75 *
    86 * Copyright (c) UPMC Sorbonne Universites
     
    2624#include <kernel_config.h>
    2725#include <hal_types.h>
     26#include <hal_uspace.h>
    2827#include <printk.h>
    2928#include <errno.h>
     
    3837#include <spinlock.h>
    3938#include <dqdt.h>
     39#include <rpc.h>
    4040
    4141
     
    4646                        pthread_attr_t * user_attr,     // [in] argument
    4747                        void           * start_func,    // [in] argument
    48                         void           * start_args )   // [in] argument
     48                        void           * start_arg )    // [in] argument
    4949{
    50         pthread_attr_t   attr;             // copy of pthread attributes in kernel space
     50        pthread_attr_t   k_attr;           // copy of pthread attributes in kernel space
    5151        thread_t       * parent;           // pointer on thread executing the pthread_create
    52     xptr_t           xp_parent;        // extended pointer on created thread
    53     thread_t       * child;            // pointer on created child thread
    54     xptr_t           xp_child;         // extended pointer on created thread
     52    xptr_t           parent_xp;        // extended pointer on created thread
     53    thread_t       * child_ptr;        // pointer on created child thread
     54    xptr_t           child_xp;         // extended pointer on created thread
    5555    trdid_t          trdid;            // created thread identifier
    5656    process_t      * process;          // pointer on local process descriptor
     57    paddr_t          paddr;            // unused, required by vmm_v2p_translate()
    5758    error_t          error;
    5859
     
    6465    // get parent thead pointer, extended pointer, and process pointer
    6566        parent     = CURRENT_THREAD;
    66     xp_parent  = XPTR( local_cxy , parent );   
     67    parent_xp  = XPTR( local_cxy , parent );   
    6768        process    = parent->process;
    6869
    69     // check user_attr & start_func arguments
    70         if( user_attr == NULL )
     70    // check user_attr in user space
     71    error = vmm_v2p_translate( false , user_attr , &paddr );
     72
     73        if( error )
    7174        {
    72                 printk("\n[ERROR] in %s : user_attr is NULL\n", __FUNCTION__ );
    73                 return EINVAL;
    74         }
    75         if( start_func== NULL )
    76         {
    77                 printk("\n[ERROR] in %s : start_func is NULL\n", __FUNCTION__ );
    78                 return EINVAL;
     75                printk("\n[ERROR] in %s : user_attr unmapped\n", __FUNCTION__ );
     76                parent->errno = EINVAL;
     77        return -1;
    7978        }
    8079
    81     // copy user_attr structure to kernel space
    82         hal_copy_from_uspace( &attr , user_attr , sizeof(pthread_attr_t) );
     80    // check start_func in user space
     81    error = vmm_v2p_translate( false , start_func , &paddr );
     82
     83        if( error )
     84        {
     85                printk("\n[ERROR] in %s : start_func unmapped\n", __FUNCTION__ );
     86                parent->errno = EINVAL;
     87        return -1;
     88        }
     89
     90    // check start_arg in user space
     91    if( start_arg != NULL ) error = vmm_v2p_translate( false , start_arg , &paddr );
     92
     93        if( error )
     94        {
     95                printk("\n[ERROR] in %s : start_arg unmapped\n", __FUNCTION__ );
     96                parent->errno = EINVAL;
     97        return -1;
     98        }
     99
     100    // copy user_attr structure from user space to kernel space
     101        hal_copy_from_uspace( &k_attr , user_attr , sizeof(pthread_attr_t) );
    83102
    84103    // check/set "cxy" attribute
    85         if( attr.flags & PT_FLAG_CLUSTER_DEFINED )
     104        if( k_attr.attributes & PT_ATTR_CLUSTER_DEFINED )
    86105    {
    87         if( cluster_is_undefined( attr.cxy ) )
     106        if( cluster_is_undefined( k_attr.cxy ) )
    88107        {
    89                     printk("\n[ERROR] in %s : illegal target cluster = %x\n",
    90                    __FUNCTION__ , attr.cxy );
    91                     return = EINVAL;
     108                    printk("\n[ERROR] in %s : illegal target cluster attribute = %x\n",
     109                   __FUNCTION__ , k_attr.cxy );
     110                    parent->errno = EINVAL;
     111            return -1;
    92112        }
    93113    }
    94114    else
    95115    {
    96         attr.cxy = dqdt_get_cluster_for_process();
     116        k_attr.cxy = dqdt_get_cluster_for_process();
    97117    }
    98118
    99     // set "pid", "start_func" & "start_args" attributes
    100     attr.pid        = process->pid;
    101     attr.start_func = start_func;
    102     attr.start_args = start_args;
    103 
    104119    // create the thread, using a RPC if required
    105     // this returns "error", "child", and "xp_child"
    106     if( attr.cxy == local_cxy )                 // target cluster is local
     120    // this returns "error", "child", and "child_xp"
     121 
     122    if( k_attr.cxy == local_cxy )                         // target cluster is local
    107123    {
    108         // allocate a stack from local VMM
    109         vseg_t * vseg = vmm_create_vseg( process,
    110                                          0,
    111                                          0,
    112                                          VSEG_TYPE_STACK,
    113                                          local_cxy );
    114         if( vseg == NULL )
    115         {
    116                     printk("\n[ERROR] in %s for : cannot create stack vseg\n", __FUNCTION__ );
    117                     return = EINVAL;
    118         }
    119124
    120125        // create thread in local cluster
    121         error = thread_user_create( &child,
    122                                     &attr,
    123                                     vseg->min,
    124                                     vseg->max - vseg->min );
     126        error = thread_user_create( process->pid,
     127                                    start_func,
     128                                    start_arg,
     129                                    &k_attr,
     130                                    &child_ptr );
    125131
    126         xp_child = XPTR( local_cxy , thread );
     132        child_xp = XPTR( local_cxy , child_ptr );
    127133    }
    128134    else                                                 // target cluster is remote
    129135    {
    130         rpc_thread_user_create( attr.cxy , &attr , &error , &xp_child );
    131         child = (thread_t *)GET_PTR( xp_child );
     136        rpc_thread_user_create_client( k_attr.cxy,
     137                                       process->pid,
     138                                       start_func,
     139                                       start_arg,
     140                                       &k_attr,
     141                                       &child_xp,
     142                                       &error );
     143
     144        child_ptr = (thread_t *)GET_PTR( child_xp );
    132145    }
    133146
     
    140153
    141154    // returns trdid to user space
    142     trdid = hal_remote_lw( XPTR( attr.cxy , &child->trdid ) );   
     155    trdid = hal_remote_lw( XPTR( k_attr.cxy , &child_ptr->trdid ) );   
    143156        hal_copy_to_uspace( new_thread , &trdid , sizeof(pthread_t) );
    144157   
    145158    // register new-thread in parent-thread children list if required
    146     if( attr.flags & PT_FLAG_DETACH == 0 ) thread_child_parent_link( xp_parent , xp_child );
     159    if( (k_attr.attributes & PT_ATTR_DETACH) == 0 )
     160        thread_child_parent_link( parent_xp , child_xp );
    147161
    148162        tm_end = hal_time_stamp();
     
    150164        thread_dmsg("\n[INFO] %s created thread %x for process %x in cluster %x\n"
    151165                "  start_cycle = %d / end_cycle = %d\n",
    152                    trdid , process->pid , attr.cxy , tm_start , tm_end );
     166                   trdid , process->pid , k_attr.cxy , tm_start , tm_end );
    153167        return 0;
    154168
Note: See TracChangeset for help on using the changeset viewer.