Ignore:
Timestamp:
Nov 7, 2017, 3:08:12 PM (6 years ago)
Author:
alain
Message:

First implementation of fork/exec.

File:
1 edited

Legend:

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

    r406 r407  
    4040
    4141
    42 //////////////////////////////////////////////////////////////////////////////////////////
    43 // This function implements the pthread_create system call
    44 //////////////////////////////////////////////////////////////////////////////////////////
    45 int sys_thread_create ( thread_t       * new_thread,    // [out] argument
    46                         pthread_attr_t * user_attr,     // [in] argument
    47                         void           * start_func,    // [in] argument
    48                         void           * start_arg )    // [in] argument
     42///////////////////////////////////////////////////
     43int sys_thread_create ( pthread_t      * trdid_ptr,
     44                        pthread_attr_t * user_attr,
     45                        void           * start_func,
     46                        void           * start_arg )
    4947{
    50         pthread_attr_t   k_attr;           // copy of pthread attributes in kernel space
     48        pthread_attr_t   kern_attr;        // copy of pthread attributes in kernel space
    5149        thread_t       * parent;           // pointer on thread executing the pthread_create
    5250        xptr_t           parent_xp;        // extended pointer on created thread
     
    5654        process_t      * process;          // pointer on local process descriptor
    5755        paddr_t          paddr;            // unused, required by vmm_v2p_translate()
     56    cxy_t            target_cxy;       // target cluster identifier
    5857        error_t          error;
    5958
     
    6362        tm_start = hal_get_cycles();
    6463
    65         // get parent thead pointer, extended pointer, and process pointer
     64        // get parent thead pointer, extended pointer, and process
    6665        parent     = CURRENT_THREAD;
    6766        parent_xp  = XPTR( local_cxy , parent );
    6867        process    = parent->process;
    6968
    70         // check user_attr in user space
    71         error = vmm_v2p_translate( false , user_attr , &paddr );
     69        // check user_attr in user space & copy to kernel space
     70    if( user_attr != NULL )
     71    {
     72            error = vmm_v2p_translate( false , user_attr , &paddr );
    7273
    73         if( error )
    74         {
    75                 printk("\n[ERROR] in %s : user_attr unmapped\n", __FUNCTION__ );
    76                 parent->errno = EINVAL;
    77                 return -1;
    78         }
     74            if( error )
     75            {
     76                    printk("\n[ERROR] in %s : user_attr unmapped\n", __FUNCTION__ );
     77                    parent->errno = EINVAL;
     78                    return -1;
     79            }
     80       
     81            hal_copy_from_uspace( &kern_attr , user_attr , sizeof(pthread_attr_t) );
     82    }
    7983
    8084        // check start_func in user space
     
    98102        }
    99103
    100         // copy user_attr structure from user space to kernel space
    101         hal_copy_from_uspace( &k_attr , user_attr , sizeof(pthread_attr_t) );
    102 
    103         // check/set "cxy" attribute
    104         if( k_attr.attributes & PT_ATTR_CLUSTER_DEFINED )
     104        // check / define attributes an target_cxy
     105    if( user_attr != NULL )                      // user defined attributes
     106    {
     107            // check / get target_cxy
     108            if( kern_attr.attributes & PT_ATTR_CLUSTER_DEFINED )
     109            {
     110                    if( cluster_is_undefined( kern_attr.cxy ) )
     111                    {
     112                            printk("\n[ERROR] in %s : illegal target cluster = %x\n",
     113                            __FUNCTION__ , kern_attr.cxy );
     114                            parent->errno = EINVAL;
     115                            return -1;
     116            }
     117            target_cxy = kern_attr.cxy;
     118                }
     119        else
     120        {
     121            target_cxy = dqdt_get_cluster_for_process();
     122        }
     123        }
     124        else                                        // set default attributes
    105125        {
    106                 if( cluster_is_undefined( k_attr.cxy ) )
    107                 {
    108                         printk("\n[ERROR] in %s : illegal target cluster attribute = %x\n",
    109                                __FUNCTION__ , k_attr.cxy );
    110                         parent->errno = EINVAL;
    111                         return -1;
    112                 }
    113         }
    114         else
    115         {
    116                 k_attr.cxy = dqdt_get_cluster_for_process();
     126        kern_attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED;
     127        target_cxy           = dqdt_get_cluster_for_process();
    117128        }
    118129
    119130        // create the thread, using a RPC if required
    120         // this returns "error", "child", and "child_xp"
     131        // this returns "error", "child_ptr", and "child_xp"
    121132
    122         if( k_attr.cxy == local_cxy )                         // target cluster is local
     133        if( target_cxy == local_cxy )                         // target cluster is local
    123134        {
    124135                // create thread in local cluster
     
    126137                                            start_func,
    127138                                            start_arg,
    128                                             &k_attr,
     139                                            &kern_attr,
    129140                                            &child_ptr );
    130141
     
    133144        else                                                 // target cluster is remote
    134145        {
    135                 rpc_thread_user_create_client( k_attr.cxy,
     146                rpc_thread_user_create_client( target_cxy,
    136147                                               process->pid,
    137148                                               start_func,
    138149                                               start_arg,
    139                                                &k_attr,
     150                                               &kern_attr,
    140151                                               &child_xp,
    141152                                               &error );
     
    152163
    153164        // returns trdid to user space
    154         trdid = hal_remote_lw( XPTR( k_attr.cxy , &child_ptr->trdid ) );
    155         hal_copy_to_uspace( new_thread , &trdid , sizeof(pthread_t) );
     165        trdid = hal_remote_lw( XPTR( target_cxy , &child_ptr->trdid ) );
     166        hal_copy_to_uspace( trdid_ptr , &trdid , sizeof(pthread_t) );
    156167
    157         // register new-thread in parent-thread children list if required
    158         if( (k_attr.attributes & PT_ATTR_DETACH) == 0 )
    159             thread_child_parent_link( parent_xp , child_xp );
     168    // register child in parent if required
     169    if( user_attr != NULL )
     170    {
     171            if( (kern_attr.attributes & PT_ATTR_DETACH) == 0 )
     172                thread_child_parent_link( parent_xp , child_xp );
     173    }
     174
     175    // activate new thread
     176        thread_unblock( child_xp , THREAD_BLOCKED_GLOBAL );
     177
     178    hal_fence();
    160179
    161180        tm_end = hal_get_cycles();
    162181
    163         thread_dmsg("\n[DMSG] %s created thread %x for process %x in cluster %x\n"
    164                     "  start_cycle = %d / end_cycle = %d\n",
    165                        trdid , process->pid , k_attr.cxy , tm_start , tm_end );
     182syscall_dmsg("\n[DBG] %s : core[%x,%d] created thread %x for process %x / cycle %d\n"
     183"      cluster %x / cost = %d cycles\n",
     184__FUNCTION__ , local_cxy , parent->core->lid , trdid , process->pid , tm_end ,
     185target_cxy , tm_end - tm_start );
     186
    166187        return 0;
    167 }
    168188
     189}  // end sys_thread_create()
     190
Note: See TracChangeset for help on using the changeset viewer.