Ignore:
Timestamp:
Jan 29, 2018, 6:08:07 PM (4 years ago)
Author:
alain
Message:

blip

File:
1 edited

Legend:

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

    r416 r428  
    3939#include <core.h>
    4040#include <thread.h>
     41#include <chdev.h>
    4142#include <list.h>
    4243#include <string.h>
     
    5657//////////////////////////////////////////////////////////////////////////////////////////
    5758
    58 extern process_t process_zero;
     59extern process_t           process_zero;     // allocated in kernel_init.c
     60extern chdev_directory_t   chdev_dir;        // allocated in kernel_init.c
    5961
    6062//////////////////////////////////////////////////////////////////////////////////////////
     
    8486}
    8587
    86 /////////////////////////////////////////////
    87 void process_zero_init( process_t * process )
    88 {
    89     // initialize PID, PPID anf PREF
    90     process->pid    = 0;
    91     process->ppid   = 0;
    92     process->ref_xp = XPTR( local_cxy , process );
    93 
    94     // reset th_tbl[] array as empty
    95     uint32_t i;
    96     for( i = 0 ; i < CONFIG_THREAD_MAX_PER_CLUSTER ; i++ )
    97         {
    98         process->th_tbl[i] = NULL;
    99     }
    100     process->th_nr  = 0;
    101     spinlock_init( &process->th_lock );
    102 
    103         hal_fence();
    104 
    105 process_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x\n",
    106 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , process->pid );
    107 
    108 }  // end process_zero_init()
    109 
    11088/////////////////////////////////////////////////
    11189void process_reference_init( process_t * process,
    11290                             pid_t       pid,
    113                              pid_t       ppid,
     91                             xptr_t      parent_xp,
    11492                             xptr_t      model_xp )
    11593{
     94    cxy_t       parent_cxy;
     95    process_t * parent_ptr;
    11696    cxy_t       model_cxy;
    11797    process_t * model_ptr;
    118         error_t     error1;
    119         error_t     error2;
    120         error_t     error3;
    12198    xptr_t      stdin_xp;
    12299    xptr_t      stdout_xp;
     
    126103    uint32_t    stderr_id;
    127104    error_t     error;
    128 
    129 process_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / ppid = %x\n",
    130 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid , ppid );
     105    uint32_t    txt_id;
     106    char        rx_path[40];
     107    char        tx_path[40];
     108    xptr_t      chdev_xp;
     109    chdev_t *   chdev_ptr;
     110    cxy_t       chdev_cxy;
     111    pid_t       model_pid;
     112    pid_t       parent_pid;
    131113
    132114    // get model process cluster and local pointer
     
    134116    model_ptr = (process_t *)GET_PTR( model_xp );
    135117
    136     // initialize PID, PPID, and REF
    137         process->pid    = pid;
    138     process->ppid   = ppid;
    139     process->ref_xp = XPTR( local_cxy , process );
     118    // get parent process cluster and local pointer
     119    parent_cxy = GET_CXY( parent_xp );
     120    parent_ptr = (process_t *)GET_PTR( parent_xp );
     121
     122    // get model_pid and parent_pid
     123    parent_pid = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) );
     124    model_pid  = hal_remote_lw( XPTR( model_cxy  , &model_ptr->pid ) );
     125
     126process_dmsg("\n[DBG] %s : core[%x,%d] enters / pid = %x / ppid = %x / model_pid = %x\n",
     127__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid , parent_pid , model_pid );
     128
     129    // initialize PID, REF_XP, PARENT_XP, and STATE
     130        process->pid       = pid;
     131    process->ref_xp    = XPTR( local_cxy , process );
     132    process->parent_xp = parent_xp;
     133    process->state     = PROCESS_STATE_RUNNING;
    140134
    141135    // initialize vmm as empty
     
    143137    assert( (error == 0) , __FUNCTION__ , "cannot initialize VMM\n" );
    144138 
    145 
    146 process_dmsg("\n[DBG] %s : core[%x,%d] / vmm empty for process %x\n",
     139process_dmsg("\n[DBG] %s : core[%x,%d] / vmm inialised as empty for process %x\n",
    147140__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid );
    148141
     
    150143    process_fd_init( process );
    151144
    152     // create stdin / stdout / stderr pseudo-files
    153     if( ppid == 0 )                                       // process_init
    154     {
    155         error1 = vfs_open( process,
    156                            CONFIG_INIT_STDIN,
     145    // define the stdin/stdout/stderr pseudo files <=> select a TXT terminal.
     146    // - if INIT (pid == 1)         => link to kernel TXT[0]
     147    // - if KSH[i] (model_pid == 1) => allocate a free TXT[i]
     148    // - if USER process            => same terminal as model
     149
     150    if( (pid == 1) || (model_pid == 1)) // INIT or KSH process
     151    {
     152        if (pid == 1 )  txt_id = 0;                    // INIT
     153        else            txt_id = process_txt_alloc();  // KSH[i]
     154
     155        // attach process to TXT[txt_id]
     156        process_txt_attach( process , txt_id );
     157
     158        // build path to TXT_RX[i] and TXT_TX[i] chdevs
     159        snprintf( rx_path , 40 , "/dev/external/txt%d_rx", txt_id );
     160        snprintf( tx_path , 40 , "/dev/external/txt%d_tx", txt_id );
     161
     162        // create stdin pseudo file         
     163        error = vfs_open( process,
     164                           rx_path,
    157165                           O_RDONLY,
    158166                           0,                // FIXME chmod
     
    160168                           &stdin_id );
    161169
    162         error2 = vfs_open( process,
    163                            CONFIG_INIT_STDOUT,
     170        assert( (error == 0) , __FUNCTION__ , "cannot open stdin pseudo file" );
     171        assert( (stdin_id == 0) , __FUNCTION__ , "stdin index must be 0" );
     172
     173        // create stdout pseudo file         
     174        error = vfs_open( process,
     175                           tx_path,
    164176                           O_WRONLY,
    165177                           0,                // FIXME chmod
     
    167179                           &stdout_id );
    168180
    169         error3 = vfs_open( process,
    170                            CONFIG_INIT_STDERR,
     181        assert( (error == 0) , __FUNCTION__ , "cannot open stdout pseudo file" );
     182        assert( (stdout_id == 1) , __FUNCTION__ , "stdout index must be 1" );
     183
     184        // create stderr pseudo file         
     185        error = vfs_open( process,
     186                           tx_path,
    171187                           O_WRONLY,
    172188                           0,                // FIXME chmod
    173189                           &stderr_xp,
    174190                           &stderr_id );
    175     }
    176     else                                                  // any other process
    177     {
    178         error1 = vfs_open( process,
    179                            CONFIG_USER_STDIN,
    180                            O_RDONLY,
    181                            0,                // FIXME chmod
    182                            &stdin_xp,
    183                            &stdin_id );
    184 
    185         error2 = vfs_open( process,
    186                            CONFIG_USER_STDOUT,
    187                            O_WRONLY,
    188                            0,                // FIXME chmod
    189                            &stdout_xp,
    190                            &stdout_id );
    191 
    192         error3 = vfs_open( process,
    193                            CONFIG_USER_STDERR,
    194                            O_WRONLY,
    195                            0,                // FIXME chmod
    196                            &stderr_xp,
    197                            &stderr_id );
    198     }
    199 
    200     assert( ((error1 == 0) && (error2 == 0) && (error3 == 0)) , __FUNCTION__ ,
    201     "cannot open stdin/stdout/stderr pseudo files\n");
    202 
    203     assert( ((stdin_id == 0) && (stdout_id == 1) && (stderr_id == 2)) , __FUNCTION__ ,
    204     "bad indexes : stdin %d / stdout %d / stderr %d \n", stdin_id , stdout_id , stderr_id );
     191
     192        assert( (error == 0) , __FUNCTION__ , "cannot open stderr pseudo file" );
     193        assert( (stderr_id == 2) , __FUNCTION__ , "stderr index must be 2" );
     194
     195    }
     196    else                                            // normal user process
     197    {
     198        // get extended pointer on model process TXT chdev
     199        chdev_xp = chdev_from_file( model_ptr->fd_array.array[0] );
     200 
     201        // get cluster and local pointer on chdev
     202        chdev_cxy = GET_CXY( chdev_xp );
     203        chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );
     204 
     205        // get TXT terminal index
     206        txt_id = hal_remote_lw( XPTR( chdev_cxy , &chdev_ptr->channel ) );
     207
     208        // attach process to TXT[txt_id]
     209        process_txt_attach( process , txt_id );
     210
     211        // copy all open files from model process fd_array to this process
     212        process_fd_remote_copy( XPTR( local_cxy , &process->fd_array ),
     213                                XPTR( model_cxy , &model_ptr->fd_array ) );
     214    }
    205215
    206216    // initialize specific inodes root and cwd
     
    214224    remote_rwlock_init( XPTR( local_cxy , &process->cwd_lock ) );
    215225
    216     // copy all open file descriptors (other than stdin / stdout / stderr)
    217     process_fd_remote_copy( XPTR( local_cxy , &process->fd_array ),
    218                             XPTR( model_cxy , &model_ptr->fd_array ) );
    219 
    220 process_dmsg("\n[DBG] %s : core[%x,%d] / fd array for process %x\n",
     226process_dmsg("\n[DBG] %s : core[%x,%d] / fd array initialised for process %x\n",
    221227__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid );
    222228
     
    224230    xlist_root_init( XPTR( local_cxy , &process->children_root ) );
    225231    process->children_nr     = 0;
     232    remote_spinlock_init( XPTR( local_cxy , &process->children_lock ) );
    226233
    227234    // reset semaphore / mutex / barrier / condvar list roots
     
    256263__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid );
    257264
    258 }  // process_reference init()
     265}  // process_reference_init()
    259266
    260267/////////////////////////////////////////////////////
     
    268275    process_t * ref_ptr = (process_t *)GET_PTR( reference_process_xp );
    269276
    270     // set the pid, ppid, ref_xp fields in local process
    271     local_process->pid    = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->pid ) );
    272     local_process->ppid   = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->ppid ) );
    273     local_process->ref_xp = reference_process_xp;
    274 
    275 process_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x in cluster %x\n",
     277    // initialize PID, REF_XP, PARENT_XP, and STATE
     278    local_process->pid       = hal_remote_lw(  XPTR( ref_cxy , &ref_ptr->pid ) );
     279    local_process->parent_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->parent_xp ) );
     280    local_process->ref_xp    = reference_process_xp;
     281    local_process->state     = PROCESS_STATE_RUNNING;
     282
     283process_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x\n",
    276284__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , local_process->pid );
    277285
     
    291299    xlist_root_init( XPTR( local_cxy , &local_process->children_root ) );
    292300    local_process->children_nr   = 0;
    293 
    294     // reset brothers list (not used in a process descriptor copy)
    295     xlist_entry_init( XPTR( local_cxy , &local_process->brothers_list ) );
     301    remote_spinlock_init( XPTR( local_cxy , &local_process->children_lock ) );
     302
     303    // reset children_list (not used in a process descriptor copy)
     304    xlist_entry_init( XPTR( local_cxy , &local_process->children_list ) );
    296305
    297306    // reset semaphores list root (not used in a process descriptor copy)
     
    318327        hal_fence();
    319328
    320 process_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x in cluster %x\n",
     329process_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x\n",
    321330__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , local_process->pid );
    322331
     
    328337void process_destroy( process_t * process )
    329338{
    330         if( process->th_nr != 0 )
    331     {
    332         panic("process %x in cluster %x has still active threads",
    333               process->pid , local_cxy );
    334     }
     339    xptr_t      parent_xp;
     340    process_t * parent_ptr;
     341    cxy_t       parent_cxy;
     342    xptr_t      parent_thread_xp;
     343    xptr_t      children_lock_xp;
     344    xptr_t      copies_lock_xp;
     345
     346        assert( (process->th_nr == 0) , __FUNCTION__ ,
     347    "process %x in cluster %x has still active threads", process->pid , local_cxy );
     348
     349process_dmsg("\n[DBG] %s : core[%x,%d] enter for process %x\n",
     350__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , process->pid );
    335351
    336352    // get local process manager pointer
    337353    pmgr_t * pmgr = &LOCAL_CLUSTER->pmgr;
    338354
    339     // remove the process descriptor from local_list in cluster manager
     355    // remove process from local_list in cluster manager
    340356    remote_spinlock_lock( XPTR( local_cxy , &pmgr->local_lock ) );
    341357    xlist_unlink( XPTR( local_cxy , &process->local_list ) );
     
    343359
    344360    // get extended pointer on copies_lock in owner cluster manager
    345     cxy_t  owner_cxy    = CXY_FROM_PID( process->pid );
    346         lpid_t lpid         = LPID_FROM_PID( process->pid );
    347     xptr_t copies_lock  = XPTR( owner_cxy , &pmgr->copies_lock[lpid] );
    348 
    349     // remove the local process descriptor from copies_list
    350     remote_spinlock_lock( copies_lock );
     361    cxy_t  owner_cxy = CXY_FROM_PID( process->pid );
     362        lpid_t lpid      = LPID_FROM_PID( process->pid );
     363    copies_lock_xp   = XPTR( owner_cxy , &pmgr->copies_lock[lpid] );
     364
     365    // remove local process from copies_list
     366    remote_spinlock_lock( copies_lock_xp );
    351367    xlist_unlink( XPTR( local_cxy , &process->copies_list ) );
    352     remote_spinlock_unlock( copies_lock );
     368    remote_spinlock_unlock( copies_lock_xp );
     369
     370    // for reference process only
     371    if( XPTR( local_cxy , process ) == process->ref_xp )
     372    {
     373        // remove reference process from txt_list
     374        process_txt_detach( process );
     375
     376        // get pointers on parent process
     377        parent_xp  = process->parent_xp;
     378        parent_cxy = GET_CXY( parent_xp );
     379        parent_ptr = GET_PTR( parent_xp );
     380
     381        // get extended pointer on children_lock in parent process
     382        children_lock_xp = XPTR( parent_cxy , &parent_ptr->children_lock );
     383
     384        // remove process from children_list
     385        remote_spinlock_lock( children_lock_xp );
     386        xlist_unlink( XPTR( local_cxy , &process->children_list ) );
     387        remote_spinlock_unlock( children_lock_xp );
     388
     389        // get extende pointer on parent main thread
     390        parent_thread_xp = XPTR( parent_cxy ,
     391                           hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->th_tbl[1] )));
     392       
     393        // unblock parent process main thread
     394        thread_unblock( parent_thread_xp , THREAD_BLOCKED_WAIT );
     395    }
    353396
    354397    // release the process PID to cluster manager
    355398    cluster_pid_release( process->pid );
    356399
    357         hal_fence();
    358 
    359     // From this point, the process descriptor is unreachable
    360 
    361400    // FIXME close all open files and update dirty [AG]
    362401
    363     // Decrease refcount for bin file, root file and cwd file
     402    // decrease refcount for bin file, root file and cwd file
    364403        if( process->vfs_bin_xp  != XPTR_NULL ) vfs_file_count_down( process->vfs_bin_xp );
    365404        if( process->vfs_root_xp != XPTR_NULL ) vfs_file_count_down( process->vfs_root_xp );
     
    371410    // release memory allocated to process descriptor
    372411    process_free( process );
     412
     413process_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x\n",
     414__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , process->pid );
    373415
    374416}  // end process_destroy()
     
    401443    rpc_desc_t         rpc;               // rpc descriptor allocated in stack
    402444
    403 sigaction_dmsg("\n[DBG] %s : enter to %s process %x in cluster %x\n",
     445process_dmsg("\n[DBG] %s : enter to %s process %x in cluster %x\n",
    404446__FUNCTION__ , process_action_str( action_type ) , process->pid , local_cxy );
    405447
     
    415457
    416458    // check owner cluster
    417     assert( (owner_cxy == local_cxy) , __FUNCTION__ ,
    418     "must be executed in the owner cluster\n" );
     459    assert( (owner_cxy == local_cxy) , __FUNCTION__ , "must be executed in owner cluster\n" );
    419460   
    420461    // get number of remote copies
     
    425466    assert( ((action_type == DELETE_ALL_THREADS ) ||
    426467             (action_type == BLOCK_ALL_THREADS )  ||
    427              (action_type == UNBLOCK_ALL_THREADS )),
    428              __FUNCTION__ , "illegal action type" );
     468             (action_type == UNBLOCK_ALL_THREADS )), __FUNCTION__ , "illegal action type" );
    429469             
    430470    // initialise rpc descriptor
     
    434474    rpc.thread   = client;
    435475
    436     // get extended pointers on copies root, copies lock, and number of copies
     476    // get extended pointers on copies root and lock
    437477    root_xp   = XPTR( local_cxy , &cluster->pmgr.copies_root[lpid] );
    438478    lock_xp   = XPTR( local_cxy , &cluster->pmgr.copies_lock[lpid] );
     
    452492        {
    453493
    454 sigaction_dmsg("\n[DBG] %s : send RPC to remote cluster %x\n",
     494process_dmsg("\n[DBG] %s : send RPC to remote cluster %x\n",
    455495__FUNCTION__ , process_cxy );
    456496
     
    477517    }
    478518
    479 sigaction_dmsg("\n[DBG] %s : make action in owner cluster %x\n",
     519process_dmsg("\n[DBG] %s : make action in owner cluster %x\n",
    480520__FUNCTION__ , local_cxy );
    481521
    482522
    483523    // 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 
    488 sigaction_dmsg("\n[DBG] %s : exit after %s process %x in cluster %x\n",
     524    if      (action_type == DELETE_ALL_THREADS  ) process_delete_threads ( process , client_xp );
     525    else if (action_type == BLOCK_ALL_THREADS   ) process_block_threads  ( process , client_xp );
     526    else if (action_type == UNBLOCK_ALL_THREADS ) process_unblock_threads( process             );
     527
     528process_dmsg("\n[DBG] %s : exit after %s process %x in cluster %x\n",
    489529__FUNCTION__ , process_action_str( action_type ) , process->pid , local_cxy );
    490530
    491531}  // end process_sigaction()
    492532
    493 ////////////////////////////////////////
    494 void process_block( process_t * process,
    495                     xptr_t      client_xp )
     533////////////////////////////////////////////////
     534void process_block_threads( process_t * process,
     535                            xptr_t      client_xp )
    496536{
    497537    thread_t          * target;         // pointer on target thread
     
    524564
    525565            // - if the target thread is the client thread, we do nothing,
    526             //   and simply decrement the responses counter.
     566            //   and we simply decrement the responses counter.
    527567            // - 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.
     568            //   we block the target thread, we don't need confirmation from scheduler,
     569            //   and we simply decrement the responses counter.
    530570            // - if the calling thread and the target thread are not running on the same
    531571            //   core, we ask the target scheduler to acknowlege the blocking
     
    559599    }
    560600
    561     // get lock protecting process th_tbl[]
     601    // release lock protecting process th_tbl[]
    562602    spinlock_unlock( &process->th_lock );
    563603
     
    575615__FUNCTION__ , process->pid , local_cxy , count );
    576616
    577 }  // end process_block()
    578 
    579 ///////////////////////////////////////////
    580 void process_unblock( process_t * process )
     617}  // end process_block_threads()
     618
     619///////////////////////////////////////////////////
     620void process_unblock_threads( process_t * process )
    581621{
    582622    thread_t          * target;        // pointer on target thead
     
    605645    }
    606646
    607     // get lock protecting process th_tbl[]
     647    // release lock protecting process th_tbl[]
    608648    spinlock_unlock( &process->th_lock );
    609649
     
    611651__FUNCTION__ , process->pid , local_cxy , count );
    612652
    613 }  // end process_unblock()
    614 
    615 /////////////////////////////////////////
    616 void process_delete( process_t * process,
    617                      xptr_t      client_xp )
     653}  // end process_unblock_threads()
     654
     655/////////////////////////////////////////////////
     656void process_delete_threads( process_t * process,
     657                             xptr_t      client_xp )
    618658{
    619659    thread_t          * target;        // pointer on target thread
    620660    uint32_t            ltid;          // index in process th_tbl
    621661    uint32_t            count;         // request counter
    622     thread_t          * requester;     // pointer on calling thread
    623662
    624663sigaction_dmsg("\n[DBG] %s : enter for process %x in cluster %x at cycle %d\n",
    625664__FUNCTION__ , process->pid , local_cxy , (uint32_t)hal_get_cycles() );
    626 
    627     // get calling thread pointer
    628     requester = CURRENT_THREAD;
    629665
    630666    // get lock protecting process th_tbl[]
     
    649685    }
    650686
    651     // get lock protecting process th_tbl[]
     687    // release lock protecting process th_tbl[]
    652688    spinlock_unlock( &process->th_lock );
    653689
     
    655691__FUNCTION__ , process->pid , local_cxy , (uint32_t)hal_get_cycles() );
    656692
    657 }  // end process_delete()
     693}  // end process_delete_threads()
    658694
    659695///////////////////////////////////////////////
     
    779815        remote_spinlock_unlock( XPTR( ref_cxy , &ref_ptr->fd_array.lock ) );
    780816
    781     if ( !found ) return EMFILE;
     817    if ( !found ) return -1;
    782818    else          return 0;
    783819}
     
    831867        remote_spinlock_lock( XPTR( src_cxy , &src_ptr->lock ) );
    832868
    833     // loop on all entries other than
    834     // the three first entries: stdin/stdout/stderr
    835     for( fd = 3 ; fd < CONFIG_PROCESS_FILE_MAX_NR ; fd++ )
     869    // loop on all fd_array entries
     870    for( fd = 0 ; fd < CONFIG_PROCESS_FILE_MAX_NR ; fd++ )
    836871        {
    837872                entry = (xptr_t)hal_remote_lwd( XPTR( src_cxy , &src_ptr->array[fd] ) );
     
    862897{
    863898    ltid_t   ltid;
    864     bool_t   found;
     899    bool_t   found = false;
    865900
    866901    assert( (process != NULL) , __FUNCTION__ , "process argument is NULL" );
     
    868903    assert( (thread != NULL) , __FUNCTION__ , "thread argument is NULL" );
    869904
     905    // take lock protecting th_tbl
     906    spinlock_lock( &process->th_lock );
     907
    870908    // search a free slot in th_tbl[]
    871     // 0 is not a valid ltid value
    872     found = false;
    873     for( ltid = 1 ; ltid < CONFIG_THREAD_MAX_PER_CLUSTER ; ltid++ )
     909    for( ltid = 0 ; ltid < CONFIG_THREAD_MAX_PER_CLUSTER ; ltid++ )
    874910    {
    875911        if( process->th_tbl[ltid] == NULL )
     
    890926    }
    891927
     928
     929    // release lock protecting th_tbl
     930    hal_fence();
     931    spinlock_unlock( &process->th_lock );
     932
    892933    return (found) ? 0 : ENOMEM;
    893934
     
    903944    // get thread local index
    904945    ltid_t  ltid = LTID_FROM_TRDID( thread->trdid );
     946
     947    // take lock protecting th_tbl
     948    spinlock_lock( &process->th_lock );
     949
     950    assert( (process->th_nr) , __FUNCTION__ , "process th_nr cannot be 0\n" );
    905951
    906952    // remove thread from th_tbl[]
    907953    process->th_tbl[ltid] = NULL;
    908954    process->th_nr--;
     955
     956    hal_fence();
     957
     958    // release lock protecting th_tbl
     959    spinlock_unlock( &process->th_lock );
    909960
    910961}  // process_remove_thread()
     
    921972    pid_t       parent_pid;      // process identifier for parent process
    922973    xptr_t      ref_xp;          // extended pointer on reference process
     974    xptr_t      vfs_bin_xp;      // extended pointer on .elf file
    923975    error_t     error;
    924976
     
    927979    process_t * parent_process_ptr = (process_t *)GET_PTR( parent_process_xp );
    928980
    929     // get parent process PID
    930     parent_pid = hal_remote_lw( XPTR( parent_process_cxy , &parent_process_ptr->pid ) );
    931    
     981    // get parent process PID and extended pointer on .elf file
     982    parent_pid = hal_remote_lw (XPTR( parent_process_cxy , &parent_process_ptr->pid));
     983    vfs_bin_xp = hal_remote_lwd(XPTR( parent_process_cxy , &parent_process_ptr->vfs_bin_xp));
     984
    932985    // check parent process is the reference
    933986    ref_xp = hal_remote_lwd( XPTR( parent_process_cxy , &parent_process_ptr->ref_xp ) );
     
    9471000    }
    9481001
    949 fork_dmsg("\n[DBG] %s : core[%x,%d] child process descriptor allocated at cycle %d\n",
    950  __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() );
     1002fork_dmsg("\n[DBG] %s : core[%x,%d] created child process %x at cycle %d\n",
     1003 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, process, (uint32_t)hal_get_cycles() );
    9511004
    9521005    // allocate a child PID from local cluster
    9531006    error = cluster_pid_alloc( process , &new_pid );
    954     if( (error != 0) || (new_pid == 0) )
     1007    if( error )
    9551008    {
    9561009        printk("\n[ERROR] in %s : cannot get PID in cluster %x\n",
     
    9601013    }
    9611014
    962 fork_dmsg("\n[DBG] %s : core[%x, %d] child process PID allocated = %x at cycle %d\n",
     1015fork_dmsg("\n[DBG] %s : core[%x, %d] child process PID = %x at cycle %d\n",
    9631016 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, new_pid , (uint32_t)hal_get_cycles() );
    9641017
     
    9661019    process_reference_init( process,
    9671020                            new_pid,
    968                             parent_pid,
     1021                            parent_process_xp,
    9691022                            parent_process_xp );
    9701023
     
    9871040__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() );
    9881041
     1042    // update extended pointer on .elf file
     1043    process->vfs_bin_xp = vfs_bin_xp;
     1044
    9891045    // create child thread descriptor from parent thread descriptor
    9901046    error = thread_user_fork( parent_thread_xp,
     
    10001056    }
    10011057
     1058    // check main thread index
     1059    assert( (thread->trdid == 0) , __FUNCTION__ , "main thread must have index 0\n" );
     1060
    10021061fork_dmsg("\n[DBG] %s : core[%x,%d] child thread created at cycle %d\n",
    10031062__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() );
     
    10181077__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() );
    10191078
    1020     // update children list in parent process
    1021         xlist_add_last( XPTR( parent_process_cxy , &parent_process_ptr->children_root ),
    1022                     XPTR( local_cxy , &process->brothers_list ) );
    1023         hal_remote_atomic_add( XPTR( parent_process_cxy,
    1024                                  &parent_process_ptr->children_nr), 1 );
    1025 
    1026 // vmm_display( process , true );
    1027 // vmm_display( parent_process_ptr , true );
    1028 // sched_display( 0 );
     1079    // get extended pointers on parent children_root, children_lock and children_nr
     1080    xptr_t children_root_xp = XPTR( parent_process_cxy , &parent_process_ptr->children_root );
     1081    xptr_t children_lock_xp = XPTR( parent_process_cxy , &parent_process_ptr->children_lock );
     1082    xptr_t children_nr_xp   = XPTR( parent_process_cxy , &parent_process_ptr->children_nr   );
     1083
     1084    // register process in parent children list
     1085    remote_spinlock_lock( children_lock_xp );
     1086        xlist_add_last( children_root_xp , XPTR( local_cxy , &process->children_list ) );
     1087        hal_remote_atomic_add( children_nr_xp , 1 );
     1088    remote_spinlock_unlock( children_lock_xp );
    10291089
    10301090    // return success
     
    10321092    *child_pid    = new_pid;
    10331093
     1094
    10341095fork_dmsg("\n[DBG] %s : core[%x,%d] exit at cycle %d\n",
    10351096__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() );
     
    10441105{
    10451106    char           * path;                    // pathname to .elf file
     1107    pid_t            pid;                     // old_process PID given to new_process
     1108    pid_t            temp_pid;                // temporary PID given to old_process
    10461109    process_t      * old_process;             // local pointer on old process
    10471110    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
     1111    thread_t       * new_thread;              // local pointer on main thread
    10521112    pthread_attr_t   attr;                    // main thread attributes
    10531113    lid_t            lid;                     // selected core local index
     
    10561116        // get .elf pathname and PID from exec_info
    10571117        path     = exec_info->path;
    1058     old_pid  = exec_info->pid;
     1118    pid      = exec_info->pid;
    10591119
    10601120    // 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 );
    1063 
    1064 exec_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / path = %s\n",
    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;
     1121    assert( (CXY_FROM_PID( pid ) == local_cxy), __FUNCTION__,
     1122    "local cluster %x is not owner for process %x\n", local_cxy, pid );
     1123
     1124exec_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / %s / cycle %d\n",
     1125__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid, path, (uint32_t)hal_get_cycles() );
     1126
     1127    // get old_process local pointer
     1128    old_process = (process_t *)cluster_get_local_process_from_pid( pid );
    10701129   
    10711130    if( old_process == NULL )
     
    10751134    }
    10761135
    1077     // allocate memory for new process descriptor
     1136     // allocate memory for new_process descriptor
    10781137    new_process = process_alloc();
    10791138
    10801139    if( new_process == NULL )
    10811140    {
    1082         printk("\n[ERROR] in %s : cannot allocate new process descriptor\n", __FUNCTION__ );
     1141        printk("\n[ERROR] in %s : cannot allocate process descriptor in cluster %x\n",
     1142        __FUNCTION__ , local_cxy );
    10831143        return -1;
    10841144    }
    10851145
    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 );
     1146    // get a new PID for old_process
     1147    error = cluster_pid_alloc( old_process , &temp_pid );
     1148    if( error )
     1149    {
     1150        printk("\n[ERROR] in %s : cannot get PID in cluster %x\n",
     1151        __FUNCTION__ , local_cxy );
     1152        process_free( new_process );
    10931153        return -1;
    10941154    }
     1155
     1156    // request blocking for all threads in old_process (but the calling thread)
     1157    process_sigaction( old_process , BLOCK_ALL_THREADS );
     1158
     1159    // request destruction for all threads in old_process (but the calling thread)
     1160    process_sigaction( old_process , DELETE_ALL_THREADS );
     1161
     1162exec_dmsg("\n[DBG] %s : core[%x,%d] marked old threads for destruction / cycle %d\n",
     1163__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid , (uint32_t)hal_get_cycles() );
     1164
     1165    // set new PID to old_process
     1166    old_process->pid = temp_pid;
    10951167
    10961168    // initialize new process descriptor
    10971169    process_reference_init( new_process,
    1098                             new_pid,                            // temporary PID
    1099                             old_process->ppid,                  // same parent
    1100                             XPTR( local_cxy , old_process ) );
    1101 
    1102 exec_dmsg("\n[DBG] %s : core[%x,%d] created new process %x / path = %s\n",
    1103 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, new_pid, path );
    1104 
    1105     // register "code" and "data" vsegs as well as entry-point
    1106     // in new process VMM, using information contained in the elf file.
     1170                            pid,
     1171                            old_process->parent_xp,             // parent_process_xp
     1172                            XPTR(local_cxy , old_process) );    // model_process_xp
     1173
     1174    // give TXT ownership to new_process
     1175    process_txt_set_ownership( XPTR( local_cxy , new_process ) );
     1176
     1177exec_dmsg("\n[DBG] %s : core[%x,%d] initialised new process %x / cycle %d \n",
     1178__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, new_process, (uint32_t)hal_get_cycles() );
     1179
     1180    // register code & data vsegs as well as entry-point in new process VMM,
     1181    // and register extended pointer on .elf file in process descriptor
    11071182        if( elf_load_process( path , new_process ) )
    11081183        {
    1109                 printk("\n[ERROR] in %s : failed to access .elf file for process %x / path = %s\n",
    1110                 __FUNCTION__, new_pid , path );
    1111         cluster_pid_release( new_pid );
     1184                printk("\n[ERROR] in %s : failed to access .elf file for path %s\n",
     1185                __FUNCTION__ , path );
    11121186        process_destroy( new_process );
    11131187        return -1;
    11141188        }
    11151189
    1116 exec_dmsg("\n[DBG] %s : core[%x,%d] vsegs registered / path = %s\n",
    1117 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path );
     1190exec_dmsg("\n[DBG] %s : core[%x,%d] vsegs registered in new process %x / cycle %d\n",
     1191__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, new_process, (uint32_t)hal_get_cycles() );
    11181192
    11191193    // select a core in local cluster to execute the main thread
     
    11251199    attr.lid        = lid;
    11261200
    1127     // create and initialize thread descriptor
    1128         error = thread_user_create( new_pid,
     1201    // create and initialize main thread in local cluster
     1202        error = thread_user_create( pid,
    11291203                                (void *)new_process->vmm.entry_point,
    11301204                                exec_info->args_pointers,
     
    11331207        if( error )
    11341208        {
    1135                 printk("\n[ERROR] in %s : cannot create thread for process %x / path = %s\n",
    1136             __FUNCTION__, new_pid , path );
    1137         cluster_pid_release( new_pid );
     1209                printk("\n[ERROR] in %s : cannot create thread for process %x\n",
     1210            __FUNCTION__ , new_process );
    11381211        process_destroy( new_process );
    11391212        return -1;
    11401213        }
    11411214
    1142 exec_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    
     1215    // check main thread index
     1216    assert( (new_thread->trdid == 0) , __FUNCTION__ , "main thread must have index 0\n" );
     1217
     1218exec_dmsg("\n[DBG] %s : core[%x,%d] created new_process main thread / cycle %d\n",
     1219__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() );
     1220
     1221    // get pointers on parent process
     1222    xptr_t      parent_xp  = new_process->parent_xp;
     1223    process_t * parent_ptr = GET_PTR( parent_xp );
     1224    cxy_t       parent_cxy = GET_CXY( parent_xp );
     1225
     1226    // get extended pointers on parent children_root, children_lock and children_nr
     1227    xptr_t root_xp = XPTR( parent_cxy , &parent_ptr->children_root );
     1228    xptr_t lock_xp = XPTR( parent_cxy , &parent_ptr->children_lock );
     1229    xptr_t nr_xp   = XPTR( parent_cxy , &parent_ptr->children_nr   );
     1230
     1231    // register new_process in parent children list
     1232    remote_spinlock_lock( lock_xp );
     1233        xlist_add_last( root_xp , XPTR( local_cxy , &new_process->children_list ) );
     1234        hal_remote_atomic_add( nr_xp , 1 );
     1235    remote_spinlock_unlock( lock_xp );
     1236
     1237exec_dmsg("\n[DBG] %s : core[%x,%d] updated parent process children list / cycle %d\n",
     1238__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() );
     1239   
     1240    // block and mark calling thread for deletion
     1241    // only when it is an user thread
     1242    thread_t * this = CURRENT_THREAD;
     1243    if( this->type == THREAD_USER )
     1244    {
     1245        thread_block( this , THREAD_BLOCKED_GLOBAL );
     1246        hal_atomic_or( &this->flags , THREAD_FLAG_REQ_DELETE );
     1247    }
     1248
    11621249    // activate new thread
    11631250        thread_unblock( XPTR( local_cxy , new_thread ) , THREAD_BLOCKED_GLOBAL );
    11641251
    1165 exec_dmsg("\n[DBG] %s : core[%x,%d] exit for path = %s\n",
    1166 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path  );
    1167 
    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
     1252    hal_fence();
     1253
     1254exec_dmsg("\n[DBG] %s : core[%x,%d] exit for path = %s / cycle %d\n",
     1255__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path , (uint32_t)hal_get_cycles() );
     1256
    11781257        return 0;
    11791258
     
    11881267    "must execute in owner cluster" );
    11891268
     1269    thread_t * this = CURRENT_THREAD;
     1270
    11901271kill_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
     1272__FUNCTION__, local_cxy, this->core->lid, pid , sig_id );
     1273
     1274    // get pointer on local target process descriptor
    11941275    process_t * process = process_get_local_copy( pid );
    11951276
     
    12051286    switch( sig_id )
    12061287    {
    1207         case SIGSTOP:     // block all threads in all clusters
     1288        case SIGSTOP:     
    12081289        {
     1290            // block all threads in all clusters
    12091291            process_sigaction( process , BLOCK_ALL_THREADS );
     1292
     1293            // remove TXT ownership to target process
     1294            process_txt_reset_ownership( XPTR( local_cxy , process ) );
    12101295        }
    12111296        break;
     
    12171302        case SIGKILL:  // block all threads, then delete all threads
    12181303        {
    1219             // block all threads (but the calling thread)
     1304            // block all threads in all clusters
    12201305            process_sigaction( process , BLOCK_ALL_THREADS );
     1306
     1307            // remove TXT ownership to target process
     1308            process_txt_reset_ownership( XPTR( local_cxy , process ) );
    12211309
    12221310            // delete all threads (but the calling thread)
     
    12241312
    12251313            // delete the calling thread if required
    1226             thread_t * this = CURRENT_THREAD;
    1227 
    1228             if( this->process == process )
     1314            if( CURRENT_THREAD->process == process )
    12291315            {
    12301316                // set REQ_DELETE flag
     
    12381324    }
    12391325
    1240 //@@@
    1241 sched_display( 0 );
    1242 //@@@
    1243 
    12441326kill_dmsg("\n[DBG] %s : core[%x,%d] exit / process %x / sig %d \n",
    12451327__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid , sig_id );
     
    12801362}  // end process_make_exit()
    12811363
     1364///////////////////////////////////////////////
     1365void process_zero_create( process_t * process )
     1366{
     1367
     1368process_dmsg("\n[DBG] %s : core[%x,%d] enter at cycle %d\n",
     1369__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() );
     1370
     1371    // initialize PID, REF_XP, PARENT_XP, and STATE
     1372    process->pid       = 0;
     1373    process->ref_xp    = XPTR( local_cxy , process );
     1374    process->parent_xp = XPTR_NULL;
     1375    process->state     = PROCESS_STATE_RUNNING;
     1376
     1377    // reset th_tbl[] array as empty
     1378    uint32_t i;
     1379    for( i = 0 ; i < CONFIG_THREAD_MAX_PER_CLUSTER ; i++ )
     1380        {
     1381        process->th_tbl[i] = NULL;
     1382    }
     1383    process->th_nr  = 0;
     1384    spinlock_init( &process->th_lock );
     1385
     1386    // reset children list as empty
     1387    xlist_root_init( XPTR( local_cxy , &process->children_root ) );
     1388    remote_spinlock_init( XPTR( local_cxy , &process->children_lock ) );
     1389    process->children_nr = 0;
     1390
     1391        hal_fence();
     1392
     1393process_dmsg("\n[DBG] %s : core[%x,%d] exit at cycle %d\n",
     1394__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , (uint32_t)hal_get_cycles() );
     1395
     1396}  // end process_zero_init()
     1397
    12821398//////////////////////////
    12831399void process_init_create()
    12841400{
    1285     process_t      * process;       // local pointer on process_init descriptor
     1401    process_t      * process;       // local pointer on process descriptor
    12861402    pid_t            pid;           // process_init identifier
    12871403    thread_t       * thread;        // local pointer on main thread
     
    12901406    error_t          error;
    12911407
    1292 kinit_dmsg("\n[DBG] %s :  core[%x,%d] enters\n",
     1408process_dmsg("\n[DBG] %s :  core[%x,%d] enters at cycle %d\n",
    12931409__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid );
    12941410
     
    13071423                printk("\n[PANIC] in %s : cannot allocate PID in cluster %x\n",
    13081424                __FUNCTION__, local_cxy );
    1309         process_destroy( process );
    1310     }
    1311 
    1312     assert( (LPID_FROM_PID(pid) == 1) , __FUNCTION__ , "LPID must be 1 for process_init" );
     1425        process_free( process );
     1426    }
     1427
     1428    // check allocated PID
     1429    assert( (pid == 1) , __FUNCTION__ , "process INIT must be first process in cluster 0\n" );
    13131430
    13141431    // initialize process descriptor / parent is local process_zero
    13151432    process_reference_init( process,
    13161433                            pid,
    1317                             0,
    1318                             XPTR( local_cxy , &process_zero ) );
    1319 
    1320 kinit_dmsg("\n[DBG] %s : core[%x,%d] / process initialised\n",
     1434                            XPTR( local_cxy , &process_zero ),     // parent
     1435                            XPTR( local_cxy , &process_zero ) );   // model
     1436
     1437process_dmsg("\n[DBG] %s : core[%x,%d] / initialisation done\n",
    13211438__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid );
    13221439
     
    13301447        }
    13311448
    1332 kinit_dmsg("\n[DBG] %s : core[%x,%d] vsegs registered / path = %s\n",
     1449process_dmsg("\n[DBG] %s : core[%x,%d] vsegs registered / path = %s\n",
    13331450__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, CONFIG_PROCESS_INIT_PATH );
     1451
     1452    // get extended pointers on process_zero children_root, children_lock
     1453    xptr_t children_root_xp = XPTR( local_cxy , &process_zero.children_root );
     1454    xptr_t children_lock_xp = XPTR( local_cxy , &process_zero.children_lock );
     1455
     1456    // register process INIT in parent local process_zero
     1457    remote_spinlock_lock( children_lock_xp );
     1458        xlist_add_last( children_root_xp , XPTR( local_cxy , &process->children_list ) );
     1459        hal_atomic_add( &process_zero.children_nr , 1 );
     1460    remote_spinlock_unlock( children_lock_xp );
    13341461
    13351462    // select a core in local cluster to execute the main thread
     
    13541481        }
    13551482
     1483    // check main thread index
     1484    assert( (thread->trdid == 0) , __FUNCTION__ , "main thread must have index 0\n" );
     1485
    13561486    // activate thread
    13571487        thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL );
     
    13591489    hal_fence();
    13601490
    1361 kinit_dmsg("\n[DBG] %s : core[%x,%d] exit / main thread = %x\n",
     1491process_dmsg("\n[DBG] %s : core[%x,%d] exit / main thread = %x\n",
    13621492__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, thread );
    13631493
    13641494}  // end process_init_create()
    13651495
     1496//////////////////////////////////////////
     1497char * process_state_str( uint32_t state )
     1498{
     1499    if     ( state == PROCESS_STATE_RUNNING ) return "RUNNING";
     1500    else if( state == PROCESS_STATE_KILLED  ) return "KILLED";
     1501    else if( state == PROCESS_STATE_EXITED  ) return "EXITED";
     1502    else                                      return "undefined";
     1503}
     1504
     1505/////////////////////////////////////////
     1506void process_display( xptr_t process_xp )
     1507{
     1508    process_t   * process_ptr;
     1509    cxy_t         process_cxy;
     1510    xptr_t        parent_xp;       // extended pointer on parent process
     1511    process_t   * parent_ptr;
     1512    cxy_t         parent_cxy;
     1513
     1514    pid_t         pid;
     1515    pid_t         ppid;
     1516    uint32_t      state;
     1517    xptr_t        ref_xp;
     1518    uint32_t      th_nr;
     1519
     1520    xptr_t        txt_file_xp;     // extended pointer on TXT_RX pseudo file
     1521    xptr_t        chdev_xp;        // extended pointer on TXT_RX chdev
     1522    chdev_t     * chdev_ptr;
     1523    cxy_t         chdev_cxy;
     1524    xptr_t        owner_xp;        // extended pointer on TXT owner process
     1525
     1526    xptr_t        elf_file_xp;     // extended pointer on .elf file
     1527    cxy_t         elf_file_cxy;
     1528    vfs_file_t  * elf_file_ptr;
     1529    vfs_inode_t * elf_inode_ptr;   // local pointer on .elf inode
     1530
     1531    char          txt_name[CONFIG_VFS_MAX_NAME_LENGTH];
     1532    char          elf_name[CONFIG_VFS_MAX_NAME_LENGTH];
     1533
     1534    // get cluster and local pointer on process
     1535    process_ptr = GET_PTR( process_xp );
     1536    process_cxy = GET_CXY( process_xp );
     1537
     1538    // check reference process
     1539    ref_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->ref_xp ) );
     1540    assert( (process_xp == ref_xp) , __FUNCTION__ , "process is not the reference\n");
     1541
     1542    // get PID and state
     1543    pid   = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) );
     1544    state = hal_remote_lw( XPTR( process_cxy , &process_ptr->state ) );
     1545
     1546    // get PPID
     1547    parent_xp  = hal_remote_lwd( XPTR( process_cxy , &process_ptr->parent_xp ) );
     1548    parent_cxy = GET_CXY( parent_xp );
     1549    parent_ptr = GET_PTR( parent_xp );
     1550    ppid       = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) );
     1551
     1552    // get number of threads
     1553    th_nr      = hal_remote_lw( XPTR( process_cxy , &process_ptr->th_nr ) );
     1554
     1555    // get TXT name and process owner
     1556    txt_file_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->fd_array.array[0] ) );
     1557
     1558    assert( (txt_file_xp != XPTR_NULL) , __FUNCTION__ ,
     1559    "process must be attached to one TXT terminal\n" );
     1560
     1561    chdev_xp  = chdev_from_file( txt_file_xp );
     1562    chdev_cxy = GET_CXY( chdev_xp );
     1563    chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );
     1564    hal_remote_strcpy( XPTR( local_cxy , txt_name ) ,
     1565                           XPTR( chdev_cxy , chdev_ptr->name ) );
     1566    owner_xp = (xptr_t)hal_remote_lwd( XPTR( chdev_cxy , &chdev_ptr->ext.txt.owner_xp ) );
     1567   
     1568    // get process .elf name
     1569    elf_file_xp   = hal_remote_lwd( XPTR( process_cxy , &process_ptr->vfs_bin_xp ) );
     1570
     1571    elf_file_cxy  = GET_CXY( elf_file_xp );
     1572    elf_file_ptr  = (vfs_file_t *)GET_PTR( elf_file_xp );
     1573    elf_inode_ptr = (vfs_inode_t *)hal_remote_lpt( XPTR( elf_file_cxy , &elf_file_ptr->inode ) );
     1574    vfs_inode_get_name( XPTR( elf_file_cxy , elf_inode_ptr ) , elf_name );
     1575
     1576    // display process info
     1577    if( owner_xp == process_xp )
     1578    {
     1579        printk("PID %X | PPID %X | %s\t| %s (FG) | %X | %d | %s\n",
     1580        pid, ppid, process_state_str(state), txt_name, process_ptr, th_nr, elf_name );
     1581    }
     1582    else
     1583    {
     1584        printk("PID %X | PPID %X | %s\t| %s (BG) | %X | %d | %s\n",
     1585        pid, ppid, process_state_str(state), txt_name, process_ptr, th_nr, elf_name );
     1586    }
     1587}  // end process_display()
     1588
     1589
     1590////////////////////////////////////////////////////////////////////////////////////////
     1591//     Terminals related functions
     1592////////////////////////////////////////////////////////////////////////////////////////
     1593
     1594////////////////////////////
     1595uint32_t process_txt_alloc()
     1596{
     1597    uint32_t  index;       // TXT terminal index
     1598    xptr_t    chdev_xp;    // extended pointer on TXT_RX chdev
     1599    chdev_t * chdev_ptr;   // local pointer on TXT_RX chdev
     1600    cxy_t     chdev_cxy;   // TXT_RX chdev cluster
     1601    xptr_t    root_xp;     // extended pointer on owner field in chdev
     1602
     1603    // scan the user TXT_RX chdevs (TXT0 is reserved for kernel)
     1604    for( index = 1 ; index < LOCAL_CLUSTER->nb_txt_channels ; index ++ )
     1605    {
     1606        // get pointers on TXT_RX[index]
     1607        chdev_xp  = chdev_dir.txt_rx[index];
     1608        chdev_cxy = GET_CXY( chdev_xp );
     1609        chdev_ptr = GET_PTR( chdev_xp );
     1610
     1611        // get extended pointer on root of attached process
     1612        root_xp = XPTR( chdev_cxy , &chdev_ptr->ext.txt.root );
     1613
     1614        // return free TXT index if found
     1615        if( xlist_is_empty( root_xp ) ) return index; 
     1616    }
     1617
     1618    assert( false , __FUNCTION__ , "no free TXT terminal found" );
     1619
     1620    return -1;
     1621
     1622} // end process_txt_alloc()
     1623
     1624/////////////////////////////////////////////
     1625void process_txt_attach( process_t * process,
     1626                         uint32_t    txt_id )
     1627{
     1628    xptr_t      chdev_xp;     // extended pointer on TXT_RX chdev
     1629    cxy_t       chdev_cxy;    // TXT_RX chdev cluster
     1630    chdev_t *   chdev_ptr;    // local pointer on TXT_RX chdev
     1631    xptr_t      root_xp;      // extended pointer on list root in chdev
     1632    xptr_t      lock_xp;      // extended pointer on list lock in chdev
     1633
     1634process_dmsg("\n[DBG] %s : core[%x,%d] enter for process %x at cycle\n",
     1635__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, process->pid, (uint32_t)hal_get_cycles() );
     1636
     1637    // check process is reference
     1638    assert( (process->ref_xp == XPTR( local_cxy , process )) , __FUNCTION__ ,
     1639    "process is not the reference descriptor" );
     1640
     1641    // check terminal index
     1642    assert( (txt_id < LOCAL_CLUSTER->nb_txt_channels) ,
     1643    __FUNCTION__ , "illegal TXT terminal index" );
     1644
     1645    // get pointers on TXT_RX[txt_id] chdev
     1646    chdev_xp  = chdev_dir.txt_rx[txt_id];
     1647    chdev_cxy = GET_CXY( chdev_xp );
     1648    chdev_ptr = GET_PTR( chdev_xp );
     1649
     1650    // get extended pointer on root & lock of attached process list
     1651    root_xp = XPTR( chdev_cxy , &chdev_ptr->ext.txt.root );
     1652    lock_xp = XPTR( chdev_cxy , &chdev_ptr->ext.txt.lock );
     1653
     1654    // insert process in attached process list
     1655    remote_spinlock_lock( lock_xp );
     1656    xlist_add_last( root_xp , XPTR( local_cxy , &process->txt_list ) );
     1657    remote_spinlock_unlock( lock_xp );
     1658
     1659process_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x at cycle\n",
     1660__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, process->pid, (uint32_t)hal_get_cycles() );
     1661
     1662} // end process_txt_attach()
     1663
     1664//////////////////////////////////////////////
     1665void process_txt_detach( process_t * process )
     1666{
     1667    xptr_t      chdev_xp;     // extended pointer on TXT_RX chdev
     1668    cxy_t       chdev_cxy;    // TXT_RX chdev cluster
     1669    chdev_t *   chdev_ptr;    // local pointer on TXT_RX chdev
     1670    xptr_t      lock_xp;      // extended pointer on list lock in chdev
     1671
     1672process_dmsg("\n[DBG] %s : core[%x,%d] enter for process %x at cycle\n",
     1673__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, process->pid, (uint32_t)hal_get_cycles() );
     1674
     1675    // check process is reference
     1676    assert( (process->ref_xp == XPTR( local_cxy , process )) , __FUNCTION__ ,
     1677    "process is not the reference descriptor" );
     1678
     1679    // get extended pointer on TXT_RX chdev
     1680    chdev_xp  = chdev_from_file( process->fd_array.array[0] );
     1681    chdev_cxy = GET_CXY( chdev_xp );
     1682    chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );
     1683
     1684    // get extended pointer on lock of attached process list
     1685    lock_xp = XPTR( chdev_cxy , &chdev_ptr->ext.txt.lock );
     1686
     1687    // unlink process from attached process list
     1688    remote_spinlock_lock( lock_xp );
     1689    xlist_unlink( XPTR( local_cxy , &process->txt_list ) );
     1690    remote_spinlock_unlock( lock_xp );
     1691   
     1692process_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x at cycle %d\n",
     1693__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, process->pid, (uint32_t)hal_get_cycles() );
     1694
     1695} // end process_txt_detach()
     1696
     1697///////////////////////////////////////////////////
     1698void process_txt_set_ownership( xptr_t process_xp )
     1699{
     1700    process_t * process_ptr;
     1701    cxy_t       process_cxy;
     1702    xptr_t      file_xp;
     1703    xptr_t      txt_xp;     
     1704    chdev_t   * txt_ptr;
     1705    cxy_t       txt_cxy;
     1706
     1707    // get cluster and local pointer on process
     1708    process_cxy = GET_CXY( process_xp );
     1709    process_ptr = (process_t *)GET_PTR( process_xp );
     1710
     1711    // get extended pointer on stdin pseudo file
     1712    file_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->fd_array.array[0] ) );
     1713
     1714    // get pointers on TXT chdev
     1715    txt_xp  = chdev_from_file( file_xp );
     1716    txt_cxy = GET_CXY( txt_xp );
     1717    txt_ptr = (chdev_t *)GET_PTR( txt_xp );
     1718
     1719    // set owner field in TXT chdev
     1720    hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , process_xp );
     1721
     1722}  // end process_txt_set ownership()
     1723
     1724/////////////////////////////////////////////////////
     1725void process_txt_reset_ownership( xptr_t process_xp )
     1726{
     1727    process_t * process_ptr;
     1728    cxy_t       process_cxy;
     1729    xptr_t      parent_xp;       // extended pointer on parent process
     1730    process_t * parent_ptr;
     1731    cxy_t       parent_cxy;
     1732    xptr_t      file_xp;         // extended pointer on TXT_RX pseudo file
     1733    xptr_t      txt_xp;          // extended pointer on TXT_RX chdev
     1734    chdev_t   * txt_ptr;
     1735    cxy_t       txt_cxy;
     1736    xptr_t      owner_xp;        // extended pointer on current TXT_RX owner
     1737    xptr_t      root_xp;         // extended pointer on root of attached process list
     1738    xptr_t      iter_xp;         // iterator for xlist
     1739    xptr_t      current_xp;      // extended pointer on current process
     1740    process_t * current_ptr;
     1741    cxy_t       current_cxy;
     1742    pid_t       ppid;
     1743
     1744    // get cluster and local pointer on process
     1745    process_cxy = GET_CXY( process_xp );
     1746    process_ptr = (process_t *)GET_PTR( process_xp );
     1747
     1748    // get extended pointer on stdin pseudo file
     1749    file_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->fd_array.array[0] ) );
     1750
     1751    // get pointers on TXT chdev
     1752    txt_xp  = chdev_from_file( file_xp );
     1753    txt_cxy = GET_CXY( txt_xp );
     1754    txt_ptr = (chdev_t *)GET_PTR( txt_xp );
     1755
     1756    // get extended pointer on TXT_RX owner
     1757    owner_xp = hal_remote_lwd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) );
     1758
     1759    // transfer ownership to KSH if required
     1760    if( owner_xp == process_xp )   
     1761    {
     1762        // get extended pointer on root of list of attached processes
     1763        root_xp = hal_remote_lwd( XPTR( txt_cxy , &txt_ptr->ext.txt.root ) );
     1764
     1765        // scan attached process list to find KSH process
     1766        XLIST_FOREACH( root_xp , iter_xp )
     1767        {
     1768            current_xp  = XLIST_ELEMENT( iter_xp , process_t , txt_list );
     1769            current_cxy = GET_CXY( current_xp );
     1770            current_ptr = GET_PTR( current_xp );
     1771            parent_xp   = hal_remote_lwd( XPTR( current_cxy , &current_ptr->parent_xp ) );
     1772
     1773            parent_cxy  = GET_CXY( parent_xp );
     1774            parent_ptr  = GET_PTR( parent_xp );
     1775            ppid        = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) );
     1776
     1777            if( ppid == 1 )  // current is KSH
     1778            {
     1779                // set owner field in TXT chdev
     1780                hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , current_xp );
     1781                return;
     1782            }
     1783        }
     1784    }
     1785
     1786    assert( false , __FUNCTION__ , "KSH process not found" );
     1787
     1788}  // end process_txt_reset_ownership()
     1789
     1790
     1791     
Note: See TracChangeset for help on using the changeset viewer.