Ignore:
Timestamp:
Aug 2, 2018, 11:47:13 AM (6 years ago)
Author:
alain
Message:

This version modifies the exec syscall and fixes a large number of small bugs.
The version number has been updated (0.1)

File:
1 edited

Legend:

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

    r450 r457  
    2525
    2626#include <kernel_config.h>
    27 #include <hal_types.h>
     27#include <hal_kernel_types.h>
    2828#include <hal_remote.h>
    2929#include <hal_uspace.h>
     
    8989void process_reference_init( process_t * process,
    9090                             pid_t       pid,
    91                              xptr_t      parent_xp,
    92                              xptr_t      model_xp )
     91                             xptr_t      parent_xp )
    9392{
    9493    cxy_t       parent_cxy;
    9594    process_t * parent_ptr;
    96     cxy_t       model_cxy;
    97     process_t * model_ptr;
    9895    xptr_t      stdin_xp;
    9996    xptr_t      stdout_xp;
     
    110107    chdev_t *   chdev_ptr;
    111108    cxy_t       chdev_cxy;
    112     pid_t       model_pid;
    113109    pid_t       parent_pid;
    114 
    115     // get model process cluster and local pointer
    116     model_cxy = GET_CXY( model_xp );
    117     model_ptr = GET_PTR( model_xp );
    118110
    119111    // get parent process cluster and local pointer
     
    121113    parent_ptr = GET_PTR( parent_xp );
    122114
    123     // get model_pid and parent_pid
     115    // get parent_pid
    124116    parent_pid = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) );
    125     model_pid  = hal_remote_lw( XPTR( model_cxy  , &model_ptr->pid ) );
    126117
    127118#if DEBUG_PROCESS_REFERENCE_INIT
    128119uint32_t cycle = (uint32_t)hal_get_cycles();
    129120if( DEBUG_PROCESS_REFERENCE_INIT )
    130 printk("\n[DBG] %s : thread %x enter / pid = %x / ppid = %x / model_pid = %x / cycle %d\n",
    131 __FUNCTION__ , CURRENT_THREAD , pid , parent_pid , model_pid , cycle );
     121printk("\n[DBG] %s : thread %x in process %x enter to initalialize process %x / cycle %d\n",
     122__FUNCTION__, CURRENT_THREAD->trdid, parent_pid , pid , cycle );
    132123#endif
    133124
     
    146137cycle = (uint32_t)hal_get_cycles();
    147138if( DEBUG_PROCESS_REFERENCE_INIT )
    148 printk("\n[DBG] %s : thread %x / vmm empty for process %x / cycle %d\n",
    149 __FUNCTION__ , CURRENT_THREAD , pid , cycle );
     139printk("\n[DBG] %s : thread %x in process %x / vmm empty for process %x / cycle %d\n",
     140__FUNCTION__, CURRENT_THREAD->trdid, parent_pid , cycle );
    150141#endif
    151142
     
    154145
    155146    // define the stdin/stdout/stderr pseudo files <=> select a TXT terminal.
    156     // - if INIT (pid == 1)         => link to kernel TXT[0]
    157     // - if KSH[i] (model_pid == 1) => allocate a free TXT[i]
    158     // - if USER process            => same terminal as model
    159 
    160     if( (pid == 1) || (model_pid == 1)) // INIT or KSH process
    161     {
    162         if (pid == 1 )  txt_id = 0;                    // INIT
    163         else            txt_id = process_txt_alloc();  // KSH[i]
    164 
    165         // attach process to TXT[txt_id]
     147    if( (pid == 1) || (parent_pid == 1)) // INIT or KSH process
     148    {
     149        // allocate a TXT channel
     150        if( pid == 1 )  txt_id = 0;                     // INIT
     151        else            txt_id = process_txt_alloc();   // KSH
     152
     153        // attach process to TXT
    166154        process_txt_attach( process , txt_id );
     155
     156#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
     157cycle = (uint32_t)hal_get_cycles();
     158if( DEBUG_PROCESS_REFERENCE_INIT )
     159printk("\n[DBG] %s : thread %x in process %x / process %x attached to TXT%d / cycle %d\n",
     160__FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid, txt_id, cycle );
     161#endif
     162
     163
    167164
    168165        // build path to TXT_RX[i] and TXT_TX[i] chdevs
     
    184181cycle = (uint32_t)hal_get_cycles();
    185182if( DEBUG_PROCESS_REFERENCE_INIT )
    186 printk("\n[DBG] %s : thread %x / stdin open for process %x / cycle %d\n",
    187 __FUNCTION__ , CURRENT_THREAD , pid , cycle );
     183printk("\n[DBG] %s : thread %x in process %x / stdin open for process %x / cycle %d\n",
     184__FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid, cycle );
    188185#endif
    189186
     
    202199cycle = (uint32_t)hal_get_cycles();
    203200if( DEBUG_PROCESS_REFERENCE_INIT )
    204 printk("\n[DBG] %s : thread %x / stdout open for process %x / cycle %d\n",
    205 __FUNCTION__ , CURRENT_THREAD , pid , cycle );
     201printk("\n[DBG] %s : thread %x in process %x / stdout open for process %x / cycle %d\n",
     202__FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid, cycle );
    206203#endif
    207204
     
    220217cycle = (uint32_t)hal_get_cycles();
    221218if( DEBUG_PROCESS_REFERENCE_INIT )
    222 printk("\n[DBG] %s : thread %x / stderr open for process %x / cycle %d\n",
    223 __FUNCTION__ , CURRENT_THREAD , pid , cycle );
     219printk("\n[DBG] %s : thread %x in process %x / stderr open for process %x / cycle %d\n",
     220__FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid, cycle );
    224221#endif
    225222
     
    227224    else                                            // normal user process
    228225    {
    229         // get extended pointer on stdin pseudo file in model process
    230         file_xp = (xptr_t)hal_remote_lwd( XPTR( model_cxy , &model_ptr->fd_array.array[0] ) );
    231 
    232         // get extended pointer on model process TXT chdev
     226        // get extended pointer on stdin pseudo file in parent process
     227        file_xp = (xptr_t)hal_remote_lwd( XPTR( parent_cxy , &parent_ptr->fd_array.array[0] ) );
     228
     229        // get extended pointer on parent process TXT chdev
    233230        chdev_xp = chdev_from_file( file_xp );
    234231 
     
    243240        process_txt_attach( process , txt_id );
    244241
    245         // copy all open files from model process fd_array to this process
     242        // copy all open files from parent process fd_array to this process
    246243        process_fd_remote_copy( XPTR( local_cxy , &process->fd_array ),
    247                                 XPTR( model_cxy , &model_ptr->fd_array ) );
     244                                XPTR( parent_cxy , &parent_ptr->fd_array ) );
    248245    }
    249246
    250247    // initialize specific inodes root and cwd
    251     process->vfs_root_xp = (xptr_t)hal_remote_lwd( XPTR( model_cxy,
    252                                                          &model_ptr->vfs_root_xp ) );
    253     process->vfs_cwd_xp  = (xptr_t)hal_remote_lwd( XPTR( model_cxy,
    254                                                          &model_ptr->vfs_cwd_xp ) );
     248    process->vfs_root_xp = (xptr_t)hal_remote_lwd( XPTR( parent_cxy,
     249                                                         &parent_ptr->vfs_root_xp ) );
     250    process->vfs_cwd_xp  = (xptr_t)hal_remote_lwd( XPTR( parent_cxy,
     251                                                         &parent_ptr->vfs_cwd_xp ) );
    255252    vfs_inode_remote_up( process->vfs_root_xp );
    256253    vfs_inode_remote_up( process->vfs_cwd_xp );
     
    469466////////////////////////////////////////
    470467void process_sigaction( pid_t       pid,
    471                         uint32_t    action_type )
     468                        uint32_t    type )
    472469{
    473470    cxy_t              owner_cxy;         // owner cluster identifier
     
    479476    xptr_t             process_xp;        // extended pointer on process copy
    480477    cxy_t              process_cxy;       // process copy cluster identifier
     478    process_t        * process_ptr;       // local pointer on process copy
    481479    reg_t              save_sr;           // for critical section
    482480    rpc_desc_t         rpc;               // shared RPC descriptor
    483 
    484     thread_t * client = CURRENT_THREAD;
     481    thread_t         * client;            // pointer on client thread
     482    xptr_t             client_xp;         // extended pointer on client thread
     483    process_t        * local;             // pointer on process copy in local cluster
     484    uint32_t           remote_nr;         // number of remote process copies
     485
     486    client    = CURRENT_THREAD;
     487    client_xp = XPTR( local_cxy , client );
     488    local     = NULL;
     489    remote_nr = 0;
    485490
    486491#if DEBUG_PROCESS_SIGACTION
    487492uint32_t cycle = (uint32_t)hal_get_cycles();
    488493if( DEBUG_PROCESS_SIGACTION < cycle )
    489 printk("\n[DBG] %s : thread %x enter to %s process %x / cycle %d\n",
    490 __FUNCTION__ , client, process_action_str( action_type ) , pid , cycle );
     494printk("\n[DBG] %s : thread %x in process %x enter to %s process %x / cycle %d\n",
     495__FUNCTION__ , client->trdid, client->process->pid,
     496process_action_str( type ) , pid , cycle );
    491497#endif
    492498
     
    503509
    504510    // check action type
    505     assert( ((action_type == DELETE_ALL_THREADS ) ||
    506              (action_type == BLOCK_ALL_THREADS )  ||
    507              (action_type == UNBLOCK_ALL_THREADS )), __FUNCTION__ , "illegal action type" );
     511    assert( ((type == DELETE_ALL_THREADS ) ||
     512             (type == BLOCK_ALL_THREADS )  ||
     513             (type == UNBLOCK_ALL_THREADS )), __FUNCTION__ , "illegal action type" );
    508514             
    509     // allocate a - shared - RPC descriptor in client thread stack
    510     // it can be shared because all parallel, non-blocking, server threads
    511     // use the same input arguments, and use the shared RPC response field
    512 
    513     // the client thread makes the following sequence:
    514     // 1. mask interrupts
    515     // 2. block itself
    516     // 3. send RPC requests to all copies
    517     // 4. unmask interrupts
    518     // 5. deschedule
     515
     516    // The client thread send parallel RPCs to all remote clusters containing
     517    // target process copies, wait all responses, and then handles directly the
     518    // threads in local cluster, when required.
     519    // The client thread allocates a - shared - RPC descriptor in the stack,
     520    // because all parallel, non-blocking, server threads use the same input
     521    // arguments, and use the shared RPC response field
    519522
    520523    // mask IRQs
    521524    hal_disable_irq( &save_sr);
    522525
    523     // client register blocking condition for itself
    524     thread_block( XPTR( local_cxy , client ) , THREAD_BLOCKED_RPC );
     526    // client thread blocks itself
     527    thread_block( client_xp , THREAD_BLOCKED_RPC );
    525528
    526529    // take the lock protecting the copies
     
    533536    rpc.thread    = client;
    534537    rpc.lid       = client->core->lid;
    535     rpc.args[0]   = action_type;
     538    rpc.args[0]   = type;
    536539    rpc.args[1]   = pid;
    537540
    538     // send RPCs to all clusters containing process copiess
     541    // scan list of process copies
     542    // to send RPCs to remote copies
    539543    XLIST_FOREACH( root_xp , iter_xp )
    540544    {
    541         // atomically increment responses counter
    542         hal_atomic_add( (void *)&rpc.responses , 1 );
    543 
     545        // get extended pointers and cluster on process
    544546        process_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
    545547        process_cxy = GET_CXY( process_xp );
     548        process_ptr = GET_PTR( process_xp );
     549
     550        if( process_cxy == local_cxy )    // process is local
     551        {
     552            local = process_ptr;
     553        }
     554        else                              // process is remote
     555        {
     556            // update number of remote process copies
     557            remote_nr++;
     558
     559            // atomically increment responses counter
     560            hal_atomic_add( (void *)&rpc.responses , 1 );
    546561
    547562#if DEBUG_PROCESS_SIGACTION
    548563if( DEBUG_PROCESS_SIGACTION < cycle )
    549 printk("\n[DBG] %s : send RPC to %s process %x in cluster %x\n",
    550 __FUNCTION__ , process_action_str( action_type ) , pid , process_cxy );
    551 #endif
    552         // call RPC in target cluster
    553         rpc_process_sigaction_client( process_cxy , &rpc );
    554     }
    555    
     564printk("\n[DBG] %s : thread %x in process %x handles remote process %x in cluster %x\n",
     565__FUNCTION__, client->trdid, client->process->pid, pid , process_cxy );
     566#endif
     567            // call RPC in target cluster
     568            rpc_process_sigaction_client( process_cxy , &rpc );
     569        }
     570    }  // end list of copies
     571
    556572    // release the lock protecting process copies
    557573    remote_spinlock_unlock( lock_xp );
     
    560576    hal_restore_irq( save_sr);
    561577
    562     // client thread deschedule : will be unblocked by the last RPC server thread
    563     sched_yield("blocked on rpc_process_sigaction");
     578    // - if there is remote process copies, the client thread deschedules,
     579    //   (it will be unblocked by the last RPC server thread).
     580    // - if there is no remote copies, the client thread unblock itself.
     581    if( remote_nr )
     582    {
     583        sched_yield("blocked on rpc_process_sigaction");
     584    }
     585    else
     586    {
     587        thread_unblock( client_xp , THREAD_BLOCKED_RPC );
     588    }
     589
     590    // handle the local process copy if required
     591    if( local != NULL )
     592    {
     593
     594#if DEBUG_PROCESS_SIGACTION
     595if( DEBUG_PROCESS_SIGACTION < cycle )
     596printk("\n[DBG] %s : thread %x in process %x handles local process %x in cluster %x\n",
     597__FUNCTION__, client->trdid, client->process->pid, pid , local_cxy );
     598#endif
     599        if     (type == DELETE_ALL_THREADS  ) process_delete_threads ( local , client_xp );
     600        else if(type == BLOCK_ALL_THREADS   ) process_block_threads  ( local , client_xp );
     601        else if(type == UNBLOCK_ALL_THREADS ) process_unblock_threads( local );
     602    }
    564603
    565604#if DEBUG_PROCESS_SIGACTION
    566605cycle = (uint32_t)hal_get_cycles();
    567606if( DEBUG_PROCESS_SIGACTION < cycle )
    568 printk("\n[DBG] %s : thread %x exit after %s process %x in cluster %x / cycle %d\n",
    569 __FUNCTION__ , client, process_action_str( action_type ) , pid , local_cxy , cycle );
     607printk("\n[DBG] %s : thread %x in process %x exit after %s process %x / cycle %d\n",
     608__FUNCTION__, client->trdid, client->process->pid,
     609process_action_str( type ), pid, cycle );
    570610#endif
    571611
     
    11001140uint32_t cycle = (uint32_t)hal_get_cycles();
    11011141if( DEBUG_PROCESS_MAKE_FORK < cycle )
    1102 printk("\n[DBG] %s : thread %x enter for process %x / cluster %x / cycle %d\n",
    1103 __FUNCTION__, CURRENT_THREAD, parent_pid, local_cxy, cycle );
     1142printk("\n[DBG] %s : thread %x in process %x enter / cluster %x / cycle %d\n",
     1143__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, local_cxy, cycle );
    11041144#endif
    11051145
     
    11231163    }
    11241164
     1165#if DEBUG_PROCESS_MAKE_FORK
     1166cycle = (uint32_t)hal_get_cycles();
     1167if( DEBUG_PROCESS_MAKE_FORK < cycle )
     1168printk("\n[DBG] %s : thread %x in process %x allocated process %x / cycle %d\n",
     1169__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, new_pid, cycle );
     1170#endif
     1171
    11251172    // initializes child process descriptor from parent process descriptor
    11261173    process_reference_init( process,
    11271174                            new_pid,
    1128                             parent_process_xp,
    11291175                            parent_process_xp );
    11301176
     
    11321178cycle = (uint32_t)hal_get_cycles();
    11331179if( DEBUG_PROCESS_MAKE_FORK < cycle )
    1134 printk("\n[DBG] %s : thread %x created child_process %x / child_pid %x / cycle %d\n",
    1135 __FUNCTION__, CURRENT_THREAD, process, new_pid, cycle );
    1136 #endif
     1180printk("\n[DBG] %s : thread %x in process %x initialized child_process %x / cycle %d\n",
     1181__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, new_pid, cycle );
     1182#endif
     1183
     1184    // give TXT ownership to child process
     1185    process_txt_set_ownership( XPTR( local_cxy , process ) );
    11371186
    11381187    // copy VMM from parent descriptor to child descriptor
     
    11511200cycle = (uint32_t)hal_get_cycles();
    11521201if( DEBUG_PROCESS_MAKE_FORK < cycle )
    1153 printk("\n[DBG] %s : thread %x copied VMM from parent %x to child %x / cycle %d\n",
    1154 __FUNCTION__ , CURRENT_THREAD , parent_pid, new_pid, cycle );
    1155 #endif
     1202printk("\n[DBG] %s : thread %x in process %x copied VMM from parent %x to child %x / cycle %d\n",
     1203__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,
     1204parent_pid, new_pid, cycle );
     1205#endif
     1206
     1207    // parent process gives TXT ownership to child process if required
     1208    if( process_txt_is_owner(parent_process_xp) )
     1209    {
     1210        process_txt_set_ownership( XPTR( local_cxy , process ) );
     1211
     1212#if( DEBUG_PROCESS_MAKE_FORK & 1 )
     1213cycle = (uint32_t)hal_get_cycles();
     1214if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1215printk("\n[DBG] %s : thread %x in process %x gives TXT from parent %x to child %x / cycle %d\n",
     1216__FUNCTION__ , CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,
     1217parent_pid, new_pid, cycle );
     1218#endif
     1219
     1220    }
    11561221
    11571222    // update extended pointer on .elf file
     
    11781243cycle = (uint32_t)hal_get_cycles();
    11791244if( DEBUG_PROCESS_MAKE_FORK < cycle )
    1180 printk("\n[DBG] %s : thread %x created child thread %x on core[%x,%d] / cycle %d\n",
    1181 __FUNCTION__ , CURRENT_THREAD, thread, local_cxy, thread->core->lid, cycle );
     1245printk("\n[DBG] %s : thread %x in process %x created main thread %x on core[%x,%d] / cycle %d\n",
     1246__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,
     1247thread, local_cxy, thread->core->lid, cycle );
    11821248#endif
    11831249
     
    12001266cycle = (uint32_t)hal_get_cycles();
    12011267if( DEBUG_PROCESS_MAKE_FORK < cycle )
    1202 printk("\n[DBG] %s : thread %x set COW in parent and child / cycle %d\n",
    1203 __FUNCTION__ , CURRENT_THREAD, cycle );
     1268printk("\n[DBG] %s : thread %x in process %x set COW in parent and child / cycle %d\n",
     1269__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, cycle );
    12041270#endif
    12051271
     
    12221288cycle = (uint32_t)hal_get_cycles();
    12231289if( DEBUG_PROCESS_MAKE_FORK < cycle )
    1224 printk("\n[DBG] %s : thread %x exit / cycle %d\n",
    1225 __FUNCTION__, CURRENT_THREAD, cycle );
     1290printk("\n[DBG] %s : thread %x in process %x exit / created process %x / cycle %d\n",
     1291__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, new_pid, cycle );
    12261292#endif
    12271293
     
    12291295
    12301296}   // end process_make_fork()
    1231 
    12321297
    12331298/////////////////////////////////////////////////////
    12341299error_t process_make_exec( exec_info_t  * exec_info )
    12351300{
    1236     char           * path;                    // pathname to .elf file
    1237     pid_t            pid;                     // old_process PID, given to new_process
    1238     pid_t            temp_pid;                // temporary PID / given to old_process
    1239     process_t      * old_process;             // local pointer on old process
    1240     thread_t       * old_thread;              // local pointer on old thread
    1241     process_t      * new_process;             // local pointer on new process
    1242     thread_t       * new_thread;              // local pointer on new thread
    1243     xptr_t           parent_xp;               // extended pointer on parent process
    1244     process_t      * parent_ptr;              // local pointer on parent process
    1245     cxy_t            parent_cxy;              // parent process cluster identifier
    1246     xptr_t           children_lock_xp;        // extended pointer on children lock in parent
    1247     xptr_t           children_root_xp;        // extended pointer on children root in parent
    1248     xptr_t           children_nr_xp;          // extended pointer on children number in parent
    1249     thread_t       * parent_main_ptr;         // local pointer on parent main thread
    1250     xptr_t           parent_main_xp;          // extended pointer on parent main thread
    1251     pthread_attr_t   attr;                    // new thread attributes
    1252     lid_t            lid;                     // selected core local index
     1301    thread_t       * thread;                  // local pointer on this thread
     1302    process_t      * process;                 // local pointer on this process
     1303    pid_t            pid;                     // this process identifier
    12531304        error_t          error;                   // value returned by called functions
    1254    
    1255     // get old_thread, old_process & PID
    1256     old_thread  = CURRENT_THREAD;
    1257     old_process = old_thread->process;
    1258     pid         = old_process->pid;
    1259 
    1260         // get .elf pathname from exec_info
    1261         path = exec_info->path;
    1262 
    1263     // this function must be executed by a thread running in owner cluster
    1264     assert( (CXY_FROM_PID( pid ) == local_cxy), __FUNCTION__,
    1265     "local_cluster must be owner_cluster\n" );
    1266 
    1267     assert( (LTID_FROM_TRDID( old_thread->trdid ) == 0) , __FUNCTION__,
    1268     "must be called by the main thread\n" );
    1269  
     1305    char           * path;                    // path to .elf file
     1306    xptr_t           file_xp;                 // extended pointer on .elf file descriptor
     1307    uint32_t         file_id;                 // file index in fd_array
     1308    uint32_t         args_nr;                 // number of main thread arguments
     1309    char          ** args_pointers;           // array of pointers on main thread arguments
     1310
     1311    // get thread, process & PID
     1312    thread  = CURRENT_THREAD;
     1313    process = thread->process;
     1314    pid     = process->pid;
     1315
     1316        // get relevant infos from exec_info
     1317        path          = exec_info->path;
     1318    args_nr       = exec_info->args_nr;
     1319    args_pointers = exec_info->args_pointers;
     1320
    12701321#if DEBUG_PROCESS_MAKE_EXEC
    12711322uint32_t cycle = (uint32_t)hal_get_cycles();
    12721323if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    12731324printk("\n[DBG] %s : thread %x in process %x enters / path %s / cycle %d\n",
    1274 __FUNCTION__, old_thread->trdid, pid, path, cycle );
    1275 #endif
    1276 
    1277     // get parent process pointers
    1278     parent_xp   = old_process->parent_xp;
    1279     parent_cxy  = GET_CXY( parent_xp );
    1280     parent_ptr  = GET_PTR( parent_xp );
    1281    
     1325__FUNCTION__, thread->trdid, pid, path, cycle );
     1326#endif
     1327
     1328    // open the file identified by <path>
     1329    file_xp = XPTR_NULL;
     1330    file_id = -1;
     1331        error   = vfs_open( process,
     1332                            path,
     1333                            O_RDONLY,
     1334                            0,
     1335                            &file_xp,
     1336                            &file_id );
     1337        if( error )
     1338        {
     1339                printk("\n[ERROR] in %s : failed to open file <%s>\n", __FUNCTION__ , path );
     1340                return -1;
     1341        }
     1342
    12821343#if (DEBUG_PROCESS_MAKE_EXEC & 1)
    12831344if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1284 printk("\n[DBG] %s : thread %x in process %x get parent process %x in cluster %x\n",
    1285 __FUNCTION__, old_thread->trdid, pid, parent_ptr, parent_cxy );
    1286 #endif
    1287 
    1288     // get extended pointers on parent children_root, children_lock and children_nr
    1289     children_root_xp = XPTR( parent_cxy , &parent_ptr->children_root );
    1290     children_lock_xp = XPTR( parent_cxy , &parent_ptr->children_lock );
    1291     children_nr_xp   = XPTR( parent_cxy , &parent_ptr->children_nr   );
    1292 
    1293     // get pointers on the parent process main thread
    1294     parent_main_ptr = hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->th_tbl[0] ) );
    1295     parent_main_xp  = XPTR( parent_cxy , parent_main_ptr );
    1296 
    1297      // allocate memory for new_process descriptor
    1298     new_process = process_alloc();
    1299 
    1300     if( new_process == NULL )
    1301     {
    1302         printk("\n[ERROR] in %s : cannot allocate process for %s\n", __FUNCTION__ , path );
     1345printk("\n[DBG] %s : open file <%s>\n", __FUNCTION__, path );
     1346#endif
     1347
     1348    // delete all threads other than this main thread in all clusters
     1349    process_sigaction( pid , DELETE_ALL_THREADS );
     1350
     1351    // reset local process VMM
     1352    vmm_destroy( process );
     1353
     1354#if( DEBUG_PROCESS_MAKE_EXEC & 1 )
     1355cycle = (uint32_t)hal_get_cycles();
     1356if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1357printk("\n[DBG] %s : thread %x in process %x / reset VMM / cycle %d\n",
     1358__FUNCTION__, thread->trdid, pid, cycle );
     1359#endif
     1360
     1361    // re-initialize the VMM (kentry/args/envs vsegs registration)
     1362    error = vmm_init( process );
     1363    if( error )
     1364    {
     1365        printk("\n[ERROR] in %s : cannot initialise VMM for %s\n", __FUNCTION__ , path );
     1366        vfs_close( file_xp , file_id );
     1367        // FIXME restore old process VMM
    13031368        return -1;
    13041369    }
    1305 
    1306     // get a temporary PID for old_process
    1307     error = cluster_pid_alloc( old_process , &temp_pid );
    1308     if( error )
    1309     {
    1310         printk("\n[ERROR] in %s : cannot get PID in cluster %x\n",
    1311         __FUNCTION__ , local_cxy );
    1312         process_free( new_process );
    1313         return -1;
    1314     }
    1315 
    1316     // set temporary PID to old_process
    1317     old_process->pid = temp_pid;
    1318 
    1319     // initialize new process descriptor
    1320     process_reference_init( new_process,
    1321                             pid,
    1322                             parent_xp,                          // parent_process_xp
    1323                             XPTR(local_cxy , old_process) );    // model_process
    1324 
    1325     // give TXT ownership to new_process
    1326     process_txt_set_ownership( XPTR( local_cxy , new_process) );
    1327 
     1370   
    13281371#if( DEBUG_PROCESS_MAKE_EXEC & 1 )
    13291372cycle = (uint32_t)hal_get_cycles();
    13301373if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1331 printk("\n[DBG] %s : thread %x in process %x created new process %x\n",
    1332 __FUNCTION__ , old_thread->trdid, pid, new_process );
    1333 #endif
    1334 
    1335     // register code & data vsegs as well as entry-point in new process VMM,
     1374printk("\n[DBG] %s : thread %x in process %x / kentry/args/envs vsegs registered / cycle %d\n",
     1375__FUNCTION__, thread->trdid, pid, cycle );
     1376#endif
     1377
     1378    // register code & data vsegs as well as entry-point in process VMM,
    13361379    // and register extended pointer on .elf file in process descriptor
    1337         error = elf_load_process( path , new_process );
    1338 
     1380        error = elf_load_process( file_xp , process );
    13391381    if( error )
    13401382        {
    13411383                printk("\n[ERROR] in %s : failed to access <%s>\n", __FUNCTION__ , path );
    1342         process_txt_set_ownership( XPTR( local_cxy , old_process) );
    1343         process_txt_detach( XPTR( local_cxy , new_process) );
    1344         process_destroy( new_process );
    1345         old_process->pid = pid;
     1384        vfs_close( file_xp , file_id );
     1385        // FIXME restore old process VMM
    13461386        return -1;
    13471387        }
     
    13501390cycle = (uint32_t)hal_get_cycles();
    13511391if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1352 printk("\n[DBG] %s : thread %x registered code/data vsegs in new process %x / cycle %d\n",
    1353 __FUNCTION__, old_thread , new_process->pid , cycle );
    1354 #endif
    1355 
    1356     // select a core in local cluster to execute the main thread
    1357     lid  = cluster_select_local_core();
    1358 
    1359     // initialize pthread attributes for main thread
    1360     attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED | PT_ATTR_CORE_DEFINED;
    1361     attr.cxy        = local_cxy;
    1362     attr.lid        = lid;
    1363 
    1364     // create and initialize main thread in local cluster
    1365         error = thread_user_create( pid,
    1366                                 (void *)new_process->vmm.entry_point,
    1367                                 exec_info->args_pointers,
    1368                                 &attr,
    1369                                 &new_thread );
    1370         if( error )
    1371         {
    1372                 printk("\n[ERROR] in %s : cannot create thread for %s\n", __FUNCTION__ , path );
    1373         process_txt_set_ownership( XPTR( local_cxy , old_process) );
    1374         process_txt_detach( XPTR( local_cxy , new_process) );
    1375         process_destroy( new_process );
    1376         old_process->pid = pid;
     1392printk("\n[DBG] %s : thread %x in process %x / code/data vsegs registered / cycle %d\n",
     1393__FUNCTION__, thread->trdid, pid, cycle );
     1394#endif
     1395
     1396    // update the existing main thread descriptor... and jump to user code
     1397    error = thread_user_exec( (void *)process->vmm.entry_point,
     1398                              args_nr,
     1399                              args_pointers );
     1400    if( error )
     1401    {
     1402        printk("\n[ERROR] in %s : cannot reset main thread for %s\n", __FUNCTION__ , path );
     1403        vfs_close( file_xp , file_id );
     1404        // FIXME restore old process VMM
    13771405        return -1;
    1378         }
    1379 
    1380     // check main thread LTID
    1381     assert( (LTID_FROM_TRDID(new_thread->trdid) == 0) , __FUNCTION__ ,
    1382     "main thread must have LTID == 0\n" );
    1383 
    1384 #if( DEBUG_PROCESS_MAKE_EXEC & 1 )
    1385 cycle = (uint32_t)hal_get_cycles();
    1386 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1387 printk("\n[DBG] %s : thread %x created new_process main thread %x / cycle %d\n",
    1388 __FUNCTION__ , old_thread , new_thread , cycle );
    1389 #endif
    1390 
    1391     // register new_process in parent children list
    1392     remote_spinlock_lock( children_lock_xp );
    1393         xlist_add_last( children_root_xp , XPTR( local_cxy , &new_process->children_list ) );
    1394         hal_remote_atomic_add( children_nr_xp , 1 );
    1395     remote_spinlock_unlock( children_lock_xp );
    1396 
    1397     // activate new thread
    1398         thread_unblock( XPTR( local_cxy , new_thread ) , THREAD_BLOCKED_GLOBAL );
    1399 
    1400     // detach old_process from TXT
    1401     process_txt_detach( XPTR( local_cxy , old_process ) );
    1402 
    1403     // block old_thread
    1404     thread_block( XPTR( local_cxy , old_thread ) , THREAD_BLOCKED_GLOBAL );
    1405 
    1406     // atomically update old_process termination state
    1407     hal_atomic_or( &old_process->term_state , PROCESS_TERM_EXIT );
    1408 
    1409     // take the children lock and unblock the parent process main thread
    1410     remote_spinlock_lock( children_lock_xp );
    1411     thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT );
    1412     remote_spinlock_unlock( children_lock_xp );
    1413 
    1414     hal_fence();
    1415 
    1416 #if DEBUG_PROCESS_MAKE_EXEC
    1417 cycle = (uint32_t)hal_get_cycles();
    1418 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1419 printk("\n[DBG] %s : old thread %x blocked for delete / new thread %x activated / cycle %d\n",
    1420 __FUNCTION__ , old_thread , new_thread , cycle );
    1421 #endif
    1422    
     1406    }
     1407
     1408    assert( false, __FUNCTION__, "we should not execute this code");
     1409 
    14231410        return 0;
    14241411
    14251412}  // end process_make_exec()
     1413
    14261414
    14271415///////////////////////////////////////////////
     
    14741462    pthread_attr_t   attr;          // main thread attributes
    14751463    lid_t            lid;           // selected core local index for main thread
     1464    xptr_t           file_xp;       // extended pointer on .elf file descriptor
     1465    uint32_t         file_id;       // file index in fd_array
    14761466    error_t          error;
    14771467
     
    14791469uint32_t cycle = (uint32_t)hal_get_cycles();
    14801470if( DEBUG_PROCESS_INIT_CREATE < cycle )
    1481 printk("\n[DBG] %s : thread %x enter / cycle %d\n", __FUNCTION__, CURRENT_THREAD, cycle );
     1471printk("\n[DBG] %s : thread %x in process %x enter / cycle %d\n",
     1472__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, cycle );
    14821473#endif
    14831474
    14841475    // allocates memory for process descriptor from local cluster
    14851476        process = process_alloc();
    1486         if( process == NULL )
    1487     {
    1488                 printk("\n[PANIC] in %s : no memory for process descriptor in cluster %x\n",
    1489                 __FUNCTION__, local_cxy  );
    1490     }
     1477       
     1478    assert( (process != NULL), __FUNCTION__,
     1479    "no memory for process descriptor in cluster %x\n", local_cxy  );
    14911480
    14921481    // get PID from local cluster
    14931482    error = cluster_pid_alloc( process , &pid );
    1494     if( error )
    1495     {
    1496                 printk("\n[PANIC] in %s : cannot allocate PID in cluster %x\n",
    1497                 __FUNCTION__, local_cxy );
    1498         process_free( process );
    1499     }
    1500 
    1501     // check allocated PID
    1502     assert( (pid == 1) , __FUNCTION__ , "process INIT must be first process in cluster 0\n" );
     1483
     1484    assert( (error == 0), __FUNCTION__,
     1485    "cannot allocate PID in cluster %x\n", local_cxy );
     1486
     1487    assert( (pid == 1) , __FUNCTION__,
     1488    "process INIT must be first process in cluster 0\n" );
    15031489
    15041490    // initialize process descriptor / parent is local process_zero
    15051491    process_reference_init( process,
    15061492                            pid,
    1507                             XPTR( local_cxy , &process_zero ),     // parent
    1508                             XPTR( local_cxy , &process_zero ) );   // model
     1493                            XPTR( local_cxy , &process_zero ) ); 
     1494
     1495    // open the file identified by CONFIG_PROCESS_INIT_PATH
     1496    file_xp = XPTR_NULL;
     1497    file_id = -1;
     1498        error   = vfs_open( process,
     1499                            CONFIG_PROCESS_INIT_PATH,
     1500                            O_RDONLY,
     1501                            0,
     1502                            &file_xp,
     1503                            &file_id );
     1504
     1505        assert( (error == 0), __FUNCTION__,
     1506    "failed to open file <%s>\n", CONFIG_PROCESS_INIT_PATH );
    15091507
    15101508    // register "code" and "data" vsegs as well as entry-point
    15111509    // in process VMM, using information contained in the elf file.
    1512         if( elf_load_process( CONFIG_PROCESS_INIT_PATH , process ) )
    1513         {
    1514                 printk("\n[PANIC] in %s : cannot access .elf file / path = %s\n",
    1515                 __FUNCTION__, CONFIG_PROCESS_INIT_PATH );
    1516         process_destroy( process );
    1517         }
     1510        error = elf_load_process( file_xp , process );
     1511
     1512        assert( (error == 0), __FUNCTION__,
     1513    "cannot access .elf file <%s>\n", CONFIG_PROCESS_INIT_PATH );
    15181514
    15191515    // get extended pointers on process_zero children_root, children_lock
     
    15411537                                &attr,
    15421538                                &thread );
    1543         if( error )
    1544         {
    1545                 printk("\n[PANIC] in %s : cannot create main thread / path = %s\n",
    1546                 __FUNCTION__, CONFIG_PROCESS_INIT_PATH );
    1547         process_destroy( process );
    1548         }
    1549 
    1550     // check main thread index
    1551     assert( (thread->trdid == 0) , __FUNCTION__ , "main thread must have index 0\n" );
     1539
     1540        assert( (error == 0), __FUNCTION__,
     1541    "cannot create main thread for <%s>\n", CONFIG_PROCESS_INIT_PATH );
     1542
     1543    assert( (thread->trdid == 0), __FUNCTION__,
     1544    "main thread must have index 0 for <%s>\n", CONFIG_PROCESS_INIT_PATH );
    15521545
    15531546    // activate thread
     
    15591552cycle = (uint32_t)hal_get_cycles();
    15601553if( DEBUG_PROCESS_INIT_CREATE < cycle )
    1561 printk("\n[DBG] %s : thread %x exit / cycle %d\n", __FUNCTION__, CURRENT_THREAD, cycle );
     1554printk("\n[DBG] %s : thread %x in process %x exit / cycle %d\n",
     1555__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, cycle );
    15621556#endif
    15631557
     
    17021696    xptr_t      lock_xp;      // extended pointer on list lock in chdev
    17031697
    1704 #if DEBUG_PROCESS_TXT
    1705 uint32_t cycle = (uint32_t)hal_get_cycles();
    1706 if( DEBUG_PROCESS_TXT < cycle )
    1707 printk("\n[DBG] %s : thread %x enter for process %x / txt_id = %d  / cycle %d\n",
    1708 __FUNCTION__, CURRENT_THREAD, process->pid, txt_id, cycle );
    1709 #endif
    1710 
    17111698    // check process is in owner cluster
    17121699    assert( (CXY_FROM_PID( process->pid ) == local_cxy) , __FUNCTION__ ,
     
    17321719
    17331720#if DEBUG_PROCESS_TXT
    1734 cycle = (uint32_t)hal_get_cycles();
     1721uint32_t cycle = (uint32_t)hal_get_cycles();
    17351722if( DEBUG_PROCESS_TXT < cycle )
    1736 printk("\n[DBG] %s : thread %x exit for process %x / txt_id = %d / cycle %d\n",
    1737 __FUNCTION__, CURRENT_THREAD, process->pid, txt_id , cycle );
     1723printk("\n[DBG] %s : thread %x in process %x attached process %x to TXT %d / cycle %d\n",
     1724__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,
     1725process->pid, txt_id , cycle );
    17381726#endif
    17391727
     
    17551743    process_cxy = GET_CXY( process_xp );
    17561744    process_ptr = GET_PTR( process_xp );
     1745
     1746    // check process descriptor in owner cluster
    17571747    process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) );
    1758 
    1759     // check process descriptor in owner cluster
    17601748    assert( (CXY_FROM_PID( process_pid ) == process_cxy ) , __FUNCTION__ ,
    17611749    "process descriptor not in owner cluster" );
    1762 
    1763 #if DEBUG_PROCESS_TXT
    1764 uint32_t cycle = (uint32_t)hal_get_cycles();
    1765 if( DEBUG_PROCESS_TXT < cycle )
    1766 printk("\n[DBG] %s : thread %x enter for process %x / cycle %d\n",
    1767 __FUNCTION__, CURRENT_THREAD, process_pid, cycle );
    1768 #endif
    17691750
    17701751    // release TXT ownership (does nothing if not TXT owner)
     
    17881769
    17891770#if DEBUG_PROCESS_TXT
    1790 cycle  = (uint32_t)hal_get_cycles();
     1771uint32_t cycle  = (uint32_t)hal_get_cycles();
    17911772uint32_t txt_id = hal_remote_lw( XPTR( chdev_cxy , &chdev_ptr->channel ) );
    17921773if( DEBUG_PROCESS_TXT < cycle )
    1793 printk("\n[DBG] %s : thread %x exit / process %x detached from TXT %d / cycle %d\n",
    1794 __FUNCTION__, CURRENT_THREAD, process_pid, txt_id, cycle );
     1774printk("\n[DBG] %s : thread %x in process %x detached process %x from TXT %d / cycle %d\n",
     1775__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,
     1776process_pid, txt_id, cycle );
    17951777#endif
    17961778
     
    18111793    process_cxy = GET_CXY( process_xp );
    18121794    process_ptr = GET_PTR( process_xp );
    1813 
    1814     // get process PID
    18151795    process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) );
    18161796
     
    18181798    assert( (process_cxy == CXY_FROM_PID( process_pid )) , __FUNCTION__,
    18191799    "process descriptor not in owner cluster\n" );
    1820 
    1821 #if DEBUG_PROCESS_TXT
    1822 uint32_t cycle = (uint32_t)hal_get_cycles();
    1823 if( DEBUG_PROCESS_TXT < cycle )
    1824 printk("\n[DBG] %s : thread %x enter for process %x / cycle %d\n",
    1825 __FUNCTION__, CURRENT_THREAD, process_pid, cycle );
    1826 #endif
    18271800
    18281801    // get extended pointer on stdin pseudo file
     
    18381811
    18391812#if DEBUG_PROCESS_TXT
    1840 cycle = (uint32_t)hal_get_cycles();
     1813uint32_t cycle  = (uint32_t)hal_get_cycles();
     1814uint32_t txt_id = hal_remote_lw( XPTR( txt_cxy , &txt_ptr->channel ) );
    18411815if( DEBUG_PROCESS_TXT < cycle )
    1842 printk("\n[DBG] %s : thread %x exit for process %x / cycle %d\n",
    1843 __FUNCTION__, CURRENT_THREAD, process_pid, cycle );
     1816printk("\n[DBG] %s : thread %x in process %x give TXT %d to process %x / cycle %d\n",
     1817__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, txt_id, process_pid, cycle );
    18441818#endif
    18451819
     
    18651839    cxy_t       current_cxy;     // cluster for current process
    18661840
     1841#if DEBUG_PROCESS_TXT
     1842uint32_t cycle;
     1843#endif
     1844
    18671845    // get pointers on process in owner cluster
    18681846    process_cxy = GET_CXY( process_xp );
    18691847    process_ptr = GET_PTR( process_xp );
    1870 
    1871     // get process PID
    18721848    process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) );
    18731849
     
    18751851    assert( (process_cxy == CXY_FROM_PID( process_pid )) , __FUNCTION__,
    18761852    "process descriptor not in owner cluster\n" );
    1877 
    1878 #if DEBUG_PROCESS_TXT
    1879 uint32_t cycle = (uint32_t)hal_get_cycles();
    1880 if( DEBUG_PROCESS_TXT < cycle )
    1881 printk("\n[DBG] %s : thread %x enter / process %x / cycle %d\n",
    1882 __FUNCTION__, CURRENT_THREAD, process_pid, cycle );
    1883 #endif
    18841853
    18851854    // get extended pointer on stdin pseudo file
     
    18951864    txt_id   = hal_remote_lw ( XPTR( txt_cxy , &txt_ptr->channel ) );
    18961865
    1897 #if( DEBUG_PROCESS_TXT & 1 )
    1898 if( DEBUG_PROCESS_TXT < cycle )
    1899 printk("\n[DBG] %s : file_ptr %x / txt_ptr %x / txt_id %d / owner_ptr = %x\n",
    1900 __FUNCTION__, GET_PTR(file_xp), txt_ptr, txt_id, GET_PTR(owner_xp) );
    1901 #endif
    1902 
    19031866    // transfer ownership only if process is the TXT owner
    19041867    if( (owner_xp == process_xp) && (txt_id > 0) ) 
     
    19131876        if( process_get_ppid( process_xp ) != 1 )           // process is not KSH
    19141877        {
    1915 
    1916 #if( DEBUG_PROCESS_TXT & 1 )
    1917 if( DEBUG_PROCESS_TXT < cycle )
    1918 printk("\n[DBG] %s : process is not the KSH process => search the KSH\n", __FUNCTION__ );
    1919 #endif
    19201878            // scan attached process list to find KSH process
    19211879            XLIST_FOREACH( root_xp , iter_xp )
     
    19341892
    19351893#if DEBUG_PROCESS_TXT
    1936 cycle = (uint32_t)hal_get_cycles();
     1894cycle   = (uint32_t)hal_get_cycles();
     1895uint32_t ksh_pid = hal_remote_lw( XPTR( current_cxy , &current_ptr->pid ) );
    19371896if( DEBUG_PROCESS_TXT < cycle )
    1938 printk("\n[DBG] %s : thread %x exit / process %x to KSH process %x / cycle %d\n",
    1939 __FUNCTION__, CURRENT_THREAD, process_pid,
    1940 hal_remote_lw( XPTR( current_cxy , &current_ptr->pid ) ), cycle );
     1897printk("\n[DBG] %s : thread %x in process %x release TXT %d to KSH %x / cycle %d\n",
     1898__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, txt_id, ksh_pid, cycle );
     1899process_txt_display( txt_id );
    19411900#endif
    19421901                     return;
     
    19541913        else                                               // process is KSH
    19551914        {
    1956 
    1957 #if( DEBUG_PROCESS_TXT & 1 )
    1958 if( DEBUG_PROCESS_TXT < cycle )
    1959 printk("\n[DBG] %s : process is the KSH process => search another\n", __FUNCTION__ );
    1960 #endif
    1961 
    19621915            // scan attached process list to find another process
    19631916            XLIST_FOREACH( root_xp , iter_xp )
     
    19761929
    19771930#if DEBUG_PROCESS_TXT
    1978 cycle = (uint32_t)hal_get_cycles();
     1931cycle   = (uint32_t)hal_get_cycles();
     1932uint32_t new_pid = hal_remote_lw( XPTR( current_cxy , &current_ptr->pid ) );
    19791933if( DEBUG_PROCESS_TXT < cycle )
    1980 printk("\n[DBG] %s : thread %x exit / KSH process %x to process %x / cycle %d\n",
    1981 __FUNCTION__, CURRENT_THREAD, process_pid,
    1982 hal_remote_lw( XPTR( current_cxy , &current_ptr->pid ) ), cycle );
     1934printk("\n[DBG] %s : thread %x in process %x release TXT %d to process %x / cycle %d\n",
     1935__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, txt_id, new_pid, cycle );
     1936process_txt_display( txt_id );
    19831937#endif
    19841938                     return;
     
    19951949cycle = (uint32_t)hal_get_cycles();
    19961950if( DEBUG_PROCESS_TXT < cycle )
    1997 printk("\n[DBG] %s : thread %x exit / KSH process %x to nobody / cycle %d\n",
    1998 __FUNCTION__, CURRENT_THREAD, process_pid, cycle );
     1951printk("\n[DBG] %s : thread %x in process %x release TXT %d to nobody / cycle %d\n",
     1952__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, txt_id, cycle );
     1953process_txt_display( txt_id );
    19991954#endif
    20001955            return;
     
    20071962cycle = (uint32_t)hal_get_cycles();
    20081963if( DEBUG_PROCESS_TXT < cycle )
    2009 printk("\n[DBG] %s : thread %x exit / process %x is not TXT owner / cycle %d\n",
    2010 __FUNCTION__, CURRENT_THREAD, process_pid, cycle );
     1964printk("\n[DBG] %s : thread %x in process %d does nothing (not TXT owner) / cycle %d\n",
     1965__FUNCTION__, CURRENT_THREAD->trdid, process_pid, cycle );
     1966process_txt_display( txt_id );
    20111967#endif
    20121968
     
    20141970}  // end process_txt_transfer_ownership()
    20151971
     1972
     1973//////////////////////////////////////////////////
     1974uint32_t process_txt_is_owner( xptr_t process_xp )
     1975{
     1976    // get local pointer and cluster of process in owner cluster
     1977    cxy_t       process_cxy = GET_CXY( process_xp );
     1978    process_t * process_ptr = GET_PTR( process_xp );
     1979
     1980    // check owner cluster
     1981    pid_t process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) );
     1982    assert( (process_cxy == CXY_FROM_PID( process_pid )) , __FUNCTION__,
     1983    "process descriptor not in owner cluster\n" );
     1984
     1985    // get extended pointer on stdin pseudo file
     1986    xptr_t file_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->fd_array.array[0] ) );
     1987
     1988    // get pointers on TXT chdev
     1989    xptr_t    txt_xp  = chdev_from_file( file_xp );
     1990    cxy_t     txt_cxy = GET_CXY( txt_xp );
     1991    chdev_t * txt_ptr = GET_PTR( txt_xp );
     1992
     1993    // get extended pointer on TXT_RX owner process
     1994    xptr_t owner_xp = hal_remote_lwd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) );
     1995
     1996    return (process_xp == owner_xp);
     1997
     1998}   // end process_txt_is_owner()
    20161999
    20172000////////////////////////////////////////////////     
     
    20232006
    20242007    return (xptr_t)hal_remote_lwd( XPTR( txt_rx_cxy , &txt_rx_ptr->ext.txt.owner_xp ) );
    2025 }
     2008
     2009}  // end process_txt_get_owner()
    20262010
    20272011///////////////////////////////////////////
Note: See TracChangeset for help on using the changeset viewer.