Changeset 428 for trunk/kernel


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

blip

Location:
trunk/kernel/kern
Files:
6 deleted
16 edited

Legend:

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

    r418 r428  
    276276}  // end chdev_sequencial_server()
    277277
     278////////////////////////////////////////
     279xptr_t chdev_from_file( xptr_t file_xp )
     280{
     281    cxy_t         file_cxy;
     282    vfs_file_t  * file_ptr;
     283    uint32_t      inode_type;
     284    vfs_inode_t * inode_ptr;
     285    chdev_t     * chdev_ptr;
     286
     287    // get cluster and local pointer on remote file descriptor
     288    // associated inode and chdev are stored in same cluster as the file desc.
     289    file_cxy  = GET_CXY( file_xp );
     290    file_ptr  = (vfs_file_t *)GET_PTR( file_xp );
     291
     292    // get inode type from file descriptor
     293    inode_type = hal_remote_lw( XPTR( file_cxy , &file_ptr->type ) );
     294    inode_ptr  = (vfs_inode_t *)hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) );
     295
     296    assert( (inode_type == INODE_TYPE_DEV) , __FUNCTION__ ,
     297    "inode type %d is not INODE_TYPE_DEV", inode_type );
     298
     299    // get chdev local pointer from inode extension
     300    chdev_ptr = (chdev_t *)hal_remote_lpt( XPTR( file_cxy , &inode_ptr->extend ) );
     301
     302    return XPTR( file_cxy , chdev_ptr );
     303
     304}  // end chdev_from_file()
     305
    278306////////////////////////
    279307void chdev_dir_display()
    280308{
    281     cxy_t     iob_cxy  = GET_CXY( chdev_dir.iob );
    282     chdev_t * iob_ptr  = (chdev_t *)GET_PTR( chdev_dir.iob );
    283     uint32_t  iob_base = (uint32_t)hal_remote_lwd( XPTR( iob_cxy , &iob_ptr->base ) );
    284 
    285     cxy_t     pic_cxy  = GET_CXY( chdev_dir.pic );
    286     chdev_t * pic_ptr  = (chdev_t *)GET_PTR( chdev_dir.pic );
    287     uint32_t  pic_base = (uint32_t)hal_remote_lwd( XPTR( pic_cxy , &pic_ptr->base ) );
    288 
    289     cxy_t     txt0_tx_cxy  = GET_CXY( chdev_dir.txt_tx[0] );
    290     chdev_t * txt0_tx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_tx[0] );
    291     uint32_t  txt0_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt0_tx_cxy , &txt0_tx_ptr->base ) );
    292 
    293     cxy_t     txt0_rx_cxy  = GET_CXY( chdev_dir.txt_rx[0] );
    294     chdev_t * txt0_rx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_rx[0] );
    295     uint32_t  txt0_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt0_rx_cxy , &txt0_rx_ptr->base ) );
    296 
    297     cxy_t     txt1_tx_cxy  = GET_CXY( chdev_dir.txt_tx[1] );
    298     chdev_t * txt1_tx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_tx[1] );
    299     uint32_t  txt1_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt1_tx_cxy , &txt1_tx_ptr->base ) );
    300 
    301     cxy_t     txt1_rx_cxy  = GET_CXY( chdev_dir.txt_rx[1] );
    302     chdev_t * txt1_rx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_rx[1] );
    303     uint32_t  txt1_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt1_rx_cxy , &txt1_rx_ptr->base ) );
    304 
    305     cxy_t     txt2_tx_cxy  = GET_CXY( chdev_dir.txt_tx[2] );
    306     chdev_t * txt2_tx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_tx[2] );
    307     uint32_t  txt2_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt2_tx_cxy , &txt2_tx_ptr->base ) );
    308 
    309     cxy_t     txt2_rx_cxy  = GET_CXY( chdev_dir.txt_rx[2] );
    310     chdev_t * txt2_rx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_rx[2] );
    311     uint32_t  txt2_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt2_rx_cxy , &txt2_rx_ptr->base ) );
    312 
    313     cxy_t     ioc_cxy  = GET_CXY( chdev_dir.ioc[0] );
    314     chdev_t * ioc_ptr  = (chdev_t *)GET_PTR( chdev_dir.ioc[0] );
    315     uint32_t  ioc_base = (uint32_t)hal_remote_lwd( XPTR( ioc_cxy , &ioc_ptr->base ) );
    316 
    317     cxy_t     fbf_cxy  = GET_CXY( chdev_dir.fbf[0] );
    318     chdev_t * fbf_ptr  = (chdev_t *)GET_PTR( chdev_dir.fbf[0] );
    319     uint32_t  fbf_base = (uint32_t)hal_remote_lwd( XPTR( fbf_cxy , &fbf_ptr->base ) );
    320 
    321     cxy_t     nic0_rx_cxy  = GET_CXY( chdev_dir.nic_rx[0] );
    322     chdev_t * nic0_rx_ptr  = (chdev_t *)GET_PTR( chdev_dir.nic_rx[0] );
    323     uint32_t  nic0_rx_base = (uint32_t)hal_remote_lwd( XPTR( nic0_rx_cxy , &nic0_rx_ptr->base ) );
    324 
    325     cxy_t     nic0_tx_cxy  = GET_CXY( chdev_dir.nic_tx[0] );
    326     chdev_t * nic0_tx_ptr  = (chdev_t *)GET_PTR( chdev_dir.nic_tx[0] );
    327     uint32_t  nic0_tx_base = (uint32_t)hal_remote_lwd( XPTR( nic0_tx_cxy , &nic0_tx_ptr->base ) );
    328 
    329     printk("\n***** external chdev directory in cluster %x\n"
    330            "  - iob       : cxy = %X / ptr = %X / base = %X\n"
    331            "  - pic       : cxy = %X / ptr = %X / base = %X\n"
    332            "  - ioc       : cxy = %X / ptr = %X / base = %X\n"
    333            "  - fbf       : cxy = %X / ptr = %X / base = %X\n"
    334            "  - txt_rx[0] : cxy = %X / ptr = %X / base = %X\n"
    335            "  - txt_tx[0] : cxy = %X / ptr = %X / base = %X\n"
    336            "  - txt_rx[1] : cxy = %X / ptr = %X / base = %X\n"
    337            "  - txt_tx[1] : cxy = %X / ptr = %X / base = %X\n"
    338            "  - txt_rx[2] : cxy = %X / ptr = %X / base = %X\n"
    339            "  - txt_tx[2] : cxy = %X / ptr = %X / base = %X\n"
    340            "  - nic_rx[0] : cxy = %X / ptr = %X / base = %X\n"
    341            "  - nic_tx[0] : cxy = %X / ptr = %X / base = %X\n",
    342            local_cxy,
    343            iob_cxy , iob_ptr , iob_base ,
    344            pic_cxy , pic_ptr , pic_base ,
    345            ioc_cxy , ioc_ptr , ioc_base ,
    346            fbf_cxy , fbf_ptr , fbf_base ,
    347            txt0_rx_cxy , txt0_rx_ptr , txt0_rx_base ,
    348            txt0_tx_cxy , txt0_tx_ptr , txt0_tx_base ,
    349            txt1_rx_cxy , txt1_rx_ptr , txt1_rx_base ,
    350            txt1_tx_cxy , txt1_tx_ptr , txt1_tx_base ,
    351            txt2_rx_cxy , txt2_rx_ptr , txt2_rx_base ,
    352            txt2_tx_cxy , txt2_tx_ptr , txt2_tx_base ,
    353            nic0_rx_cxy , nic0_rx_ptr , nic0_rx_base ,
    354            nic0_tx_cxy , nic0_tx_ptr , nic0_tx_base );
     309    uint32_t  i;
     310    cxy_t     cxy;
     311    chdev_t * ptr;
     312    uint32_t  base;
     313    reg_t     save_sr;
     314
     315    // get pointers on TXT0 chdev
     316    xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
     317    cxy_t     txt0_cxy = GET_CXY( txt0_xp );
     318    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
     319
     320    // get extended pointer on remote TXT0 chdev lock
     321    xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
     322
     323    // get TXT0 lock in busy waiting mode
     324    remote_spinlock_lock_busy( lock_xp , &save_sr );
     325
     326    // header
     327    nolock_printk("\n***** external chdevs directory *****\n");
     328
     329    // IOB
     330    cxy  = GET_CXY( chdev_dir.iob );
     331    ptr  = GET_PTR( chdev_dir.iob );
     332    base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
     333    nolock_printk("  - iob       : cxy = %X / ptr = %X / base = %X\n", cxy, ptr, base);
     334
     335    // PIC
     336    cxy  = GET_CXY( chdev_dir.pic );
     337    ptr  = GET_PTR( chdev_dir.pic );
     338    base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
     339    nolock_printk("  - pic       : cxy = %X / ptr = %X / base = %X\n", cxy, ptr, base);
     340
     341    // TXT
     342    for( i = 0 ; i < LOCAL_CLUSTER->nb_txt_channels ; i++ )
     343    {
     344        cxy = GET_CXY( chdev_dir.txt_rx[i] );
     345        ptr = GET_PTR( chdev_dir.txt_rx[i] );
     346        base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
     347        nolock_printk("  - txt_rx[%d] : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base);
     348
     349        cxy = GET_CXY( chdev_dir.txt_tx[i] );
     350        ptr = GET_PTR( chdev_dir.txt_tx[i] );
     351        base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
     352        nolock_printk("  - txt_tx[%d] : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base);
     353    }
     354
     355    // IOC
     356    for( i = 0 ; i < LOCAL_CLUSTER->nb_ioc_channels ; i++ )
     357    {
     358        cxy = GET_CXY( chdev_dir.ioc[i] );
     359        ptr = GET_PTR( chdev_dir.ioc[i] );
     360        base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
     361        nolock_printk("  - ioc[%d]    : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base);
     362    }
     363
     364    // FBF
     365    for( i = 0 ; i < LOCAL_CLUSTER->nb_fbf_channels ; i++ )
     366    {
     367        cxy  = GET_CXY( chdev_dir.fbf[i] );
     368        ptr  = GET_PTR( chdev_dir.fbf[i] );
     369        base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
     370        nolock_printk("  - fbf[%d]    : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base);
     371    }
     372
     373    // NIC
     374    for( i = 0 ; i < LOCAL_CLUSTER->nb_nic_channels ; i++ )
     375    {
     376        cxy = GET_CXY( chdev_dir.nic_rx[i] );
     377        ptr = GET_PTR( chdev_dir.nic_rx[i] );
     378        base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
     379        nolock_printk("  - nic_rx[%d] : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base);
     380
     381        cxy = GET_CXY( chdev_dir.nic_tx[i] );
     382        ptr = GET_PTR( chdev_dir.nic_tx[i] );
     383        base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
     384        nolock_printk("  - nic_tx[%d] : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base);
     385    }
     386
     387    // release lock
     388    remote_spinlock_unlock_busy( lock_xp , save_sr );
    355389
    356390}  // end chdev_dir_display()
  • trunk/kernel/kern/chdev.h

    r407 r428  
    2828#include <hal_types.h>
    2929#include <xlist.h>
    30 #include <metafs.h>
    3130#include <remote_spinlock.h>
    3231#include <dev_iob.h>
     
    3534#include <dev_pic.h>
    3635#include <dev_fbf.h>
     36#include <dev_txt.h>
    3737
    3838/******************************************************************************************
     
    115115 * One kernel thread, in charge of handling the commands registered in the waiting queue
    116116 * of client threads is associated to each chdev descriptor (not for ICU, PIC, IOB).
    117  * For each device type ***, the specific extensions are defined in the "dev_***.h" file.
     117 * For each device type ***, the specific extension is defined in the "dev_***.h" file.
    118118 *****************************************************************************************/
    119119
     
    136136    uint32_t             irq_id;      /*! associated IRQ index in local ICU              */
    137137
    138     metafs_t             node;        /*! Metafs node associated with this device        */
    139 
    140138        remote_spinlock_t    wait_lock;   /*! lock protecting exclusive access to queue      */
    141139    xlist_entry_t        wait_root;   /*! root of waiting threads queue                  */
     
    148146        pic_extend_t     pic;         /*! PIC specific extension                         */
    149147        fbf_extend_t     fbf;         /*! FBF specific extension                         */
     148        txt_extend_t     txt;         /*! TXT specific extension                         */
    150149    }
    151150    ext;
     
    239238
    240239/******************************************************************************************
     240 * This function returns an extended pointer on the chdev associated to a pseudo file
     241 * descriptor (type INODE_TYPE_DEV) identified by the <file_xp> argument.
     242 * It can be called by a thread running in any cluster.
     243 * It enters kernel panic if the inode has not the expected type.
     244 ******************************************************************************************
     245 * @ file_xp   : extended pointer on the pseudo file descriptor.
     246 * @ return an extended pointer on chdev.
     247 *****************************************************************************************/
     248xptr_t chdev_from_file( xptr_t file_xp );
     249
     250/******************************************************************************************
    241251 * This function displays the local copy of the external chdevs directory.
    242252 * (global variable replicated in all clusters)
     
    244254void chdev_dir_display();
    245255
    246 
    247 
    248256#endif  /* _CHDEV_H_ */
  • trunk/kernel/kern/cluster.c

    r416 r428  
    5555error_t cluster_init( struct boot_info_s * info )
    5656{
    57     error_t     error;
    58     lpid_t      lpid;     // local process_index
    59     lid_t       lid;      // local core index
     57    error_t         error;
     58    lpid_t          lpid;     // local process_index
     59    lid_t           lid;      // local core index
     60    uint32_t        i;        // index in loop on external peripherals
     61    boot_device_t * dev;      // pointer on external peripheral
     62    uint32_t        func;     // external peripheral functionnal type
    6063
    6164        cluster_t * cluster = LOCAL_CLUSTER;
     
    6972        cluster->io_cxy          = info->io_cxy;
    7073
     74    // initialize external peripherals channels
     75    for( i = 0 ; i < info->ext_dev_nr ; i++ )
     76    {
     77        dev  = &info->ext_dev[i];
     78        func = FUNC_FROM_TYPE( dev->type );   
     79        if( func == DEV_FUNC_TXT ) cluster->nb_txt_channels = dev->channels;
     80        if( func == DEV_FUNC_NIC ) cluster->nb_nic_channels = dev->channels;
     81        if( func == DEV_FUNC_IOC ) cluster->nb_ioc_channels = dev->channels;
     82        if( func == DEV_FUNC_FBF ) cluster->nb_fbf_channels = dev->channels;
     83    }
     84
    7185    // initialize cluster local parameters
    7286        cluster->cores_nr        = info->cores_nr;
     
    199213
    200214////////////////////////////////////////////////////////////////////////////////////
    201 //  Process management related functions
     215//  Process related functions
    202216////////////////////////////////////////////////////////////////////////////////////
    203217
     
    336350    remote_spinlock_lock_busy( XPTR( local_cxy , &pm->local_lock ) , & irq_state );
    337351
    338     xlist_add_first( XPTR( local_cxy , &pm->local_root ),
    339                      XPTR( local_cxy , &process->local_list ) );
     352    xlist_add_last( XPTR( local_cxy , &pm->local_root ),
     353                    XPTR( local_cxy , &process->local_list ) );
    340354    pm->local_nr++;
    341355
     
    417431}
    418432
    419 ////////////////////////////////////////////////////////////////////////////////////////
    420 // TODO Il me semble que la seule chose que fait ce kernel thread à chaque réveil
    421 // est de mettre à jour la DQDT, et de se rendormir... A-t-on besoin d'un thread ? [AG]
    422 //////////////////////////////////////////////////////////////////////////////////////////
    423 
    424 #if 0
    425 void * cluster_manager_thread( void * arg )
    426 {
    427         register struct dqdt_cluster_s * root;
    428         register struct cluster_s      * root_home;
    429 
    430         register uint32_t                tm_start;
    431         register uint32_t                tm_end;
    432         register uint32_t                cpu_id;
    433         struct cluster_s               * cluster;
    434         struct thread_s                * this;
    435         struct event_s                   event;
    436         struct alarm_info_s              info;
    437         register uint32_t                cntr;
    438         register bool_t                  isRootMgr;
    439         register uint32_t                period;
    440 
    441         cpu_enable_all_irq( NULL );
    442 
    443         cluster   = arg;
    444         this      = CURRENT_THREAD;
    445         cpu_id    = cpu_get_id();
    446         root      = dqdt_root;
    447         root_home = dqdt_root->home;
    448         isRootMgr = (cluster == root_home) ? true : false;
    449         cntr      = 0;
    450         period    = (isRootMgr) ?
    451                 CONFIG_DQDT_ROOTMGR_PERIOD * MSEC_PER_TICK :
    452                 CONFIG_DQDT_MGR_PERIOD * MSEC_PER_TICK;
    453 
    454         event_set_senderId(&event, this);
    455         event_set_priority(&event, E_CHR);
    456         event_set_handler(&event, &manager_alarm_event_handler);
    457 
    458         info.event = &event;
    459         thread_preempt_disable(CURRENT_THREAD);
    460 
    461     // infinite loop
    462         while(1)
    463         {
    464                 tm_start = cpu_time_stamp();
    465                 dqdt_update();
    466                 tm_end   = cpu_time_stamp();
    467 
    468                 if(isRootMgr)
    469                 {
    470                         if((cntr % 10) == 0)
    471                         {
    472                                 printk(INFO, "INFO: cpu %d, DQDT update ended [ %u - %u ]\n",
    473                                        cpu_id,
    474                                        tm_end,
    475                                        tm_end - tm_start);
    476 
    477                                 dqdt_print_summary(root);
    478                         }
    479                 }
    480 
    481                 alarm_wait( &info , period );
    482                 sched_sleep(this);
    483                 cntr ++;
    484         }
    485 
    486         return NULL;
    487 } // end cluster_manager_thread()
    488 
    489 //////////////////////////////////////////
    490 EVENT_HANDLER(manager_alarm_event_handler)
    491 {
    492         struct thread_s *manager;
    493 
    494         manager = event_get_senderId(event);
    495 
    496         thread_preempt_disable(CURRENT_THREAD);
    497 
    498         //printk(INFO, "%s: cpu %d [%u]\n", __FUNCTION__, cpu_get_id(), cpu_time_stamp());
    499 
    500         sched_wakeup(manager);
    501 
    502         thread_preempt_enable(CURRENT_THREAD);
    503 
    504         return 0;
    505 }
    506 
    507 ///////////////////////////////////////////////
    508 EVENT_HANDLER(cluster_key_create_event_handler)
    509 {
    510         struct cluster_s *cluster;
    511         struct thread_s *sender;
    512         ckey_t *ckey;
    513         uint32_t key;
    514 
    515         sender  = event_get_senderId(event);
    516         ckey    = event_get_argument(event);
    517         cluster = current_cluster;
    518         key     = cluster->next_key;
    519 
    520         while((key < CLUSTER_TOTAL_KEYS_NR) && (cluster->keys_tbl[key] != NULL))
    521                 key ++;
    522 
    523         if(key < CLUSTER_TOTAL_KEYS_NR)
    524         {
    525                 ckey->val = key;
    526                 cluster->keys_tbl[key] = (void *) 0x1; // Reserved
    527                 cluster->next_key = key;
    528                 event_set_error(event, 0);
    529         }
    530         else
    531                 event_set_error(event, ENOSPC);
    532 
    533         sched_wakeup(sender);
    534         return 0;
    535 }
    536 
    537 ///////////////////////////////////////////////
    538 EVENT_HANDLER(cluster_key_delete_event_handler)
    539 {
    540         struct cluster_s *cluster;
    541         struct thread_s *sender;
    542         ckey_t *ckey;
    543         uint32_t key;
    544 
    545         sender  = event_get_senderId(event);
    546         ckey    = event_get_argument(event);
    547         cluster = current_cluster;
    548         key     = ckey->val;
    549 
    550         if(key < cluster->next_key)
    551                 cluster->next_key = key;
    552 
    553         cluster->keys_tbl[key] = NULL;
    554         event_set_error(event, 0);
    555 
    556         sched_wakeup(sender);
    557         return 0;
    558 }
    559 
    560 #define _CKEY_CREATE  0x0
    561 #define _CKEY_DELETE  0x1
    562 
    563 error_t cluster_do_key_op(ckey_t *key, uint32_t op)
    564 {
    565         struct event_s event;
    566         struct thread_s *this;
    567         struct cluster_s *cluster;
    568         struct cpu_s *cpu;
    569 
    570         this = CURRENT_THREAD;
    571 
    572         event_set_priority(&event, E_FUNC);
    573         event_set_senderId(&event, this);
    574         event_set_argument(&event, key);
    575 
    576         if(op == _CKEY_CREATE)
    577                 event_set_handler(&event, cluster_key_create_event_handler);
    578         else
    579                 event_set_handler(&event, cluster_key_delete_event_handler);
    580 
    581         cluster = current_cluster;
    582         cpu     = cluster->bscluster->bscpu;
    583         event_send(&event, &cpu->re_listner);
    584 
    585         sched_sleep(this);
    586 
    587         return event_get_error(&event);
    588 }
    589 
    590 error_t cluster_key_create(ckey_t *key)
    591 {
    592         return cluster_do_key_op(key, _CKEY_CREATE);
    593 }
    594 
    595 error_t cluster_key_delete(ckey_t *key)
    596 {
    597         return cluster_do_key_op(key, _CKEY_DELETE);
    598 }
    599 
    600 void* cluster_getspecific(ckey_t *key)
    601 {
    602         struct cluster_s *cluster;
    603 
    604         cluster = current_cluster;
    605         return cluster->keys_tbl[key->val];
    606 }
    607 
    608 void  cluster_setspecific(ckey_t *key, void *val)
    609 {
    610         struct cluster_s *cluster;
    611 
    612         cluster = current_cluster;
    613         cluster->keys_tbl[key->val] = val;
    614 }
    615 #endif
     433///////////////////////////////////////////
     434void cluster_processes_display( cxy_t cxy )
     435{
     436    xptr_t        root_xp;
     437    xptr_t        iter_xp;
     438    xptr_t        process_xp;     
     439
     440    // get extended pointer on root of process in cluster cxy
     441    root_xp = XPTR( cxy , &LOCAL_CLUSTER->pmgr.local_root );
     442
     443    // skip one line
     444    printk("\n");
     445
     446    // loop on all reference processes in cluster cxy
     447    XLIST_FOREACH( root_xp , iter_xp )
     448    {
     449        process_xp = XLIST_ELEMENT( iter_xp , process_t , local_list );
     450        process_display( process_xp );
     451    }
     452}  // end cluster_processes_display()
     453
     454
  • trunk/kernel/kern/cluster.h

    r416 r428  
    9696typedef struct cluster_s
    9797{
    98         spinlock_t        kcm_lock;        /*! local, protect creation of KCM allocators      */
     98        spinlock_t        kcm_lock;          /*! local, protect creation of KCM allocators    */
    9999
    100100    // global parameters
    101         uint32_t          paddr_width;     /*! numer of bits in physical address              */
    102     uint32_t          x_width;         /*! number of bits to code x_size  (can be 0)      */
    103     uint32_t          y_width;         /*! number of bits to code y_size  (can be 0)      */
    104         uint32_t          x_size;          /*! number of clusters in a row    (can be 1)      */
    105         uint32_t          y_size;          /*! number of clusters in a column (can be 1)      */
    106         cxy_t             io_cxy;          /*! io cluster identifier                          */
    107     uint32_t          dqdt_root_level; /*! index of root node in dqdt_tbl[]               */
     101        uint32_t          paddr_width;       /*! numer of bits in physical address            */
     102    uint32_t          x_width;           /*! number of bits to code x_size  (can be 0)    */
     103    uint32_t          y_width;           /*! number of bits to code y_size  (can be 0)    */
     104        uint32_t          x_size;            /*! number of clusters in a row    (can be 1)    */
     105        uint32_t          y_size;            /*! number of clusters in a column (can be 1)    */
     106        cxy_t             io_cxy;            /*! io cluster identifier                        */
     107    uint32_t          dqdt_root_level;   /*! index of root node in dqdt_tbl[]             */
     108    uint32_t          nb_txt_channels;   /*! number of TXT channels                       */
     109    uint32_t          nb_nic_channels;   /*! number of NIC channels                       */
     110    uint32_t          nb_ioc_channels;   /*! number of IOC channels                       */
     111    uint32_t          nb_fbf_channels;   /*! number of FBF channels                       */
    108112
    109113    // local parameters
    110         uint32_t          cores_nr;        /*! actual number of cores in cluster              */
    111     uint32_t          ram_size;        /*! physical memory size                           */
    112     uint32_t          ram_base;        /*! physical memory base (local address)           */
     114        uint32_t          cores_nr;          /*! actual number of cores in cluster            */
     115    uint32_t          ram_size;          /*! physical memory size                         */
     116    uint32_t          ram_base;          /*! physical memory base (local address)         */
    113117
    114118        core_t            core_tbl[CONFIG_MAX_LOCAL_CORES];         /*! embedded cores        */
    115119
    116         list_entry_t      dev_root;        /*! root of list of devices in cluster             */
     120        list_entry_t      dev_root;          /*! root of list of devices in cluster           */
    117121
    118122    // memory allocators
    119         ppm_t             ppm;             /*! embedded kernel page manager                   */
    120         khm_t             khm;             /*! embedded kernel heap manager                   */
    121         kcm_t             kcm;             /*! embedded kernel cache manager (for KCMs)       */
     123        ppm_t             ppm;               /*! embedded kernel page manager                 */
     124        khm_t             khm;               /*! embedded kernel heap manager                 */
     125        kcm_t             kcm;               /*! embedded kernel cache manager (for KCMs)     */
     126
    122127    kcm_t           * kcm_tbl[KMEM_TYPES_NR];         /*! pointers on allocated KCMs      */
    123128
    124129    // RPC
    125         remote_fifo_t     rpc_fifo;        /*! RPC fifo (one per cluster)                     */
    126     uint32_t          rpc_threads;     /*! current number of RPC threads in cluster       */
     130        remote_fifo_t     rpc_fifo;          /*! RPC fifo (one per cluster)                   */
     131    uint32_t          rpc_threads;       /*! current number of RPC threads in cluster     */
    127132
    128133    // DQDT
    129     int32_t           pages_var;       /*! pages number increment from last DQQT update   */
    130     int32_t           threads_var;     /*! threads number increment from last DQDT update */
     134    int32_t           pages_var;         /*! pages number increment from last DQQT updt   */
     135    int32_t           threads_var;       /*! threads number increment from last DQDT updt */
    131136
    132137        dqdt_node_t       dqdt_tbl[CONFIG_DQDT_LEVELS_NR]; /*! embedded DQDT nodes in cluster */
     
    196201 * This function allocates a new PID in local cluster, that becomes the process owner.
    197202 * It registers the process descriptor extended pointer in the local processs manager
    198  * pref_tbl[] array. This function is called by the process_make_fork() function,
     203 * pref_tbl[] array. The process descriptor itself is not modified.
     204 * This function is called by the process_make_fork() function,
    199205 * by the process_make_exec() function, and by the process_init_create() function.
    200206 ******************************************************************************************
     
    255261void cluster_process_copies_unlink( struct process_s * process );
    256262
     263/*********************************************************************************************
     264 * This function displays on the kernel terminal TXT0 all user processes registered
     265 * in the cluster defined by the <cxy> argument.
     266 * It can be called by a thread running in any cluster, because is use remote accesses
     267 * to scan the xlist of registered processes.
     268 *********************************************************************************************
     269 * @ cxy   : cluster identifier.
     270 ********************************************************************************************/
     271void cluster_processes_display( cxy_t cxy );
     272
    257273
    258274
     
    262278
    263279/******************************************************************************************
    264  * This function increments the "cores_in_kernel" variable in cluster descriptor.
    265  *****************************************************************************************/
    266 void cluster_core_kernel_enter();
    267 
    268 /******************************************************************************************
    269  * This function decrements the "cores_in_kernel" variable in cluster descriptor.
    270  *****************************************************************************************/
    271 void cluster_core_kernel_exit();
    272 
    273 /******************************************************************************************
    274280 * This function returns the core local index that has the lowest usage in local cluster.
    275281 *****************************************************************************************/
  • trunk/kernel/kern/do_syscall.c

    r409 r428  
    3636static int sys_undefined()
    3737{
    38     panic("undefined system call");
     38    assert( false , __FUNCTION__ , "undefined system call" );
    3939    return 0;
    4040}
     
    9191    sys_exec,               // 37
    9292    sys_stat,               // 38
    93     sys_trace,              // 39
     93    sys_wait,               // 39
    9494
    9595    sys_get_config,         // 40
    9696    sys_get_core,           // 41
    9797    sys_get_cycle,          // 42
    98     sys_get_sched,          // 43
    99     sys_panic,              // 44
     98    sys_display,            // 43
     99    sys_undefined,          // 44
    100100    sys_thread_sleep,       // 45
    101101    sys_thread_wakeup,      // 46
     102    sys_trace,              // 47
     103    sys_fg,                 // 48
    102104};
    103105
     
    146148        else if( index == SYS_EXEC           ) return "EXEC";             // 37
    147149        else if( index == SYS_STAT           ) return "STAT";             // 38
    148         else if( index == SYS_TRACE          ) return "TRACE";            // 39
     150        else if( index == SYS_WAIT           ) return "WAIT";             // 39
    149151
    150152    else if( index == SYS_GET_CONFIG     ) return "GET_CONFIG";       // 40
    151153    else if( index == SYS_GET_CORE       ) return "GET_CORE";         // 41
    152154    else if( index == SYS_GET_CYCLE      ) return "GET_CYCLE";        // 42
    153     else if( index == SYS_GET_SCHED      ) return "GET_SCHED";        // 43
    154     else if( index == SYS_PANIC          ) return "PANIC";            // 44
    155         else if( index == SYS_SLEEP          ) return "SLEEP";            // 45
    156         else if( index == SYS_WAKEUP         ) return "WAKEUP";           // 46
     155    else if( index == SYS_DISPLAY        ) return "DISPLAY";          // 43
     156        else if( index == SYS_THREAD_SLEEP   ) return "THREAD_SLEEP";     // 45
     157        else if( index == SYS_THREAD_WAKEUP  ) return "THREAD_WAKEUP";    // 46
     158        else if( index == SYS_TRACE          ) return "TRACE";            // 47
     159        else if( index == SYS_FG             ) return "FG";               // 48
    157160
    158161    else                                   return "undefined";   
  • trunk/kernel/kern/kernel_init.c

    r409 r428  
    205205        if (func == DEV_FUNC_TXT )
    206206        {
    207             assert( (channels > 0) , __FUNCTION__ ,
    208                     "numner of TXT channels cannot be 0\n");
    209 
    210             // initializes TXT0 basic fields
     207            assert( (channels > 0) , __FUNCTION__ , "number of TXT channels cannot be 0\n");
     208
     209            // initializes TXT_TX[0] chdev
    211210            txt0_chdev.func    = func;
    212211            txt0_chdev.impl    = impl;
     
    366365        uint32_t        directions;      // number of directions (1 or 2)
    367366        uint32_t        rx;              // direction index (0 or 1)
    368     uint32_t        first_channel;   // used in loop on channels for TXT
    369367    chdev_t       * chdev;           // local pointer on one channel_device descriptor
    370368    uint32_t        ext_chdev_gid;   // global index of external chdev
     
    388386        if((func == DEV_FUNC_NIC) || (func == DEV_FUNC_TXT)) directions = 2;
    389387        else                                                 directions = 1;
    390 
    391         // The TXT0 chdev has already been created
    392         if (func == DEV_FUNC_TXT) first_channel = 1;
    393         else                      first_channel = 0;
    394388
    395389        // do nothing for ROM, that does not require a device descriptor.
     
    412406
    413407        // loops on channels
    414         for( channel = first_channel ; channel < channels ; channel++ )
     408        for( channel = 0 ; channel < channels ; channel++ )
    415409        {
    416410            // loop on directions
    417411            for( rx = 0 ; rx < directions ; rx++ )
    418412            {
     413                // skip TXT_TX[0] chdev that has already been created & registered
     414                if( (func == DEV_FUNC_TXT) && (channel == 0) && (rx == 0) ) continue;
     415
    419416                // compute target cluster for chdev[func,channel,direction]
    420417                uint32_t offset     = ext_chdev_gid % ( info->x_size * info->y_size );
     
    587584            else if((func == DEV_FUNC_NIC) && (is_rx != 0)) ptr = &iopic_input.nic_rx[channel];
    588585            else if( func == DEV_FUNC_IOB )                 ptr = &iopic_input.iob;
    589             else     panic( "illegal source device for IOPIC input" );
     586            else     assert( false , __FUNCTION__ , "illegal source device for IOPIC input" );
    590587
    591588            // set one entry in all "iopic_input" structures
     
    796793    if( error )
    797794    {
    798         panic("illegal core identifiers gid = %x / cxy = %x / lid = %d",
    799               core_lid , core_cxy , core_lid );
     795        assert( false , __FUNCTION__ ,
     796        "illegal core identifiers gid = %x / cxy = %x / lid = %d",
     797        core_lid , core_cxy , core_lid );
    800798    }
    801799
     
    807805        if( error )
    808806        {
    809             panic("cannot initialise cluster %x", local_cxy );
     807            assert( false , __FUNCTION__ ,
     808            "cannot initialise cluster %x", local_cxy );
    810809        }
    811810    }
     
    831830
    832831    // all CP0s initialize the process_zero descriptor
    833     if( core_lid == 0 ) process_zero_init( &process_zero );
     832    if( core_lid == 0 ) process_zero_create( &process_zero );
    834833
    835834    // CP0 in cluster 0 initializes the PIC chdev,
     
    900899    if( error )
    901900    {
    902         panic("core[%x][%d] cannot initialize idle thread",
    903               local_cxy , core_lid );
     901        assert( false , __FUNCTION__ ,
     902        "core[%x][%d] cannot initialize idle thread", local_cxy , core_lid );
    904903    }
    905904
     
    965964        else
    966965        {
    967             panic("root FS must be FATFS");
     966            assert( false , __FUNCTION__ ,
     967            "root FS must be FATFS" );
    968968        }
    969969
     
    11131113
    11141114    /////////////////////////////////////////////////////////////////////////////////
    1115     // STEP 8 : CP0 in I/O cluster creates the first user process (process_init)
    1116     /////////////////////////////////////////////////////////////////////////////////
    1117 
    1118     if( (core_lid ==  0) && (local_cxy == io_cxy) )
    1119     {
    1120         process_init_create();
     1115    // STEP 8 : CP0 in cluster 0 creates the first user process (process_init)
     1116    /////////////////////////////////////////////////////////////////////////////////
     1117
     1118    if( (core_lid ==  0) && (local_cxy == 0) )
     1119    {
     1120
     1121#if CONFIG_KINIT_DEBUG
     1122vfs_display( vfs_root_inode_xp );
     1123#endif
     1124
     1125       process_init_create();
    11211126    }
    11221127
     
    11271132    /////////////////////////////////////////////////////////////////////////////////
    11281133
    1129 #if CONFIG_KINIT_DEBUG
    1130 sched_display( core_lid );
    1131 #endif
    1132 
    11331134    if( (core_lid ==  0) && (local_cxy == 0) )
    11341135    kinit_dmsg("\n[DBG] %s : exit barrier 8 : process init created / cycle %d\n",
     
    11441145
    11451146#if CONFIG_KINIT_DEBUG
    1146 
    1147         vfs_display( vfs_root_inode_xp );
    11481147
    11491148        printk("\n\n***** memory fooprint for main kernel objects\n\n"
  • trunk/kernel/kern/printk.c

    r408 r428  
    383383}
    384384
    385 /////////////////////////////////
    386 void _panic( char * format , ... )
    387 {
    388     va_list       args;
    389     uint32_t      save_sr;
    390 
    391     // get pointers on TXT0 chdev
    392     xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
    393     cxy_t     txt0_cxy = GET_CXY( txt0_xp );
    394     chdev_t * txt0_ptr = GET_PTR( txt0_xp );
    395 
    396     // get extended pointer on remote TXT0 chdev lock
    397     xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
    398 
    399     // get TXT0 lock in busy waiting mode
    400     remote_spinlock_lock_busy( lock_xp , &save_sr );
    401 
    402     // call kernel_printf on TXT0, in busy waiting mode
    403     va_start( args , format );
    404     kernel_printf( format , &args );
    405     va_end( args );
    406 
    407     // release lock
    408     remote_spinlock_unlock_busy( lock_xp , save_sr );
    409 
    410     hal_disable_irq( NULL );
    411 
    412     while (1)
    413     {
    414         hal_core_sleep();
    415     }
    416 }
    417 
    418385////////////////////////////////////
    419386void assert( bool_t       condition,
  • trunk/kernel/kern/printk.h

    r415 r428  
    8383
    8484/**********************************************************************************
    85  * This function displays a message and forces the calling core in sleeping mode.
    86  **********************************************************************************
    87  * @ format        : formatted string
    88  *********************************************************************************/
    89 void _panic( char* format, ... );
    90 
    91 /**********************************************************************************
    9285 * This function displays a formated message on kernel TXT0 terminal,
    9386 * and forces the calling core in sleeping mode if a Boolean condition is false.
     
    126119void putl( uint64_t val );
    127120
    128 
    129 #define panic(fmt, ...)     _panic("\n[PANIC] %s(): " fmt "\n", __func__, ##__VA_ARGS__)
    130121
    131122///////////////////////////////////////////////////////////////////////////////////
  • 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     
  • trunk/kernel/kern/process.h

    r416 r428  
    5454
    5555/*********************************************************************************************
    56  * This enum defines the actions that can be executed by the process_signal() function.
     56 * This enum defines the actions that can be executed by the process_sigaction() function.
    5757 ********************************************************************************************/
    5858
     
    6262    UNBLOCK_ALL_THREADS  = 22,
    6363    DELETE_ALL_THREADS   = 33,
     64};
     65
     66/*********************************************************************************************
     67 * This enum defines the process states for ALMOS_MKH.
     68 ********************************************************************************************/
     69
     70enum process_states
     71{
     72    PROCESS_STATE_RUNNING = 0,           /*! process is executing                           */
     73    PROCESS_STATE_STOPPED = 1,           /*! process has been stopped by a signal           */
     74    PROCESS_STATE_KILLED  = 2,           /*! process has been killed by a signal            */
     75    PROCESS_STATE_EXITED  = 3,           /*! process terminated with an exit                */
    6476};
    6577
     
    102114 * 4) The <sem_root>, <mutex_root>, <barrier_root>, <condvar_root>, and the associated
    103115 *    <sync_lock>, that are dynamically allocated, are only defined in the reference cluster.
    104  * 5) The <children_root>, and <children_nr> fields are only defined in the reference
    105  *    cluster, and are undefined in other clusters.
    106  * 6) The <brothers_list>, <local_list>, <copies_list>, <th_tbl>, <th_nr>, <th_lock> fields
     116 * 5) The <children_root>, <children_nr>, <brothers_list>, and <txt_list> fields are only
     117 *    defined in the reference cluster, and are undefined in other clusters.
     118 * 6) The <local_list>, <copies_list>, <th_tbl>, <th_nr>, <th_lock> fields
    107119 *    are defined in all process descriptors copies.
    108120 ********************************************************************************************/
     
    115127
    116128        xptr_t            vfs_root_xp;      /*! extended pointer on current VFS root inode      */
    117         xptr_t            vfs_bin_xp;       /*! extended pointer on .elf file inode             */
     129        xptr_t            vfs_bin_xp;       /*! extended pointer on .elf file descriptor        */
    118130        pid_t             pid;              /*! process identifier                              */
    119         pid_t             ppid;             /*! parent process identifier                       */
    120131    xptr_t            ref_xp;           /*! extended pointer on reference process           */
     132    xptr_t            parent_xp;        /*! extended pointer on parent process              */
    121133
    122134        xptr_t            vfs_cwd_xp;       /*! extended pointer on current working dir inode   */
     
    124136
    125137        xlist_entry_t     children_root;    /*! root of the children process xlist              */
     138    remote_spinlock_t children_lock;    /*! lock protecting children process xlist          */
    126139    uint32_t          children_nr;      /*! number of children processes                    */
    127140
    128         xlist_entry_t     brothers_list;    /*! member of list of children of same parent       */
     141        xlist_entry_t     children_list;    /*! member of list of children of same parent       */
    129142    xlist_entry_t     local_list;       /*! member of list of process in same cluster       */
    130143    xlist_entry_t     copies_list;      /*! member of list of copies of same process        */
     144    xlist_entry_t     txt_list;         /*! member of list of processes sharing same TXT    */
    131145
    132146        spinlock_t        th_lock;          /*! lock protecting th_tbl[] concurrent access      */
    133147        uint32_t          th_nr;            /*! number of threads in this cluster               */
     148
    134149        struct thread_s * th_tbl[CONFIG_THREAD_MAX_PER_CLUSTER]; /*! pointers on local threads  */
    135150
     
    138153    xlist_entry_t     barrier_root;     /*! root of the process barrier list                */
    139154    xlist_entry_t     condvar_root;     /*! root of the process condvar list                */
    140 
    141155    remote_spinlock_t sync_lock;        /*! lock protecting sem,mutex,barrier,condvar lists */
     156
     157    uint32_t          state;            /*! RUNNING / STOPPED / KILLED / EXITED             */
     158
     159    bool_t            txt_owner;        /*! current TXT owner                               */
    142160}
    143161process_t;
     
    182200
    183201/*********************************************************************************************
     202 * This function initialize, in each cluster, the kernel "process_zero", that is the owner
     203 * of all kernel threads in a given cluster. It is called by the kernel_init() function.
     204 * The process_zero descriptor is allocated as a global variable in file kernel_init.c
     205 * Both the PID and PPID fields are set to zero, the ref_xp is the local process_zero,
     206 * and the parent process is set to XPTR_NULL. The th_tbl[] is initialized as empty.
     207 *********************************************************************************************
     208 * @ process      : [in] pointer on local process descriptor to initialize.
     209 ********************************************************************************************/
     210void process_zero_create( process_t * process );
     211
     212/*********************************************************************************************
    184213 * This function allocates memory and initializes the "process_init" descriptor and the
    185214 * associated "thread_init" descriptor. It is called once at the end of the kernel
    186  * initialisation procedure, by the kernel process in cluster_IO.
     215 * initialisation procedure. Its local process identifier is 1, and parent process
     216 * is the kernel process in cluster 0.
    187217 * The "process_init" is the first user process, and all other user processes will be forked
    188218 * from this process. The code executed by "process_init" is stored in a .elf file, whose
    189219 * pathname is defined by the CONFIG_PROCESS_INIT_PATH configuration variable.
    190  * The process_init streams are defined  by the CONFIG_INIT_[STDIN/STDOUT/STDERR] variables.
    191  * Its local process identifier is 1, and parent process is the local kernel process_zero.
     220 * The process_init does not use the [STDIN/STDOUT/STDERR] streams, but it is linked
     221 * to kernel TXT0, because these streams must be defined for all user processes.
    192222 ********************************************************************************************/
    193223void process_init_create();
    194224
    195225/*********************************************************************************************
    196  * This function initialize, in each cluster, the kernel "process_zero", that is the owner
    197  * of all kernel threads in a given cluster. It is called by the kernel_init() function.
    198  * Both the PID and PPID fields are set to zero, and the ref_xp is the local process_zero.
    199  * The th_tbl[] is initialized as empty.
    200  *********************************************************************************************
    201  * @ process      : [in] pointer on local process descriptor to initialize.
    202  ********************************************************************************************/
    203 void process_zero_init( process_t * process );
    204 
    205 /*********************************************************************************************
    206  * This function initializes a local, reference user process descriptor from another process
    207  * descriptor, defined by the <model_xp> argument. The <process> descriptor, the <pid>, and
    208  * the <ppid> arguments must be previously defined by the caller.
    209  * It can be called by two functions, depending on the process type:
    210  * 1) if "process" is the "process_init", the parent is the kernel process. It is
    211  *    called once, by the process_init_create() function in cluster[xmax-1][ymax-1].
    212  * 2) if the caller is the process_make_fork() function, the model is generally a remote
    213  *    process, that is also the parent process.
    214 
    215  * 3) if the caller is the process_make_exec() function, the model is always a local process,
    216  *    and the parent is the parent of the model process. DEPRECATED [AG]
    217 
    218  * The following fields are initialised (for all process but process_zero).
    219  * - It set the pid / ppid / ref_xp fields.
     226 * This function initializes a local, reference, user process descriptor from another process
     227 * descriptor, defined by the <model_xp> argument. The <process> and <pid> arguments must
     228 * be previously allocated by he caller. This function can be called by three functions:
     229 * 1) process_init_create() : process is the reference INIT process / pid = 1 /
     230 *    the parent and model process descriptors are both the kernel process_zero.
     231 * 2) process_make_fork() : the model process descriptor is the (generally remote)
     232 *    parent process.
     233 * 3) process_make exec() : the model process is the local old_process, the new_process
     234 *    parent is the same as the old_process parent.
     235 * The following fields are initialised :
     236 * - It set the pid / ppid / ref_xp / parent_xp / state fields.
    220237 * - It initializes the VMM (register the kentry, args, envs vsegs in VSL)
    221238 * - It initializes the FDT, defining the three pseudo files STDIN / STDOUT / STDERR.
     
    230247 * @ process      : [in] pointer on local process descriptor to initialize.
    231248 * @ pid          : [in] process identifier.
    232  * @ ppid         : [in] parent process identifier.
    233  * @ model_xp     : [in] extended pointer on model process descriptor (local or remote).
     249 * @ parent_xp    : [in] extended pointer on parent process descriptor.
     250 * @ model_xp     : [in] extended pointer on model process descriptor.
    234251 ********************************************************************************************/
    235252void process_reference_init( process_t * process,
    236253                             pid_t       pid,
    237                              pid_t       ppid,
     254                             xptr_t      parent_xp,
    238255                             xptr_t      model_xp );
    239256
     
    259276
    260277/*********************************************************************************************
    261  * This function returns a printable string defining the action for process_signa().
    262  *********************************************************************************************
    263  * @ action_type   : BLOCK_ALL_THREADS / UNBLOCK_ALL_THREADS / DELETE_ALL_THREADS
     278 * This function returns a printable string defining the process state.
     279 *********************************************************************************************
     280 * @ state   : RUNNING / BLOCKED / EXITED / KILLED
    264281 * @ return a string pointer.
    265282 ********************************************************************************************/
    266 char * process_action_str( uint32_t action_type );
     283char * process_state_str( uint32_t state );
     284
     285/*********************************************************************************************
     286 * This debug function diplays on the kernel terminal TXT0 detailed informations on a
     287 * reference process identified by the <process_xp> argument.
     288 * It can be called by a thread running in any cluster.
     289 *********************************************************************************************
     290 * @ process_xp : extended pointer on reference process.
     291 ********************************************************************************************/
     292void process_display( xptr_t process_xp );
     293
     294/*********************************************************************************************
     295 * This function returns a printable string defining the sigaction type.
     296 *********************************************************************************************
     297 * @ sigaction_type   : BLOCK_ALL_THREADS / UNBLOCK_ALL_THREADS / DELETE_ALL_THREADS
     298 * @ return a string pointer.
     299 ********************************************************************************************/
     300char * process_action_str( uint32_t sigaction_type );
    267301
    268302/*********************************************************************************************
     
    290324
    291325/*********************************************************************************************
    292  * This function blocks all threads of a given user process in a given cluster.
     326 * This function blocks all threads (but the client thread defined by the <client_xp>
     327 * argument) for a given <process> in a given cluster.
    293328 * It loops on all local threads of the process, set the THREAD_BLOCKED_GLOBAL bit,
    294329 * and request the relevant schedulers to acknowledge the blocking, using IPI if required.
    295330 * The threads are not detached from the scheduler, and not detached from the local process.
    296331 * This function returns only when all blockable threads in cluster are actually blocked.
    297  * WARNING : the client thread defined by the <client_xp> argument is NOT blocked.
    298332 *********************************************************************************************
    299333 * @ process     : pointer on the target process descriptor.
    300334 * @ client_xp   : extended pointer on the client thread, that should not be blocked.
    301335 ********************************************************************************************/
    302 void process_block( process_t * process,
    303                     xptr_t      client_xp );
     336void process_block_threads( process_t * process,
     337                            xptr_t      client_xp );
    304338
    305339/*********************************************************************************************
     
    308342 * @ process     : pointer on the process descriptor.
    309343 ********************************************************************************************/
    310 void process_unblock( process_t * process );
    311 
    312 /*********************************************************************************************
    313  * This function delete all threads, of a given user process in a given cluster.
     344void process_unblock_threads( process_t * process );
     345
     346/*********************************************************************************************
     347 * This function delete all threads, (but the client thread defined by the <client_xp>
     348 * argument) for a given <process> in a given cluster.
    314349 * It loops on all local threads of the process, and set the THREAD_FLAG_REQ_DELETE bit.
    315350 * For each marked thread, the following actions will be done by the scheduler at the next
     
    320355 * - the memory allocated to the thread descriptor is released.
    321356 * - the memory allocated to the process descriptor is released, if it is the last thread.
    322  * WARNING : the client thread defined by the <client_xp> argument is NOT deleted.
    323357 *********************************************************************************************
    324358 * @ process     : pointer on the process descriptor.
    325359 * @ client_xp   : extended pointer on the client thread, that should not be deleted.
    326360 ********************************************************************************************/
    327 void process_delete( process_t * process,
    328                      xptr_t      client_xp );
     361void process_delete_threads( process_t * process,
     362                             xptr_t      client_xp );
    329363
    330364/*********************************************************************************************
     
    509543
    510544
     545/***************   Terminals related operations  ********************************************/
     546
     547/*********************************************************************************************
     548 * This function scan the set of user TXT terminals to find a free terminal
     549 * (the list of attached processes is empty for a free TXT terminal).
     550 * It is called only by the process_reference_init() function when creating a KSH process.
     551 * It makes a kernel panic if no free TXT terminal is found.
     552 * As a KSH process is never deleted, the allocated TXT terminal is never released.
     553 *********************************************************************************************
     554 * @ return TXT terminal index if succes / kernel panic if no terminal found.
     555 ********************************************************************************************/
     556uint32_t process_txt_alloc();
     557
     558/*********************************************************************************************
     559 * This function attach a reference process descriptor, identified by the <process>
     560 * argument to a TXT terminal, identified by its <txt_id> channel index argument.
     561 * It insert the process descriptor in the xlist rooted in the TXT_RX device.
     562 * It is called by the process_reference_init() function.
     563 *********************************************************************************************
     564 * @ process  : local pointer on process descriptor.
     565 * @ txt_id   : TXT channel index.
     566 ********************************************************************************************/
     567void process_txt_attach( process_t * process,
     568                         uint32_t    txt_id );
     569
     570/*********************************************************************************************
     571 * This function detach a reference process descriptor, identified by the <process_xp>
     572 * argument, from the list of process attached to a given TXT terminal.
     573 * It is called when the process is killed.
     574 *********************************************************************************************
     575 * @ process  : local pointer on process descriptor.
     576 ********************************************************************************************/
     577void process_txt_detach( process_t * process );                     
     578
     579/*********************************************************************************************
     580 * This function gives to a process identified by the <process_xp> argument, and attached
     581 * to terminal TXT[i] the exclusive ownership of the TXT_RX[i] terminal.
     582 *********************************************************************************************
     583 * @ process_xp  : extended pointer on reference process descriptor.
     584 ********************************************************************************************/
     585void process_txt_set_ownership( xptr_t process_xp );
     586
     587/*********************************************************************************************
     588 * When the process identified by the <process_xp> argument has the exclusive ownership
     589 * of the TXT_RX[i] terminal, this function gives this ownership to the KSH[i] process.
     590 * It does nothing if the process is not the owner.
     591 *********************************************************************************************
     592 * @ process_xp  : extended pointer on reference process descriptor.
     593 ********************************************************************************************/
     594void process_txt_reset_ownership( xptr_t process_xp );
    511595
    512596#endif  /* _PROCESS_H_ */
  • trunk/kernel/kern/rpc.c

    r416 r428  
    7979    &rpc_sched_display_server,          // 27
    8080    &rpc_vmm_set_cow_server,            // 28
    81     &rpc_undefined,                     // 29
     81    &rpc_vmm_display_server,            // 29
    8282};
    8383
     
    8585void __attribute__((noinline)) rpc_undefined()
    8686{
    87         panic("called in cluster %x", local_cxy );
     87        assert( false , __FUNCTION__ , "called in cluster %x", local_cxy );
    8888}
    8989
     
    10361036
    10371037    // call relevant kernel function
    1038     if      (action == DELETE_ALL_THREADS  ) process_delete ( process , client_xp );
    1039     else if (action == BLOCK_ALL_THREADS   ) process_block  ( process , client_xp );
    1040     else if (action == UNBLOCK_ALL_THREADS ) process_unblock( process             );
     1038    if      (action == DELETE_ALL_THREADS  ) process_delete_threads ( process , client_xp );
     1039    else if (action == BLOCK_ALL_THREADS   ) process_block_threads  ( process , client_xp );
     1040    else if (action == UNBLOCK_ALL_THREADS ) process_unblock_threads( process             );
    10411041
    10421042    // decrement the responses counter in RPC descriptor,
     
    22662266
    22672267    // get input arguments from client RPC descriptor
    2268     lid_t lid = (lid_t)hal_remote_lw( XPTR(cxy , &desc->args[0]));
     2268    lid_t lid = (lid_t)hal_remote_lwd( XPTR(cxy , &desc->args[0]));
    22692269   
    22702270    // call local kernel function
     
    23212321
    23222322    // get input arguments from client RPC descriptor
    2323     process = (process_t *)(intptr_t)hal_remote_lpt( XPTR(cxy , &desc->args[0]));
     2323    process = (process_t *)(intptr_t)hal_remote_lwd( XPTR(cxy , &desc->args[0]));
    23242324   
    23252325    // call local kernel function
     
    23312331}
    23322332
    2333 
     2333/////////////////////////////////////////////////////////////////////////////////////////
     2334// [29]          Marshaling functions attached to RPC_VMM_DISPLAY (blocking)
     2335/////////////////////////////////////////////////////////////////////////////////////////
     2336
     2337/////////////////////////////////////////////
     2338void rpc_vmm_display_client( cxy_t       cxy,
     2339                             process_t * process,
     2340                             bool_t      detailed )
     2341{
     2342    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     2343    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     2344    CURRENT_THREAD->core->lid , hal_time_stamp() );
     2345
     2346    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
     2347
     2348    // initialise RPC descriptor header
     2349    rpc_desc_t  rpc;
     2350    rpc.index    = RPC_VMM_DISPLAY;
     2351    rpc.response = 1;
     2352    rpc.blocking = true;
     2353
     2354    // set input arguments in RPC descriptor
     2355    rpc.args[0] = (uint64_t)(intptr_t)process;
     2356    rpc.args[1] = (uint64_t)detailed;
     2357
     2358    // register RPC request in remote RPC fifo (blocking function)
     2359    rpc_send( cxy , &rpc );
     2360
     2361    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     2362    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     2363    CURRENT_THREAD->core->lid , hal_time_stamp() );
     2364}
     2365
     2366////////////////////////////////////////
     2367void rpc_vmm_display_server( xptr_t xp )
     2368{
     2369    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     2370    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     2371    CURRENT_THREAD->core->lid , hal_time_stamp() );
     2372
     2373    process_t * process;
     2374    bool_t      detailed;
     2375
     2376    // get client cluster identifier and pointer on RPC descriptor
     2377    cxy_t        cxy  = (cxy_t)GET_CXY( xp );
     2378    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
     2379
     2380    // get input arguments from client RPC descriptor
     2381    process  = (process_t *)(intptr_t)hal_remote_lwd( XPTR(cxy , &desc->args[0]));
     2382    detailed = (bool_t)               hal_remote_lwd( XPTR(cxy , &desc->args[1]));
     2383   
     2384    // call local kernel function
     2385    vmm_display( process , detailed );
     2386
     2387    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     2388    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     2389    CURRENT_THREAD->core->lid , hal_time_stamp() );
     2390}
     2391
     2392
  • trunk/kernel/kern/rpc.h

    r416 r428  
    9090    RPC_SCHED_DISPLAY          = 27,
    9191    RPC_VMM_SET_COW            = 28,
     92    RPC_VMM_DISPLAY            = 29,
    9293
    9394    RPC_MAX_INDEX              = 30,
     
    698699void rpc_vmm_set_cow_server( xptr_t xp );
    699700
     701/***********************************************************************************
     702 * [29] The RPC_VMM_DISPLAY allows any client thread to display the VMM state
     703 * of a remote reference process identified by the <cxy> and <process> arguments.
     704 * The type of display is defined by the <detailed> boolean argument.
     705 ***********************************************************************************
     706 * @ cxy         : server cluster identifier.
     707 * @ process     : [in]  local pointer on reference process descriptor.
     708 * @ detailed    : [in]  detailed display if true.
     709 **********************************************************************************/
     710void rpc_vmm_display_client( cxy_t              cxy,
     711                             struct process_s * process,
     712                             bool_t             detailed );
     713
     714void rpc_vmm_display_server( xptr_t xp );
     715
     716
    700717#endif
  • trunk/kernel/kern/scheduler.c

    r416 r428  
    8686
    8787    // release lock
     88    hal_fence();
    8889    spinlock_unlock( &sched->lock );
    8990
     
    181182    list_entry_t * iter;
    182183    thread_t     * thread;
    183 
    184 // printk("\n@@@ %s : current thread %x enter at cycle %d\n",
    185 // __FUNCTION__ , CURRENT_THREAD , hal_time_stamp() );
     184    process_t    * process;
    186185
    187186    scheduler_t  * sched = &core->scheduler;
     
    212211        if( thread->flags & THREAD_FLAG_REQ_DELETE )
    213212        {
    214 
    215 sched_dmsg("\n[DBG] %s : current thread %x delete thread %x at cycle %d\n",
    216 __FUNCTION__ , CURRENT_THREAD , thread , hal_time_stamp() );
     213            // get thread process descriptor
     214            process = thread->process;
    217215
    218216                // release FPU if required
     
    223221            thread_child_parent_unlink( thread->parent , XPTR( local_cxy , thread ) );
    224222
    225             // detach thread from process
    226             process_remove_thread( thread );
    227 
    228             // remove thread from scheduler
     223            // remove thread from scheduler (scheduler lock already taken)
     224            uint32_t threads_nr = sched->u_threads_nr;
     225            assert( (threads_nr != 0) , __FUNCTION__ , "u_threads_nr cannot be 0\n" );
     226            sched->u_threads_nr = threads_nr - 1;
    229227            list_unlink( &thread->sched_list );
    230             sched->u_threads_nr--;
    231             if( sched->u_threads_nr == 0 ) sched->u_last = NULL;
    232 
    233             // release memory allocated to thread
     228            if( threads_nr == 1 ) sched->u_last = NULL;
     229
     230            // delete thread
    234231            thread_destroy( thread );
    235232
     233sched_dmsg("\n[DBG] %s : thread %x deleted thread %x / cycle %d\n",
     234__FUNCTION__ , CURRENT_THREAD , thread , (uint32_t)hal_get_cycles() );
     235
    236236            // destroy process descriptor if no more threads
    237             if (thread->process->th_nr == 0) process_destroy( thread->process );
     237            if( process->th_nr == 0 )
     238            {
     239                // delete process   
     240                process_destroy( process );
     241
     242sched_dmsg("\n[DBG] %s : thread %x deleted process %x / cycle %d\n",
     243__FUNCTION__ , CURRENT_THREAD , process , (uint32_t)hal_get_cycles() );
     244
     245            }
    238246        }
    239247    }
    240248
    241249    // release lock
     250    hal_fence();
    242251    spinlock_unlock( &sched->lock );
    243 
    244 // printk("\n@@@ %s : current thread %x exit at cycle %d\n",
    245 // __FUNCTION__ , CURRENT_THREAD , hal_time_stamp() );
    246252
    247253} // end sched_handle_requests()
     
    277283
    278284    // check next thread not blocked when type != IDLE
    279     assert( (next->blocked == 0) || (next->type = THREAD_IDLE) , __FUNCTION__ ,
     285    assert( ((next->blocked == 0) || (next->type == THREAD_IDLE)) , __FUNCTION__ ,
    280286    "next thread %x (%s) is blocked on core[%x,%d]\n",
    281287    next->trdid , thread_type_str(next->type) , local_cxy , core->lid );
     
    310316    {
    311317
    312 sched_dmsg("\n[DBG] %s : core[%x,%d] / cause = %s\n"
     318#if( CONFIG_SCHED_DEBUG & 0x1 )
     319if( hal_time_stamp() > CONFIG_SCHED_DEBUG )
     320printk("\n[DBG] %s : core[%x,%d] / cause = %s\n"
    313321"      thread %x (%s) (%x,%x) continue / cycle %d\n",
    314322__FUNCTION__, local_cxy, core->lid, cause,
    315323current, thread_type_str(current->type), current->process->pid, current->trdid,
    316324(uint32_t)hal_get_cycles() );
     325#endif
    317326
    318327    }
     
    355364    remote_spinlock_lock_busy( lock_xp , &save_sr );
    356365
    357     nolock_printk("\n***** scheduler state for core[%x,%d] at cycle %d\n"
    358            "kernel_threads = %d / user_threads = %d / current = (%x,%x)\n",
    359             local_cxy , core->lid, hal_time_stamp(),
    360             sched->k_threads_nr, sched->u_threads_nr,
     366    nolock_printk("\n***** scheduler state for core[%x,%d] / cycle %d / current = (%x,%x)\n",
     367            local_cxy , core->lid, (uint32_t)hal_get_cycles(),
    361368            sched->current->process->pid , sched->current->trdid );
    362369
  • trunk/kernel/kern/scheduler.h

    r416 r428  
    5959
    6060/*********************************************************************************************
    61  * This function register a new thread in a given core scheduler.
     61 * This function atomically register a new thread in a given core scheduler.
    6262 *********************************************************************************************
    6363 * @ core    : local pointer on the core descriptor.
  • trunk/kernel/kern/thread.c

    r418 r428  
    141141
    142142    // register new thread in process descriptor, and get a TRDID
    143     spinlock_lock( &process->th_lock );
    144143    error = process_register_thread( process, thread , &trdid );
    145     spinlock_unlock( &process->th_lock );
    146144
    147145    if( error )
     
    228226
    229227    assert( (attr != NULL) , __FUNCTION__, "pthread attributes must be defined" );
     228
     229thread_dmsg("\n[DBG] %s : core[%x,%d] enter for process %x\n",
     230__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, process->pid );
    230231
    231232    // get process descriptor local copy
     
    290291                         vseg->min,
    291292                         vseg->max - vseg->min );
    292 
    293293    if( error )
    294294    {
     
    326326    dqdt_local_update_threads( 1 );
    327327
    328 thread_dmsg("\n[DBG] %s : core[%x,%d] exit / trdid = %x / process %x / core = %d\n",
    329 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid,
    330 thread->trdid , process->pid , core_lid );
     328thread_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x / trdid = %x / core = %d\n",
     329__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, process->pid, thread->trdid, core_lid );
    331330
    332331    *new_thread = thread;
     
    371370
    372371    // get relevant fields from parent thread
    373     func  = (void *)  hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->entry_func   ) );
    374     args  = (void *)  hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->entry_args   ) );
    375     base  = (intptr_t)hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->u_stack_base ) );
    376     size  = (uint32_t)hal_remote_lw ( XPTR( parent_cxy , &parent_ptr->u_stack_size ) );
    377     flags =           hal_remote_lw ( XPTR( parent_cxy , &parent_ptr->flags        ) );
    378     uzone = (reg_t *) hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->uzone        ) );
     372    func  = (void *)  hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->entry_func    ));
     373    args  = (void *)  hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->entry_args    ));
     374    base  = (intptr_t)hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->u_stack_base  ));
     375    size  = (uint32_t)hal_remote_lw ( XPTR( parent_cxy , &parent_ptr->u_stack_size  ));
     376    flags =           hal_remote_lw ( XPTR( parent_cxy , &parent_ptr->flags         ));
     377    uzone = (reg_t *) hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->uzone_current ));
    379378
    380379    vpn_base = base >> CONFIG_PPM_PAGE_SHIFT;
     
    419418
    420419    // update uzone pointer in child thread descriptor
    421     child_ptr->uzone = (char *)((intptr_t)uzone +
    422                                 (intptr_t)child_ptr -
    423                                 (intptr_t)parent_ptr );
     420    child_ptr->uzone_current = (char *)((intptr_t)uzone +
     421                                        (intptr_t)child_ptr -
     422                                        (intptr_t)parent_ptr );
    424423 
    425424
     
    515514        thread_t     * thread;       // pointer on new thread descriptor
    516515
    517 thread_dmsg("\n[DBG] %s : core[%x,%d] enters / type % / cycle %d\n",
     516thread_dmsg("\n[DBG] %s : core[%x,%d] enters / type %s / cycle %d\n",
    518517__FUNCTION__ , local_cxy , core_lid , thread_type_str( type ) , hal_time_stamp() );
    519518
     
    615614        if ( thread->type == THREAD_USER ) hal_fpu_context_destroy( thread );
    616615       
    617     // release FPU if required
    618     // TODO This should be done before calling thread_destroy()
     616    // release FPU ownership if required
    619617        hal_disable_irq( &save_sr );
    620618        if( core->fpu_owner == thread )
     
    626624
    627625    // remove thread from process th_tbl[]
    628     // TODO This should be done before calling thread_destroy()
    629     ltid_t ltid = LTID_FROM_TRDID( thread->trdid );
    630 
    631         spinlock_lock( &process->th_lock );
    632         process->th_tbl[ltid] = XPTR_NULL;
    633         process->th_nr--;
    634         spinlock_unlock( &process->th_lock );
     626    process_remove_thread( thread );
    635627       
    636628    // update local DQDT
     
    814806
    815807thread_dmsg("\n[DBG] %s : killer thread %x enter for target thread %x\n",
    816 __FUNCTION__, local_cxy, killer->trdid , target trdid );
     808__FUNCTION__, local_cxy, killer->trdid , target->trdid );
    817809
    818810    // set the global blocked bit in target thread descriptor.
     
    844836
    845837thread_dmsg("\n[DBG] %s : killer thread %x exit for target thread %x\n",
    846 __FUNCTION__, local_cxy, killer->trdid , target trdid );
     838__FUNCTION__, local_cxy, killer->trdid , target->trdid );
    847839
    848840}  // end thread_kill()
  • trunk/kernel/kern/thread.h

    r418 r428  
    7373#define THREAD_FLAG_SCHED        0x0004  /*! Scheduling required for this thread      */
    7474#define THREAD_FLAG_REQ_ACK      0x0008  /*! Acknowledge required from scheduler      */
    75 #define THREAD_FLAG_REQ_DELETE   0x0010  /*! Destruction required by scheduler        */
     75#define THREAD_FLAG_REQ_DELETE   0x0010  /*! Destruction required from scheduler      */
    7676
    7777/***************************************************************************************
     
    8989#define THREAD_BLOCKED_RPC       0x0200  /*! thread wait RPC completion               */
    9090#define THREAD_BLOCKED_DEV_ISR   0x0400  /*! thread DEV wait ISR                      */
     91#define THREAD_BLOCKED_WAIT      0x0800  /*! thread parent wait child termination     */
    9192
    9293/***************************************************************************************
     
    123124 * thread is registered in the local copy of the process descriptor.
    124125 *
    125  * WARNING : Don't modify the first 3 fields order, as this order is used by the
     126 * WARNING : Don't modify the first 4 fields order, as this order is used by the
    126127 * hal_kentry assembly code for the TSAR architecture.
    127128 **************************************************************************************/
     
    133134        void              * cpu_context;     /*! pointer on CPU context switch            */
    134135        void              * fpu_context;     /*! pointer on FPU context switch            */
    135     void              * uzone;           /*! used by hal_do_syscakl & hal_do_except   */
     136    void              * uzone_current;   /*! used by hal_do_syscall & hal_do_except   */
     137    void              * uzone_previous;  /*! used by hal_do_syscall & hal_do_except   */
    136138
    137139        intptr_t            k_stack_base;    /*! kernel stack base address                */
     
    150152        uint32_t            remote_locks;        /*! number of remote locks owned by thread   */
    151153
    152     remote_spinlock_t * join_lock;       /*! lock protecting the join/exit            */
     154    remote_spinlock_t   join_lock;       /*! lock protecting the join/exit            */
    153155    void              * join_value;      /*! exit_value used in case of join          */
    154156    xptr_t              join_xp;         /*! extended pointer on joining thread       */
     
    193195    xlist_entry_t       wait_list;       /*! member of threads blocked on same cond   */
    194196
    195 #if CONFIG_LOCKS_DEBUG
    196197    list_entry_t        locks_root;      /*! root of list of locks taken              */
    197198    xlist_entry_t       xlocks_root;     /*! root of xlist of remote locks taken      */
    198 #endif
    199199
    200200        thread_info_t       info;            /*! embedded thread_info_t                   */
Note: See TracChangeset for help on using the changeset viewer.