Ignore:
Timestamp:
Jan 4, 2018, 10:05:47 AM (4 years ago)
Author:
alain
Message:

Improve sys_exec.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/kern/process.c

    r415 r416  
    337337    pmgr_t * pmgr = &LOCAL_CLUSTER->pmgr;
    338338
    339     // get the lock protecting the list of local process descriptors
     339    // remove the process descriptor from local_list in cluster manager
    340340    remote_spinlock_lock( XPTR( local_cxy , &pmgr->local_lock ) );
    341 
    342     // remove the process descriptor from local_list in local cluster manager
    343341    xlist_unlink( XPTR( local_cxy , &process->local_list ) );
    344 
    345     // release the lock protecting the list of local process descriptors
    346342    remote_spinlock_unlock( XPTR( local_cxy , &pmgr->local_lock ) );
    347343
     
    356352    remote_spinlock_unlock( copies_lock );
    357353
     354    // release the process PID to cluster manager
     355    cluster_pid_release( process->pid );
     356
    358357        hal_fence();
    359358
     
    370369    vmm_destroy( process );
    371370
    372         process_dmsg("\n[DBG] %s for pid %d / page_faults = %d\n",
    373                  __FUNCTION__ , process->pid, process->vmm.pgfault_nr );
     371    // release memory allocated to process descriptor
     372    process_free( process );
    374373
    375374}  // end process_destroy()
     
    393392    xptr_t             root_xp;           // extended pointer on root of copies
    394393    xptr_t             lock_xp;           // extended pointer on lock protecting copies
    395     xptr_t             client_xp;         // extended pointer on client thread
    396     uint32_t           rsp_count;         // number of expected responses
    397     xptr_t             rsp_xp;            // extended pointer on responses counter
    398394    xptr_t             iter_xp;           // iterator on copies list
    399395    xptr_t             process_xp;        // extended pointer on process copy
    400396    cxy_t              process_cxy;       // process copy cluster identifier
    401397    process_t        * process_ptr;       // local pointer on process copy
    402 
    403 sigaction_dmsg("\n[DBG] %s : enter for signal %s to process %x in cluster %x\n",
    404 __FUNCTION__ , process_action_str( action_type ) , process , local_cxy );
    405 
    406     thread_t         * this = CURRENT_THREAD;
    407 
    408     // get extended pointer on client thread and response counter
    409     client_xp = XPTR( local_cxy , this );
    410     rsp_xp    = XPTR( local_cxy , &rsp_count );
     398    uint32_t           responses;         // number of remote process copies
     399    uint32_t           rsp_count;         // used to assert number of copies
     400
     401    rpc_desc_t         rpc;               // rpc descriptor allocated in stack
     402
     403sigaction_dmsg("\n[DBG] %s : enter to %s process %x in cluster %x\n",
     404__FUNCTION__ , process_action_str( action_type ) , process->pid , local_cxy );
     405
     406    thread_t         * client = CURRENT_THREAD;
     407    xptr_t             client_xp = XPTR( local_cxy , client );
     408
     409    // get local pointer on local cluster manager
     410    cluster = LOCAL_CLUSTER;
    411411
    412412    // get owner cluster identifier and process lpid
     
    414414    lpid      = LPID_FROM_PID( process->pid );
    415415
    416     assert( (owner_cxy == local_cxy) , __FUNCTION__ , "illegal cluster\n" );
     416    // check owner cluster
     417    assert( (owner_cxy == local_cxy) , __FUNCTION__ ,
     418    "must be executed in the owner cluster\n" );
    417419   
    418     // get local pointer on local cluster manager
    419     cluster = LOCAL_CLUSTER;
     420    // get number of remote copies
     421    responses = cluster->pmgr.copies_nr[lpid] - 1;
     422    rsp_count = 0;
     423
     424    // check action type
     425    assert( ((action_type == DELETE_ALL_THREADS ) ||
     426             (action_type == BLOCK_ALL_THREADS )  ||
     427             (action_type == UNBLOCK_ALL_THREADS )),
     428             __FUNCTION__ , "illegal action type" );
     429             
     430    // initialise rpc descriptor
     431    rpc.index    = RPC_PROCESS_SIGACTION;
     432    rpc.response = responses;
     433    rpc.blocking = false;
     434    rpc.thread   = client;
    420435
    421436    // get extended pointers on copies root, copies lock, and number of copies
     
    423438    lock_xp   = XPTR( local_cxy , &cluster->pmgr.copies_lock[lpid] );
    424439
    425     // initialize responses number
    426     rsp_count = cluster->pmgr.copies_nr[lpid];
    427 
    428440    // take the lock protecting the copies
    429441    remote_spinlock_lock( lock_xp );
    430442
    431     // send RPCs to all process copies
     443    // send RPCs to remote clusters
    432444    XLIST_FOREACH( root_xp , iter_xp )
    433445    {
     
    436448        process_ptr = (process_t *)GET_PTR( process_xp );
    437449
    438 sigaction_dmsg("\n[DBG] %s : process = %x / pid = %x / ppid = %x\n",
    439 __FUNCTION__ , process_ptr , process_ptr->pid , process_ptr->ppid );
    440 
    441         rpc_process_sigaction_client( process_cxy,
    442                                       process_ptr,
    443                                       action_type,
    444                                       rsp_xp,
    445                                       client_xp );
     450        // send RPC to remote clusters
     451        if( process_cxy != local_cxy ) 
     452        {
     453
     454sigaction_dmsg("\n[DBG] %s : send RPC to remote cluster %x\n",
     455__FUNCTION__ , process_cxy );
     456
     457            rpc.args[0] = (uint64_t)action_type;
     458            rpc.args[1] = (uint64_t)(intptr_t)process_ptr;
     459            rpc_process_sigaction_client( process_cxy , &rpc );
     460            rsp_count++;
     461        }
    446462    }
    447463   
     
    449465    remote_spinlock_unlock( lock_xp );
    450466
    451     // block and deschedule to wait response
    452     thread_block( CURRENT_THREAD , THREAD_BLOCKED_RPC );
    453     sched_yield("BLOCKED on RPC");
    454 
    455 sigaction_dmsg("\n[DBG] %s : exit for signal %s to process %x in cluster %x\n",
    456 __FUNCTION__ , process_action_str( action_type ) , process , local_cxy );
     467    // check number of copies...
     468    assert( (rsp_count == responses) , __FUNCTION__ ,
     469    "unconsistent number of process copies : rsp_count = %d / responses = %d",
     470    rsp_count , responses );
     471
     472    // block and deschedule to wait RPC responses if required
     473    if( responses )
     474    {   
     475        thread_block( CURRENT_THREAD , THREAD_BLOCKED_RPC );
     476        sched_yield("BLOCKED on RPC_PROCESS_SIGACTION");
     477    }
     478
     479sigaction_dmsg("\n[DBG] %s : make action in owner cluster %x\n",
     480__FUNCTION__ , local_cxy );
     481
     482
     483    // call directly the relevant function in local owner cluster
     484    if      (action_type == DELETE_ALL_THREADS  ) process_delete ( process , client_xp );
     485    else if (action_type == BLOCK_ALL_THREADS   ) process_block  ( process , client_xp );
     486    else if (action_type == UNBLOCK_ALL_THREADS ) process_unblock( process             );
     487
     488sigaction_dmsg("\n[DBG] %s : exit after %s process %x in cluster %x\n",
     489__FUNCTION__ , process_action_str( action_type ) , process->pid , local_cxy );
    457490
    458491}  // end process_sigaction()
     
    460493////////////////////////////////////////
    461494void process_block( process_t * process,
    462                     xptr_t      rsp_xp,
    463495                    xptr_t      client_xp )
    464496{
    465497    thread_t          * target;         // pointer on target thread
    466498    uint32_t            ltid;           // index in process th_tbl
    467     thread_t          * killer;         // killer thread pointer
     499    thread_t          * requester;      // requesting thread pointer
    468500    uint32_t            count;          // requests counter
    469     volatile uint32_t   sig_rsp_count;  // responses counter
    470     cxy_t               client_cxy;     // client thread cluster identifier
    471     thread_t          * client_ptr;     // client thread pointer
    472     core_t            * client_core;    // client thread core pointer
    473 
    474     // get local killer thread pointer
    475     killer = CURRENT_THREAD;
     501    volatile uint32_t   rsp_count;      // responses counter
     502
     503    // get calling thread pointer
     504    requester = CURRENT_THREAD;
    476505
    477506sigaction_dmsg("\n[DBG] %s : enter for process %x in cluster %x\n",
     
    482511
    483512    // initialize local responses counter
    484     sig_rsp_count = process->th_nr;
     513    rsp_count = process->th_nr;
    485514
    486515    // loop on process threads to block and deschedule all threads in cluster
     
    494523            count++;
    495524
    496             // set signal in target thread descriptor
    497             thread_set_signal( target , (uint32_t *)sig_rsp_count );
    498 
    499             // set the global blocked bit in target thread descriptor.
    500             thread_block( target , THREAD_BLOCKED_GLOBAL );
    501 
    502             // - if the killer thread and the target thread are not on the same core
    503             //   we want the scheduler of target thread to acknowlege the signal
    504             //   to be sure that the target thread is descheduled
    505             // - if the killer thread and the target thread are on the same core
    506             //   we simply decrement the response counter.
    507             if( killer->core->lid != target->core->lid )
     525            // - if the target thread is the client thread, we do nothing,
     526            //   and simply decrement the responses counter.
     527            // - if the calling thread and the target thread are on the same core,
     528            //   we block the target thread, we don't ask ask anything to the scheduler,
     529            //   and simply decrement the responses counter.
     530            // - if the calling thread and the target thread are not running on the same
     531            //   core, we ask the target scheduler to acknowlege the blocking
     532            //   to be sure that the target thread is not running.
     533           
     534            if( XPTR( local_cxy , target ) == client_xp )
    508535            {
     536                // decrement responses counter
     537                hal_atomic_add( (void *)&rsp_count , -1 );
     538            }
     539            else if( requester->core->lid == target->core->lid )
     540            {
     541                // set the global blocked bit in target thread descriptor.
     542                thread_block( target , THREAD_BLOCKED_GLOBAL );
     543
     544                // decrement responses counter
     545                hal_atomic_add( (void *)&rsp_count , -1 );
     546            }
     547            else
     548            {
     549                // set the global blocked bit in target thread descriptor.
     550                thread_block( target , THREAD_BLOCKED_GLOBAL );
     551
     552                // set FLAG_REQ_ACK and &ack_rsp_count in target descriptor
     553                thread_set_req_ack( target , (void *)&rsp_count );
     554
     555                // force scheduling on target thread
    509556                dev_pic_send_ipi( local_cxy , target->core->lid );
    510557            }
    511             else                                                         
    512             {
    513                 hal_atomic_add( (void *)&sig_rsp_count , -1 );
    514             }
    515558        }
    516559    }
    517560
    518     // poll the reponses counter
     561    // get lock protecting process th_tbl[]
     562    spinlock_unlock( &process->th_lock );
     563
     564    // wait all responses from schedulers
    519565    while( 1 )
    520566    {
    521         // exit loop when all responses received
    522         if ( sig_rsp_count == 0 ) break;
     567        // exit loop when all local responses received
     568        if ( rsp_count == 0 ) break;
    523569   
    524570        // wait 1000 cycles before retry
     
    526572    }
    527573
    528     // acknowledge client thread & unblock client thread if last response
    529     client_cxy  = GET_CXY( client_xp );
    530     client_ptr  = (thread_t *)GET_PTR( client_xp );
    531     client_core = (core_t *)hal_remote_lpt( XPTR( client_cxy , &client_ptr->core ) );
    532     if( hal_remote_atomic_add( rsp_xp , -1 ) == 1 )
    533     {
    534         thread_unblock( client_xp , THREAD_BLOCKED_RPC);
    535         dev_pic_send_ipi( client_cxy , client_core->lid );
    536     }
    537 
    538574sigaction_dmsg("\n[DBG] %s : exit for process %x in cluster %x / %d threads blocked\n",
    539575__FUNCTION__ , process->pid , local_cxy , count );
     
    541577}  // end process_block()
    542578
    543 //////////////////////////////////////////
    544 void process_unblock( process_t * process,
    545                       xptr_t      rsp_xp,
    546                       xptr_t      client_xp )
     579///////////////////////////////////////////
     580void process_unblock( process_t * process )
    547581{
    548582    thread_t          * target;        // pointer on target thead
    549583    uint32_t            ltid;          // index in process th_tbl
    550     thread_t          * killer;        // killer thread pointer
    551     uint32_t            req_count;     // requests counter
    552     cxy_t               client_cxy;    // client thread cluster identifier
    553     thread_t          * client_ptr;    // client thread pointer
    554     core_t            * client_core;   // client thread core pointer
    555 
    556     // get local killer thread pointer
    557     killer = CURRENT_THREAD;
     584    uint32_t            count;         // requests counter
    558585
    559586sigaction_dmsg("\n[DBG] %s : enter for process %x in cluster %x\n",
     
    564591
    565592    // loop on process threads to unblock all threads in cluster
    566     // we use both "ltid" and "req_count" because it can exist "holes" in th_tbl
    567     for( ltid = 0 , req_count = 0 ;
    568          req_count < process->th_nr ;
    569          ltid++ )
     593    // we use both "ltid" and "count" because it can exist "holes" in th_tbl
     594    for( ltid = 0 , count = 0 ; count < process->th_nr ; ltid++ )
    570595    {
    571596        target = process->th_tbl[ltid];
     
    573598        if( target != NULL )             // thread found
    574599        {
    575             req_count++;
     600            count++;
    576601
    577602            // reset the global blocked bit in target thread descriptor.
     
    580605    }
    581606
    582     // acknowledge client thread & unblock client thread if last response
    583     client_cxy  = GET_CXY( client_xp );
    584     client_ptr  = (thread_t *)GET_PTR( client_xp );
    585     client_core = (core_t *)hal_remote_lpt( XPTR( client_cxy , &client_ptr->core ) );
    586     if( hal_remote_atomic_add( rsp_xp , -1 ) == 1 )
    587     {
    588         thread_unblock( client_xp , THREAD_BLOCKED_RPC);
    589         dev_pic_send_ipi( client_cxy , client_core->lid );
    590     }
     607    // get lock protecting process th_tbl[]
     608    spinlock_unlock( &process->th_lock );
    591609
    592610sigaction_dmsg("\n[DBG] %s : exit for process %x in cluster %x / %d threads blocked\n",
    593 __FUNCTION__ , process->pid , local_cxy , req_count );
     611__FUNCTION__ , process->pid , local_cxy , count );
    594612
    595613}  // end process_unblock()
     
    597615/////////////////////////////////////////
    598616void process_delete( process_t * process,
    599                      xptr_t      rsp_xp,
    600617                     xptr_t      client_xp )
    601618{
    602     thread_t          * thread;        // pointer on target thread
     619    thread_t          * target;        // pointer on target thread
    603620    uint32_t            ltid;          // index in process th_tbl
    604621    uint32_t            count;         // request counter
    605     pid_t               pid;           // process PID
    606     cxy_t               client_cxy;    // client thread cluster identifier
    607     thread_t          * client_ptr;    // client thread pointer
    608     core_t            * client_core;   // client thread core pointer
    609 
    610     // get process PID
    611     pid = process->pid;
     622    thread_t          * requester;     // pointer on calling thread
    612623
    613624sigaction_dmsg("\n[DBG] %s : enter for process %x in cluster %x at cycle %d\n",
    614 __FUNCTION__ , pid , local_cxy , (uint32_t)hal_get_cycles() );
    615 
    616     // loop on threads to release memory allocated to threads
     625__FUNCTION__ , process->pid , local_cxy , (uint32_t)hal_get_cycles() );
     626
     627    // get calling thread pointer
     628    requester = CURRENT_THREAD;
     629
     630    // get lock protecting process th_tbl[]
     631    spinlock_lock( &process->th_lock );
     632
     633    // loop on threads to set the REQ_DELETE flag
     634    // we use both "ltid" and "count" because it can exist "holes" in th_tbl
    617635    for( ltid = 0 , count = 0  ; count < process->th_nr ; ltid++ )
    618636    {
    619         thread = process->th_tbl[ltid];
    620 
    621         if( thread != NULL )             // thread found
     637        target = process->th_tbl[ltid];
     638
     639        if( target != NULL )             // thread found
    622640        {
    623641            count++;
    624642
    625             // detach thread from parent if attached
    626             if( (thread->flags & THREAD_FLAG_DETACHED) == 0 )
    627             thread_child_parent_unlink( thread->parent , XPTR( local_cxy , thread ) );
    628 
    629             // detach thread from process
    630             process_remove_thread( thread );
    631 
    632             // remove thread from scheduler
    633             sched_remove_thread( thread );
    634 
    635             // release memory allocated to thread
    636             thread_destroy( thread );
     643            // delete only if the target is not the client
     644            if( XPTR( local_cxy , target ) != client_xp )
     645            {
     646                hal_atomic_or( &target->flags , THREAD_FLAG_REQ_DELETE );
     647            }
    637648        }
    638649    }
    639650
    640     // release memory allocated to process descriptors
    641     // for all clusters other than the owner cluster
    642     if( local_cxy != CXY_FROM_PID( process->pid ) ) process_destroy( process );
    643 
    644     // acknowledge client thread & unblock client thread if last response
    645     client_cxy  = GET_CXY( client_xp );
    646     client_ptr  = (thread_t *)GET_PTR( client_xp );
    647     client_core = (core_t *)hal_remote_lpt( XPTR( client_cxy , &client_ptr->core ) );
    648     if( hal_remote_atomic_add( rsp_xp , -1 ) == 1 )
    649     {
    650         thread_unblock( client_xp , THREAD_BLOCKED_RPC);
    651         dev_pic_send_ipi( client_cxy , client_core->lid );
    652     }
     651    // get lock protecting process th_tbl[]
     652    spinlock_unlock( &process->th_lock );
    653653
    654654sigaction_dmsg("\n[DBG] %s : exit for process %x in cluster %x at cycle %d\n",
    655 __FUNCTION__ , pid , local_cxy , (uint32_t)hal_get_cycles() );
     655__FUNCTION__ , process->pid , local_cxy , (uint32_t)hal_get_cycles() );
    656656
    657657}  // end process_delete()
     
    951951
    952952    // allocate a child PID from local cluster
    953     error = cluster_pid_alloc( XPTR( local_cxy , process ) , &new_pid );
     953    error = cluster_pid_alloc( process , &new_pid );
    954954    if( (error != 0) || (new_pid == 0) )
    955955    {
     
    10371037    return 0;
    10381038
    1039 }  // end process_make_fork()
    1040 
    1041 /*  deprecated because we don't wand to destroy the existing process descriptor
     1039}   // end process_make_fork()
     1040
    10421041
    10431042/////////////////////////////////////////////////////
     
    10451044{
    10461045    char           * path;                    // pathname to .elf file
    1047     process_t      * old;                     // local pointer on old process
    1048     process_t      * new;                     // local pointer on new process
    1049     pid_t            pid;                     // old process identifier
    1050     thread_t       * thread;                  // pointer on new thread
     1046    process_t      * old_process;             // local pointer on old process
     1047    process_t      * new_process;             // local pointer on new process
     1048    pid_t            old_pid;                 // old process identifier
     1049    pid_t            new_pid;                 // new (temporary) process identifier
     1050    thread_t       * old_thread;              // pointer on new thread
     1051    thread_t       * new_thread;              // pointer on new thread
    10511052    pthread_attr_t   attr;                    // main thread attributes
    10521053    lid_t            lid;                     // selected core local index
     
    10541055
    10551056        // get .elf pathname and PID from exec_info
    1056         path = exec_info->path;
    1057     pid  = exec_info->pid;
    1058 
    1059     // check local cluster is process owner
    1060     assert( (CXY_FROM_PID( pid ) == local_cxy), __FUNCTION__,
    1061     "local cluster %x is not owner for process %x\n", local_cxy, pid );
     1057        path     = exec_info->path;
     1058    old_pid  = exec_info->pid;
     1059
     1060    // this function must be executed by a thread running in owner cluster
     1061    assert( (CXY_FROM_PID( old_pid ) == local_cxy), __FUNCTION__,
     1062    "local cluster %x is not owner for process %x\n", local_cxy, old_pid );
    10621063
    10631064exec_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / path = %s\n",
    1064 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid , path );
    1065 
    1066     // get old process local pointer
    1067     old = (process_t *)cluster_get_local_process_from_pid( pid );
     1065__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, old_pid , path );
     1066
     1067    // get old process and thread local pointers
     1068    old_process = (process_t *)cluster_get_local_process_from_pid( old_pid );
     1069    old_thread  = CURRENT_THREAD;
    10681070   
    1069     assert( (old != NULL ) , __FUNCTION__ ,
    1070     "process %x not found in cluster %x\n", pid , local_cxy );
     1071    if( old_process == NULL )
     1072    {
     1073        printk("\n[ERROR] in %s : cannot get old process descriptor\n", __FUNCTION__ );
     1074        return -1;
     1075    }
    10711076
    10721077    // allocate memory for new process descriptor
    1073     new = process_alloc();
     1078    new_process = process_alloc();
     1079
     1080    if( new_process == NULL )
     1081    {
     1082        printk("\n[ERROR] in %s : cannot allocate new process descriptor\n", __FUNCTION__ );
     1083        return -1;
     1084    }
     1085
     1086    // get a (temporary) PID for new process
     1087    error = cluster_pid_alloc( new_process , &new_pid );
     1088
     1089    if( error )
     1090    {
     1091        printk("\n[ERROR] in %s : cannot allocate a temporary PID\n", __FUNCTION__ );
     1092        process_destroy( new_process );
     1093        return -1;
     1094    }
    10741095
    10751096    // initialize new process descriptor
    1076     process_reference_init( new,
    1077                             old->pid,                   // same as old
    1078                             old->ppid,                  // same as old
    1079                             XPTR( local_cxy , old ) );
     1097    process_reference_init( new_process,
     1098                            new_pid,                            // temporary PID
     1099                            old_process->ppid,                  // same parent
     1100                            XPTR( local_cxy , old_process ) );
    10801101
    10811102exec_dmsg("\n[DBG] %s : core[%x,%d] created new process %x / path = %s\n",
    1082 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid, path );
     1103__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, new_pid, path );
    10831104
    10841105    // register "code" and "data" vsegs as well as entry-point
    10851106    // in new process VMM, using information contained in the elf file.
    1086         if( elf_load_process( path , new ) )
     1107        if( elf_load_process( path , new_process ) )
    10871108        {
    10881109                printk("\n[ERROR] in %s : failed to access .elf file for process %x / path = %s\n",
    1089                 __FUNCTION__, pid , path );
    1090         process_destroy( new );
     1110                __FUNCTION__, new_pid , path );
     1111        cluster_pid_release( new_pid );
     1112        process_destroy( new_process );
    10911113        return -1;
    10921114        }
     
    11041126
    11051127    // create and initialize thread descriptor
    1106         error = thread_user_create( pid,
    1107                                 (void *)new->vmm.entry_point,
     1128        error = thread_user_create( new_pid,
     1129                                (void *)new_process->vmm.entry_point,
    11081130                                exec_info->args_pointers,
    11091131                                &attr,
    1110                                 &thread );
     1132                                &new_thread );
    11111133        if( error )
    11121134        {
    11131135                printk("\n[ERROR] in %s : cannot create thread for process %x / path = %s\n",
    1114                        __FUNCTION__, pid , path );
    1115         process_destroy( new );
     1136            __FUNCTION__, new_pid , path );
     1137        cluster_pid_release( new_pid );
     1138        process_destroy( new_process );
    11161139        return -1;
    11171140        }
    11181141
    1119 exec_dmsg("\n[DBG] %s : core[%x,%d] created main thread %x for new process %x\n",
    1120 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, thread->trdid, pid );
    1121 
    1122     // update children list (rooted in parent process)
    1123         xlist_replace( XPTR( local_cxy , &old->brothers_list ) ,
    1124                    XPTR( local_cxy , &new->brothers_list ) );
    1125 
    1126     // request destruction of old process copies and threads in all clusters
    1127     process_sigaction( old , SIGKILL );
    1128 
     1142exec_dmsg("\n[DBG] %s : core[%x,%d] created main thread %x\n",
     1143__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, new_thread->trdid );
     1144
     1145    // update children list rooted in parent process
     1146        xlist_replace( XPTR( local_cxy , &old_process->brothers_list ) ,
     1147                   XPTR( local_cxy , &new_process->brothers_list ) );
     1148
     1149    // request blocking for all threads in old process (but the calling thread)
     1150    process_sigaction( old_process , BLOCK_ALL_THREADS );
     1151
     1152    // request destruction for all threads in old process (but the calling thread)
     1153    process_sigaction( old_process , DELETE_ALL_THREADS );
     1154
     1155    // update PID for both processes
     1156    new_process->pid = old_pid;
     1157    old_process->pid = 0xFFFFFFFF;
     1158
     1159    // release temporary PID
     1160    cluster_pid_release( new_pid );
     1161   
    11291162    // activate new thread
    1130         thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL );
     1163        thread_unblock( XPTR( local_cxy , new_thread ) , THREAD_BLOCKED_GLOBAL );
    11311164
    11321165exec_dmsg("\n[DBG] %s : core[%x,%d] exit for path = %s\n",
    11331166__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path  );
    11341167
     1168    // set BLOCKED_GLOBAL bit
     1169    thread_block( old_thread , THREAD_BLOCKED_GLOBAL );
     1170
     1171    // set REQ_DELETE flag
     1172    hal_atomic_or( &old_thread->flags , THREAD_FLAG_REQ_DELETE );
     1173
     1174    // deschedule
     1175    sched_yield("suicide after exec");
     1176
     1177    // never executed but required by compiler
    11351178        return 0;
    11361179
    11371180}  // end process_make_exec()
    11381181
    1139 */
    1140 
    1141 /////////////////////////////////////////////////////
    1142 error_t process_make_exec( exec_info_t  * exec_info )
    1143 {
    1144     char           * path;                    // pathname to .elf file
    1145     process_t      * process;                 // local pointer on old process
    1146     pid_t            pid;                     // old process identifier
    1147     thread_t       * thread;                  // pointer on new main thread
    1148     pthread_attr_t   attr;                    // main thread attributes
    1149     lid_t            lid;                     // selected core local index
    1150         error_t          error;
    1151 
    1152         // get .elf pathname and PID from exec_info
    1153         path = exec_info->path;
    1154     pid  = exec_info->pid;
    1155 
    1156     // check local cluster is process owner
    1157     assert( (CXY_FROM_PID( pid ) == local_cxy), __FUNCTION__,
    1158     "local cluster %x is not owner for process %x\n", local_cxy, pid );
    1159 
    1160 exec_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / path = %s\n",
    1161 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid , path );
    1162 
    1163     // get process local pointer
    1164     process = (process_t *)cluster_get_local_process_from_pid( pid );
    1165    
    1166     assert( (process != NULL ) , __FUNCTION__ ,
    1167     "process %x not found in cluster %x\n", pid , local_cxy );
    1168 
    1169     // reset the existing vmm
    1170     vmm_destroy( process );
    1171 
    1172 exec_dmsg("\n[DBG] %s : core[%x,%d] VMM cleared\n",
    1173 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid );
    1174 
    1175     // block all existing process threads
    1176     process_sigaction( process , BLOCK_ALL_THREADS );
    1177 
    1178     // kill all existing threads and process descriptors (other than owner)
    1179     process_sigaction( process , DELETE_ALL_THREADS );
    1180 
    1181     // check no threads
    1182     assert( (process->th_nr == 0) , __FUNCTION__ , "no threads at this point" );
    1183 
    1184 exec_dmsg("\n[DBG] %s : core[%x,%d] all threads deleted\n",
    1185 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid );
    1186 
    1187     // initialize VMM
    1188     error = vmm_init( process );
    1189         {
    1190                 printk("\n[ERROR] in %s : cannot initialize VMM for process %x / path = %s\n",
    1191                 __FUNCTION__, pid , path );
    1192         process_destroy( process );
    1193         return -1;
    1194         }
    1195 
    1196     if( error )
    1197 
    1198     // register "code" and "data" vsegs as well as entry-point and vfs_bin_xp
    1199     // in VMM, using information contained in the elf file.
    1200         error = elf_load_process( path , process );
    1201 
    1202     if( error )
    1203         {
    1204                 printk("\n[ERROR] in %s : failed to access .elf file for process %x / path = %s\n",
    1205                 __FUNCTION__, pid , path );
    1206         process_destroy( process );
    1207         return -1;
    1208         }
    1209 
    1210 exec_dmsg("\n[DBG] %s : core[%x,%d] new vsegs registered / path = %s\n",
    1211 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path );
    1212 
    1213 // @@@
    1214 vmm_display( process , true );
    1215 // @@@
    1216 
    1217     // select a core in local cluster to execute the new main thread
    1218     lid  = cluster_select_local_core();
    1219 
    1220     // initialize pthread attributes for new main thread
    1221     attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED | PT_ATTR_CORE_DEFINED;
    1222     attr.cxy        = local_cxy;
    1223     attr.lid        = lid;
    1224 
    1225     // create and initialize thread descriptor
    1226         error = thread_user_create( pid,
    1227                                 (void *)process->vmm.entry_point,
    1228                                 exec_info->args_pointers,
    1229                                 &attr,
    1230                                 &thread );
    1231         if( error )
    1232         {
    1233                 printk("\n[ERROR] in %s : cannot create thread for process %x / path = %s\n",
    1234                        __FUNCTION__, pid , path );
    1235         process_destroy( process );
    1236         return -1;
    1237         }
    1238 
    1239 exec_dmsg("\n[DBG] %s : core[%x,%d] created main thread %x for new process %x\n",
    1240 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, thread->trdid, pid );
    1241 
    1242     // activate new thread
    1243         thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL );
    1244 
    1245 exec_dmsg("\n[DBG] %s : core[%x,%d] exit for path = %s\n",
    1246 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path  );
    1247 
    1248         return 0;
    1249 
    1250 }  // end process_make_exec()
    1251 
    1252 ////////////////////////////////////////////
    1253 void process_make_kill( process_t * process,
    1254                         uint32_t    sig_id )
     1182///////////////////////////////////////
     1183void process_make_kill( pid_t      pid,
     1184                        uint32_t   sig_id )
    12551185{
    12561186    // this function must be executed by a thread running in owner cluster
    1257     assert( (CXY_FROM_PID( process->pid ) == local_cxy) , __FUNCTION__ ,
     1187    assert( (CXY_FROM_PID( pid ) == local_cxy) , __FUNCTION__ ,
    12581188    "must execute in owner cluster" );
     1189
     1190kill_dmsg("\n[DBG] %s : core[%x,%d] enter / process %x / sig %d\n",
     1191__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid , sig_id );
     1192
     1193    // get pointer on local process descriptor
     1194    process_t * process = process_get_local_copy( pid );
     1195
     1196    // does nothing if process does not exist
     1197    if( process == NULL )
     1198    {
     1199        printk("\n[WARNING] %s : process %x does not exist => do nothing\n",
     1200        __FUNCTION__ , pid );
     1201        return;
     1202    }
    12591203
    12601204    // analyse signal type
    12611205    switch( sig_id )
    12621206    {
    1263         case SIGSTOP:     // block all threads
     1207        case SIGSTOP:     // block all threads in all clusters
    12641208        {
    12651209            process_sigaction( process , BLOCK_ALL_THREADS );
    12661210        }
    12671211        break;
    1268         case SIGCONT:     // unblock all threads
     1212        case SIGCONT:     // unblock all threads in all clusters
    12691213        {
    12701214            process_sigaction( process , UNBLOCK_ALL_THREADS );
     
    12731217        case SIGKILL:  // block all threads, then delete all threads
    12741218        {
     1219            // block all threads (but the calling thread)
    12751220            process_sigaction( process , BLOCK_ALL_THREADS );
     1221
     1222            // delete all threads (but the calling thread)
    12761223            process_sigaction( process , DELETE_ALL_THREADS );
    1277             process_destroy( process );
     1224
     1225            // delete the calling thread if required
     1226            thread_t * this = CURRENT_THREAD;
     1227
     1228            if( this->process == process )
     1229            {
     1230                // set REQ_DELETE flag
     1231                hal_atomic_or( &this->flags , THREAD_FLAG_REQ_DELETE );
     1232
     1233                // deschedule
     1234                sched_yield( "suicide after kill" );
     1235            }
    12781236        }
    12791237        break;
    12801238    }
     1239
     1240//@@@
     1241sched_display( 0 );
     1242//@@@
     1243
     1244kill_dmsg("\n[DBG] %s : core[%x,%d] exit / process %x / sig %d \n",
     1245__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid , sig_id );
     1246
    12811247}  // end process_make_kill()
    12821248
    1283 ////////////////////////////////////////////
    1284 void process_make_exit( process_t * process,
     1249/////////////////////////////////////////
     1250void process_make_exit( pid_t       pid,
    12851251                        uint32_t    status )
    12861252{
    12871253    // this function must be executed by a thread running in owner cluster
    1288     assert( (CXY_FROM_PID( process->pid ) == local_cxy) , __FUNCTION__ ,
     1254    assert( (CXY_FROM_PID( pid ) == local_cxy) , __FUNCTION__ ,
    12891255    "must execute in owner cluster" );
    12901256
    1291     // block all threads in all clusters
     1257    // get pointer on local process descriptor
     1258    process_t * process = process_get_local_copy( pid );
     1259
     1260    // does nothing if process does not exist
     1261    if( process == NULL )
     1262    {
     1263        printk("\n[WARNING] %s : process %x does not exist => do nothing\n",
     1264        __FUNCTION__ , pid );
     1265        return;
     1266    }
     1267
     1268    // block all threads in all clusters (but the calling thread)
    12921269    process_sigaction( process , BLOCK_ALL_THREADS );
    12931270
    1294     // delete all threads in all clusters
     1271    // delete all threads in all clusters (but the calling thread)
    12951272    process_sigaction( process , DELETE_ALL_THREADS );
    12961273
    1297     // delete local process descriptor
    1298     process_destroy( process );
     1274    // delete the calling thread
     1275    hal_atomic_or( &CURRENT_THREAD->flags , THREAD_FLAG_REQ_DELETE );
     1276
     1277    // deschedule
     1278    sched_yield( "suicide after exit" );
    12991279
    13001280}  // end process_make_exit()
     
    13221302
    13231303    // get PID from local cluster
    1324     error = cluster_pid_alloc( XPTR( local_cxy , process ) , &pid );
     1304    error = cluster_pid_alloc( process , &pid );
    13251305    if( error )
    13261306    {
Note: See TracChangeset for help on using the changeset viewer.