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/kern/thread.c

    r16 r23  
    33 *
    44 * Author  Ghassan Almaless (2008,2009,2010,2011,2012)
    5  *         Mohamed Lamine Karaoui (2015)
    6  *         Alain Greiner (2016)
     5 *         Alain Greiner (2016,2017)
    76 *
    87 * Copyright (c) UPMC Sorbonne Universites
     
    7473static thread_t * thread_alloc()
    7574{
    76         page_t       * page;       // pointer on page descriptor containing thread descriptor
    77         kmem_req_t     req;        // kmem request
     75        page_t       * page;   // pointer on page descriptor containing thread descriptor
     76        kmem_req_t     req;    // kmem request
    7877
    7978        // allocates memory for thread descriptor + kernel stack
     
    8483
    8584    // return pointer on new thread descriptor
    86         if( page == NULL )
    87     {
    88         printk("\n[ERROR] in %s : no memory for thread descriptor\n", __FUNCTION__ );
    89         return NULL;
    90     }
    91     else
    92     {
    93         return (thread_t *)ppm_page2base( page );
    94     }
    95 }  // end thread_alloc()
     85        if( page == NULL ) return NULL;
     86    else               return (thread_t *)ppm_page2base( page );
     87
     88
     89/////////////////////////////////////////////////////////////////////////////////////
     90// This static function releases the physical memory for a thread descriptor.
     91// It can be called by the three functions:
     92// - thread_user_create()
     93// - thread_user_fork()
     94// - thread_kernel_create()
     95/////////////////////////////////////////////////////////////////////////////////////
     96// @ thread  : pointer on thread descriptor.
     97/////////////////////////////////////////////////////////////////////////////////////
     98static void thread_release( thread_t * thread )
     99{
     100    kmem_req_t   req;
     101
     102    req.type  = KMEM_PAGE;
     103    req.ptr   = ppm_base2page( thread );
     104    kmem_free( &req );
     105}
    96106
    97107/////////////////////////////////////////////////////////////////////////////////////
     
    194204
    195205/////////////////////////////////////////////////////////
    196 error_t thread_user_create( thread_t       ** new_thread,
     206error_t thread_user_create( pid_t             pid,
     207                            void            * start_func,
     208                            void            * start_arg,
    197209                            pthread_attr_t  * attr,
    198                             intptr_t          u_stack_base,
    199                             uint32_t          u_stack_size )
     210                            thread_t       ** new_thread )
    200211{
    201212    error_t        error;
     
    203214    process_t    * process;      // pointer to local process descriptor
    204215    lid_t          core_lid;     // selected core local index
    205         kmem_req_t     req;          // kmem request (for release)
    206 
    207     thread_dmsg("\n[INFO] %s : enters\n", __FUNCTION__ );
    208 
    209         cluster_t    * local_cluster = LOCAL_CLUSTER;
     216    vseg_t       * vseg;         // stack vseg
     217
     218    thread_dmsg("\n[INFO] %s : enters for process %x\n", __FUNCTION__ , pid );
     219
     220    // get process descriptor local copy
     221    process = process_get_local_copy( pid );
     222
     223    if( process == NULL )
     224    {
     225                printk("\n[ERROR] in %s : cannot get process descriptor %x\n",
     226               __FUNCTION__ , pid );
     227        return ENOMEM;
     228    }
    210229
    211230    // select a target core in local cluster
    212     if( attr->flags & PT_FLAG_CORE_DEFINED ) core_lid = attr->lid;
    213     else                                     core_lid = cluster_select_local_core();
     231    if( attr->attributes & PT_ATTR_CORE_DEFINED ) core_lid = attr->lid;
     232    else                                          core_lid = cluster_select_local_core();
    214233
    215234    // check core local index
    216     if( core_lid >= local_cluster->cores_nr ) return EINVAL;
    217 
    218     // get process descriptor local copy
    219     process = process_get_local_copy( attr->pid );
    220     if( process == NULL ) return ENOMEM;
     235    if( core_lid >= LOCAL_CLUSTER->cores_nr )
     236    {
     237            printk("\n[ERROR] in %s : illegal core index attribute = %d\n",
     238               __FUNCTION__ , core_lid );
     239       
     240        return EINVAL;
     241    }
     242
     243    // allocate a stack from local VMM
     244    vseg = vmm_create_vseg( process, 0 , 0 , VSEG_TYPE_STACK );
     245
     246    if( vseg == NULL );
     247    {
     248            printk("\n[ERROR] in %s : cannot create stack vseg\n", __FUNCTION__ );
     249                return ENOMEM;
     250    }
    221251
    222252    // allocates memory tor thread descriptor
    223253    thread = thread_alloc();
    224254
    225     if( thread == NULL ) return ENOMEM;
     255    if( thread == NULL )
     256    {
     257            printk("\n[ERROR] in %s : cannot create new thread\n", __FUNCTION__ );
     258        vmm_remove_vseg( vseg );
     259        return ENOMEM;
     260    }
    226261
    227262    // initializes thread descriptor
     
    229264                         process,
    230265                         THREAD_USER,
    231                          attr->entry_func,
    232                          attr->entry_args,
     266                         start_func,
     267                         start_arg,
    233268                         core_lid,
    234                          u_stack_base,
    235                          u_stack_size );
    236 
    237     if( error )  // release allocated memory for thread descriptor
    238     {
    239             req.type  = KMEM_PAGE;
    240         req.ptr   = ppm_base2page( thread );
    241         kmem_free( &req );
     269                         vseg->min,
     270                         vseg->max - vseg->min );
     271
     272    if( error )
     273    {
     274            printk("\n[ERROR] in %s : cannot initialize new thread\n", __FUNCTION__ );
     275        vmm_remove_vseg( vseg );
     276        thread_release( thread );
    242277        return EINVAL;
    243278    }
     
    247282
    248283    // set DETACHED flag if required
    249     if( attr->flags & PT_FLAG_DETACH ) thread->flags |= THREAD_FLAG_DETACHED;
     284    if( attr->attributes & PT_ATTR_DETACH ) thread->flags |= THREAD_FLAG_DETACHED;
    250285
    251286    // allocate & initialise CPU context
    252287        error = hal_cpu_context_create( thread );
    253     if( error ) return ENOMEM;
     288
     289    if( error )
     290    {
     291            printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ );
     292        vmm_remove_vseg( vseg );
     293        thread_release( thread );
     294        return ENOMEM;
     295    }
    254296
    255297    // allocate & initialise FPU context
    256298    error = hal_fpu_context_create( thread );
    257     if( error ) return ENOMEM;
    258  
     299
     300    if( error )
     301    {
     302            printk("\n[ERROR] in %s : cannot create FPU context\n", __FUNCTION__ );
     303        vmm_remove_vseg( vseg );
     304        thread_release( thread );
     305        return ENOMEM;
     306    }
     307
    259308    thread_dmsg("\n[INFO] %s : exit / trdid = %x / process %x / core = %d\n",
    260309                __FUNCTION__ , thread->trdid , process->pid , core_lid );
     
    266315
    267316
    268 /////////////////////////////////////////////////
    269 error_t thread_user_fork( thread_t ** new_thread,
    270                           process_t * process,
    271                           intptr_t    u_stack_base,
    272                           uint32_t    u_stack_size )
     317//////////////////////////////////////////////
     318error_t thread_user_fork( process_t * process,
     319                          thread_t ** new_thread )
    273320{
    274321    error_t        error;
    275322        thread_t     * thread;       // pointer on new thread descriptor
    276323    lid_t          core_lid;     // selected core local index
    277         kmem_req_t     req;          // kmem request (for release)
     324        vseg_t       * vseg;         // stack vseg
    278325
    279326    thread_dmsg("\n[INFO] %s : enters\n", __FUNCTION__ );
     327
     328    // allocate a stack from local VMM
     329    vseg = vmm_create_vseg( process, 0 , 0 , VSEG_TYPE_STACK );
     330
     331    if( vseg == NULL );
     332    {
     333            printk("\n[ERROR] in %s : cannot create stack vseg\n", __FUNCTION__ );
     334                return ENOMEM;
     335    }
    280336
    281337    // select a target core in local cluster
     
    288344    thread = thread_alloc();
    289345
    290     if( thread == NULL ) return ENOMEM;
     346    if( thread == NULL )
     347    {
     348        printk("\n[ERROR] in %s : cannot allocate new thread\n", __FUNCTION__ );
     349        vmm_remove_vseg( vseg );
     350        return ENOMEM;
     351    }
    291352
    292353    // initializes thread descriptor
     
    297358                         this->entry_args,
    298359                         core_lid,
    299                          u_stack_base,
    300                          u_stack_size );
    301 
    302     if( error ) // release allocated memory for thread descriptor
    303     {
    304             req.type  = KMEM_PAGE;
    305         req.ptr   = ppm_base2page( thread );
    306         kmem_free( &req );
     360                         vseg->min,
     361                         vseg->max - vseg->min );
     362
     363    if( error )
     364    {
     365            printk("\n[ERROR] in %s : cannot initialize new thread\n", __FUNCTION__ );
     366        vmm_remove_vseg( vseg );
     367        thread_release( thread );
    307368        return EINVAL;
    308369    }
     
    313374    // allocate & initialise CPU context from calling thread
    314375        error = hal_cpu_context_copy( thread , this );
    315     if( error ) return ENOMEM;
     376
     377    if( error )
     378    {
     379            printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ );
     380        vmm_remove_vseg( vseg );
     381        thread_release( thread );
     382        return ENOMEM;
     383    }
    316384
    317385    // allocate & initialise FPU context from calling thread
    318386        error = hal_fpu_context_copy( thread , this );
    319     if( error ) return ENOMEM;
    320 
    321     thread_dmsg("INFO : %s thread %x for process %x on core %d in cluster %x\n",
     387
     388    if( error )
     389    {
     390            printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ );
     391        vmm_remove_vseg( vseg );
     392        thread_release( thread );
     393        return ENOMEM;
     394    }
     395
     396    thread_dmsg("\n[INFO] %s : exit / thread %x for process %x on core %d in cluster %x\n",
    322397                 __FUNCTION__, thread->trdid, process->pid, core_lid, local_cxy );
    323398
     
    473548        spinlock_unlock( &process->th_lock );
    474549       
     550    // update local DQDT
     551    dqdt_local_update_threads( -1 );
     552
    475553    // invalidate thread descriptor
    476554        thread->signature = 0;
    477555
    478556    // release memory for thread descriptor
    479         kmem_req_t   req;
    480         req.type     = KMEM_PAGE;
    481         req.ptr      = ppm_base2page( thread );
    482         kmem_free(&req);
     557    thread_release( thread );
    483558
    484559        tm_end = hal_time_stamp();
     
    706781
    707782////////////////////////////////////////////////
    708 void thread_signals_handler( thread_t * thread )
     783void thread_signals_handle( thread_t * thread )
    709784{
    710785    // TODO
     
    712787}
    713788
    714 
     789/////////////////////////////////////
     790xptr_t thread_get_xptr( pid_t    pid,
     791                        trdid_t  trdid )
     792{
     793    cxy_t         target_cxy;          // target thread cluster identifier
     794    ltid_t        target_thread_ltid;  // target thread local index
     795    thread_t    * target_thread_ptr;   // target thread local pointer           
     796    xptr_t        target_process_xp;   // extended pointer on target process descriptor
     797    process_t   * target_process_ptr;  // local pointer on target process descriptor
     798    pid_t         target_process_pid;  // target process identifier
     799    xlist_entry_t root;                // root of list of process in target cluster
     800    xptr_t        lock_xp;             // extended pointer on lock protecting  this list
     801
     802    // get target cluster identifier and local thread identifier
     803    target_cxy         = CXY_FROM_TRDID( trdid );
     804    target_thread_ltid = LTID_FROM_TRDID( trdid );
     805
     806    // get root of list of process descriptors in target cluster
     807    hal_remote_memcpy( XPTR( local_cxy  , &root ),
     808                       XPTR( target_cxy , &LOCAL_CLUSTER->pmgr.local_root ),
     809                       sizeof(xlist_entry_t) );
     810
     811    // get extended pointer on lock protecting the list of processes
     812    lock_xp = XPTR( target_cxy , &LOCAL_CLUSTER->pmgr.local_lock );
     813
     814    // take the lock protecting the list of processes in target cluster
     815    remote_spinlock_lock( lock_xp );
     816
     817    // loop on list of process in target cluster to find the PID process
     818    xptr_t  iter;
     819    bool_t  found = false;
     820    XLIST_FOREACH( XPTR( target_cxy , &LOCAL_CLUSTER->pmgr.local_root ) , iter )
     821    {
     822        target_process_xp  = XLIST_ELEMENT( iter , process_t , local_list );
     823        target_process_ptr = (process_t *)GET_PTR( target_process_xp );
     824        target_process_pid = hal_remote_lw( XPTR( target_cxy , &target_process_ptr->pid ) );
     825        if( target_process_pid == pid )
     826        {
     827            found = true;
     828            break;
     829        }
     830    }
     831
     832    // release the lock protecting the list of processes in target cluster
     833    remote_spinlock_unlock( lock_xp );
     834
     835    // check target thread found
     836    if( found == false )
     837    {
     838        return XPTR_NULL;
     839    }
     840
     841    // get target thread local pointer
     842    xptr_t xp = XPTR( target_cxy , &target_process_ptr->th_tbl[target_thread_ltid] );
     843    target_thread_ptr = (thread_t *)hal_remote_lpt( xp );   
     844
     845    if( target_thread_ptr == NULL )
     846    {
     847        return XPTR_NULL;
     848    }
     849
     850    return XPTR( target_cxy , target_thread_ptr );
     851
     852}  // end thread_get_xptr()
     853
Note: See TracChangeset for help on using the changeset viewer.