Ignore:
Timestamp:
Mar 7, 2018, 9:02:03 AM (6 years ago)
Author:
alain
Message:

1) improve the threads and process destruction mechanism.
2) introduce FIFOs in the soclib_tty driver.

File:
1 edited

Legend:

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

    r435 r436  
    365365    cxy_t       parent_cxy;
    366366    xptr_t      children_lock_xp;
    367     xptr_t      copies_lock_xp;
    368367
    369368        assert( (process->th_nr == 0) , __FUNCTION__ ,
     
    377376#endif
    378377
    379     // get local process manager pointer
    380     pmgr_t * pmgr = &LOCAL_CLUSTER->pmgr;
    381 
    382     // remove process from local_list in cluster manager
    383     remote_spinlock_lock( XPTR( local_cxy , &pmgr->local_lock ) );
    384     xlist_unlink( XPTR( local_cxy , &process->local_list ) );
    385     remote_spinlock_unlock( XPTR( local_cxy , &pmgr->local_lock ) );
    386 
    387     // get extended pointer on copies_lock in owner cluster manager
    388     cxy_t  owner_cxy = CXY_FROM_PID( process->pid );
    389         lpid_t lpid      = LPID_FROM_PID( process->pid );
    390     copies_lock_xp   = XPTR( owner_cxy , &pmgr->copies_lock[lpid] );
    391 
    392     // remove local process from copies_list
    393     remote_spinlock_lock( copies_lock_xp );
    394     xlist_unlink( XPTR( local_cxy , &process->copies_list ) );
    395     remote_spinlock_unlock( copies_lock_xp );
    396 
    397     // for reference process only
    398     if( XPTR( local_cxy , process ) == process->ref_xp )
    399     {
    400         // remove reference process from txt_list
    401         process_txt_detach( process );
    402 
     378    // remove process from local_list in local cluster manager
     379    cluster_process_local_unlink( process );
     380
     381    // remove process from copies_list in owner cluster manager
     382    cluster_process_copies_unlink( process );
     383
     384    // remove process from children_list if process is in owner cluster
     385    if( CXY_FROM_PID( process->pid ) == local_cxy )
     386    {
    403387        // get pointers on parent process
    404388        parent_xp  = process->parent_xp;
     
    461445    xptr_t             process_xp;        // extended pointer on process copy
    462446    cxy_t              process_cxy;       // process copy cluster identifier
    463     process_t        * process_ptr;       // local pointer on process copy
    464     uint32_t           responses;         // number of remote process copies
    465     uint32_t           rsp_count;         // used to assert number of copies
    466     rpc_desc_t         rpc;               // rpc descriptor allocated in stack
     447    reg_t              save_sr;           // for critical section
     448    rpc_desc_t         rpc;               // shared RPC descriptor
    467449
    468450    thread_t * client = CURRENT_THREAD;
     
    475457#endif
    476458
    477     // get local pointer on local cluster manager
     459    // get pointer on local cluster manager
    478460    cluster = LOCAL_CLUSTER;
    479461
     
    483465
    484466    // get root of list of copies, lock, and number of copies from owner cluster
    485     responses = hal_remote_lw ( XPTR( owner_cxy , &cluster->pmgr.copies_nr[lpid] ) );
    486     root_xp   = hal_remote_lwd( XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] ) );
    487     lock_xp   = hal_remote_lwd( XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] ) );
    488 
    489     rsp_count = 0;
     467    root_xp   = XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] );
     468    lock_xp   = XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] );
    490469
    491470    // check action type
     
    494473             (action_type == UNBLOCK_ALL_THREADS )), __FUNCTION__ , "illegal action type" );
    495474             
    496     // initialise rpc descriptor
    497     rpc.index    = RPC_PROCESS_SIGACTION;
    498     rpc.response = responses;
    499     rpc.blocking = false;
    500     rpc.thread   = client;
     475    // allocate a - shared - RPC descriptor in client thread stack
     476    // it can be shared because all parallel, non-blocking, server threads
     477    // use the same input arguments, and use the shared RPC response field
     478    // but use
     479
     480    // the client thread makes the following sequence:
     481    // 1. mask interrupts
     482    // 2. block itself
     483    // 3. send RPC requests to all copies
     484    // 4. unmask interrupts
     485    // 5. deschedule
     486
     487    // mask IRQs
     488    hal_disable_irq( &save_sr);
     489
     490    // client register blocking condition for itself
     491    thread_block( XPTR( local_cxy , client ) , THREAD_BLOCKED_RPC );
    501492
    502493    // take the lock protecting the copies
    503494    remote_spinlock_lock( lock_xp );
    504495
    505     // send RPCs to remote clusters
     496    // initialize shared RPC descriptor
     497    rpc.response = 0;
     498    rpc.blocking = false;
     499    rpc.index    = RPC_PROCESS_SIGACTION;
     500    rpc.thread   = client;
     501    rpc.lid      = client->core->lid;
     502    rpc.args[0]  = action_type;
     503    rpc.args[1]  = pid;
     504
     505    // send RPCs to all clusters containing process copiess
    506506    XLIST_FOREACH( root_xp , iter_xp )
    507507    {
     508
     509#if CONFIG_DEBUG_PROCESS_SIGACTION
     510if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle )
     511printk("\n[DBG] %s : send RPC to %s process %x in cluster %x\n",
     512__FUNCTION__ , process_action_str( action_type ) , pid , process_cxy );
     513#endif
     514        // atomically increment responses counter
     515        hal_atomic_add( (void *)&rpc.response , 1 );
     516
    508517        process_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
    509518        process_cxy = GET_CXY( process_xp );
    510         process_ptr = GET_PTR( process_xp );
    511 
    512 #if CONFIG_DEBUG_PROCESS_SIGACTION
    513 if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle )
    514 printk("\n[DBG] %s : send RPC to cluster %x\n", __FUNCTION__ , process_cxy );
    515 #endif
    516 
    517         // check PID
    518         assert( (hal_remote_lw( XPTR( process_cxy , &process_ptr->pid) ) == pid),
    519         __FUNCTION__ , "unconsistent PID value\n" );
    520 
    521         rpc.args[0] = (uint64_t)action_type;
    522         rpc.args[1] = (uint64_t)pid;
     519
     520        // call RPC in target cluster
    523521        rpc_process_sigaction_client( process_cxy , &rpc );
    524         rsp_count++;
    525522    }
    526523   
     
    528525    remote_spinlock_unlock( lock_xp );
    529526
    530     // check number of copies...
    531     assert( (rsp_count == responses) , __FUNCTION__ ,
    532     "unconsistent number of process copies : rsp_count = %d / responses = %d",
    533     rsp_count , responses );
    534 
    535     // block and deschedule to wait RPC responses
    536     thread_block( CURRENT_THREAD , THREAD_BLOCKED_RPC );
    537     sched_yield("BLOCKED on RPC_PROCESS_SIGACTION");
     527    // restore IRQs
     528    hal_restore_irq( save_sr);
     529
     530    // client deschedule : will be unblocked by the last RPC server thread
     531    sched_yield("blocked on rpc_process_sigaction");
    538532
    539533#if CONFIG_DEBUG_PROCESS_SIGACTION
     
    541535if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle )
    542536printk("\n[DBG] %s : thread %x exit after %s process %x in cluster %x / cycle %d\n",
    543 __FUNCTION__ , client, process_action_str( action_type ) ,
    544 process->pid , local_cxy , cycle );
     537__FUNCTION__ , client, process_action_str( action_type ) , pid , local_cxy , cycle );
    545538#endif
    546539
     
    553546    thread_t          * this;           // pointer on calling thread
    554547    uint32_t            ltid;           // index in process th_tbl
     548    cxy_t               owner_cxy;      // target process owner cluster
    555549    uint32_t            count;          // requests counter
    556     volatile uint32_t   rsp_count;      // responses counter
     550    volatile uint32_t   ack_count;      // scheduler acknowledge counter
    557551
    558552    // get calling thread pointer
    559553    this = CURRENT_THREAD;
     554
     555    // get target process owner cluster
     556    owner_cxy = CXY_FROM_PID( process->pid );
    560557
    561558#if CONFIG_DEBUG_PROCESS_SIGACTION
     
    569566    spinlock_lock( &process->th_lock );
    570567
    571     // initialize local responses counter
    572     rsp_count = process->th_nr;
    573 
    574     // loop on process threads to block and deschedule all threads in cluster
     568    // loop to block all threads but the main thread
    575569    // we use both "ltid" and "count" because it can exist "holes" in th_tbl
    576     for( ltid = 0 , count = 0 ; count < process->th_nr ; ltid++ )
     570    for( ltid = 0 , count = 0 , ack_count = 0 ; count < process->th_nr ; ltid++ )
    577571    {
    578572        target = process->th_tbl[ltid];
    579573
    580         assert( (target != this) , __FUNCTION__ , "calling thread cannot be a target\n" );
    581 
    582         if( target != NULL )             // thread found
     574        if( target != NULL )                                 // thread exist
    583575        {
    584576            count++;
    585577
    586             // - if the calling thread and the target thread are on the same core,
    587             //   we block the target thread, we don't need confirmation from scheduler,
    588             //   and we simply decrement the responses counter.
    589             // - if the calling thread and the target thread are not running on the same
    590             //   core, we ask the target scheduler to acknowlege the blocking
    591             //   to be sure that the target thread is not running.
    592            
    593             if( this->core->lid == target->core->lid )
     578            // main thread should not be deleted
     579            if( (ltid != 0) || (owner_cxy != local_cxy) )
    594580            {
    595581                // set the global blocked bit in target thread descriptor.
    596                 thread_block( target , THREAD_BLOCKED_GLOBAL );
    597 
    598                 // decrement responses counter
    599                 hal_atomic_add( (void *)&rsp_count , -1 );
    600             }
    601             else
    602             {
    603                 // set the global blocked bit in target thread descriptor.
    604                 thread_block( target , THREAD_BLOCKED_GLOBAL );
    605 
    606                 // set FLAG_REQ_ACK and &ack_rsp_count in target descriptor
    607                 thread_set_req_ack( target , (void *)&rsp_count );
    608 
    609                 // force scheduling on target thread
    610                 dev_pic_send_ipi( local_cxy , target->core->lid );
     582                thread_block( XPTR( local_cxy , target ) , THREAD_BLOCKED_GLOBAL );
     583 
     584                // - if the calling thread and the target thread are on the same core,
     585                //   we don't need confirmation from scheduler,
     586                // - if the calling thread and the target thread are not running on the same
     587                //   core, we ask the target scheduler to acknowlege the blocking
     588                //   to be sure that the target thread is not running.
     589           
     590                if( this->core->lid != target->core->lid )
     591                {
     592                    // increment responses counter
     593                    hal_atomic_add( (void*)&ack_count , 1 );
     594
     595                    // set FLAG_REQ_ACK and &ack_rsp_count in target descriptor
     596                    thread_set_req_ack( target , (uint32_t *)&ack_count );
     597
     598                    // force scheduling on target thread
     599                    dev_pic_send_ipi( local_cxy , target->core->lid );
     600                }
    611601            }
    612602        }
     
    616606    spinlock_unlock( &process->th_lock );
    617607
    618     // wait all responses from schedulers
     608    // wait acknowledges
    619609    while( 1 )
    620610    {
    621         // exit loop when all local responses received
    622         if ( rsp_count == 0 ) break;
     611        // exit when all scheduler acknoledges received
     612        if ( ack_count == 0 ) break;
    623613   
    624614        // wait 1000 cycles before retry
     
    656646    spinlock_lock( &process->th_lock );
    657647
    658     // loop on process threads to unblock all threads in cluster
     648    // loop on process threads to unblock all threads
    659649    // we use both "ltid" and "count" because it can exist "holes" in th_tbl
    660650    for( ltid = 0 , count = 0 ; count < process->th_nr ; ltid++ )
    661651    {
    662652        target = process->th_tbl[ltid];
    663 
    664         assert( (target != this) , __FUNCTION__ , "calling thread cannot be a target\n" );
    665653
    666654        if( target != NULL )             // thread found
     
    689677{
    690678    thread_t          * target;        // pointer on target thread
    691     thread_t          * this;          // pointer on calling thread
    692679    uint32_t            ltid;          // index in process th_tbl
    693     uint32_t            count;         // request counter
    694     cxy_t               owner_cxy;     // owner cluster identifier
    695 
    696     // get calling thread pointer
    697     this = CURRENT_THREAD;
    698     owner_cxy = CXY_FROM_PID( process->pid );
     680    uint32_t            count;         // threads counter
    699681
    700682#if CONFIG_DEBUG_PROCESS_SIGACTION
     
    702684if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle )
    703685printk("\n[DBG] %s : thread %x enter for process %x in cluster %x / cycle %d\n",
    704 __FUNCTION__ , this , process->pid , local_cxy , cycle );
     686__FUNCTION__ , CURRENT_THREAD , process->pid , local_cxy , cycle );
    705687#endif
    706688
     
    708690    spinlock_lock( &process->th_lock );
    709691
    710     // loop on threads to set the REQ_DELETE flag
     692    // loop to set the REQ_DELETE flag on all threads but the main
    711693    // we use both "ltid" and "count" because it can exist "holes" in th_tbl
    712694    for( ltid = 0 , count = 0  ; count < process->th_nr ; ltid++ )
     
    714696        target = process->th_tbl[ltid];
    715697
    716         assert( (target != this) , __FUNCTION__ , "calling thread cannot be a target\n" );
    717 
    718         if( target != NULL )            // thread found
     698        if( target != NULL )
    719699        {
    720700            count++;
    721701           
    722             // the main thread should not be deleted
    723             if( (owner_cxy != local_cxy) || (ltid != 0) )   
    724             {
    725                 hal_atomic_or( &target->flags , THREAD_FLAG_REQ_DELETE );
    726             }
     702            thread_kill( XPTR( local_cxy , target ),
     703                         false,                       // is_exit
     704                         true );                      // is_forced
    727705        }
    728706    }
     
    735713if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle )
    736714printk("\n[DBG] %s : thread %x exit for process %x in cluster %x / cycle %d\n",
    737 __FUNCTION__ , this , process->pid , local_cxy , cycle );
     715__FUNCTION__ , CURRENT_THREAD , process->pid , local_cxy , cycle );
    738716#endif
    739717
     
    790768
    791769}  // end process_get_local_copy()
     770
     771////////////////////////////////////////////
     772pid_t process_get_ppid( xptr_t  process_xp )
     773{
     774    cxy_t       process_cxy;
     775    process_t * process_ptr;
     776    xptr_t      parent_xp;
     777    cxy_t       parent_cxy;
     778    process_t * parent_ptr;
     779
     780    // get process cluster and local pointer
     781    process_cxy = GET_CXY( process_xp );
     782    process_ptr = GET_PTR( process_xp );
     783
     784    // get pointers on parent process
     785    parent_xp  = (xptr_t)hal_remote_lwd( XPTR( process_cxy , &process_ptr->parent_xp ) );
     786    parent_cxy = GET_CXY( parent_xp );
     787    parent_ptr = GET_PTR( parent_xp );
     788
     789    return hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) );
     790}
    792791
    793792//////////////////////////////////////////////////////////////////////////////////////////
     
    10671066                            parent_process_xp );
    10681067
    1069 #if CONFIG_DEBUG_PROCESS_MAKE_FORK
     1068#if( CONFIG_DEBUG_PROCESS_MAKE_FORK & 1 )
    10701069cycle = (uint32_t)hal_get_cycles();
    10711070if( CONFIG_DEBUG_PROCESS_MAKE_FORK < cycle )
     
    10861085    }
    10871086
    1088 #if CONFIG_DEBUG_PROCESS_MAKE_FORK
     1087#if( CONFIG_DEBUG_PROCESS_MAKE_FORK & 1 )
    10891088cycle = (uint32_t)hal_get_cycles();
    10901089if( CONFIG_DEBUG_PROCESS_MAKE_FORK < cycle )
     
    11121111    assert( (thread->trdid == 0) , __FUNCTION__ , "main thread must have index 0\n" );
    11131112
    1114 #if CONFIG_DEBUG_PROCESS_MAKE_FORK
     1113#if( CONFIG_DEBUG_PROCESS_MAKE_FORK & 1 )
    11151114cycle = (uint32_t)hal_get_cycles();
    11161115if( CONFIG_DEBUG_PROCESS_MAKE_FORK < cycle )
     
    11341133    vmm_set_cow( process );
    11351134 
    1136 #if CONFIG_DEBUG_PROCESS_MAKE_FORK
     1135#if( CONFIG_DEBUG_PROCESS_MAKE_FORK & 1 )
    11371136cycle = (uint32_t)hal_get_cycles();
    11381137if( CONFIG_DEBUG_PROCESS_MAKE_FORK < cycle )
     
    12361235
    12371236    // give TXT ownership to new_process
    1238     process_txt_set_ownership( XPTR( local_cxy , new_process ) );
    1239 
    1240 #if CONFIG_DEBUG_PROCESS_MAKE_EXEC
     1237    process_txt_set_ownership( XPTR( local_cxy , new_process) );
     1238
     1239#if( CONFIG_DEBUG_PROCESS_MAKE_EXEC & 1 )
    12411240cycle = (uint32_t)hal_get_cycles();
    12421241if( CONFIG_DEBUG_PROCESS_MAKE_EXEC < cycle )
     
    12551254        }
    12561255
    1257 #if CONFIG_DEBUG_PROCESS_MAKE_EXEC
     1256#if( CONFIG_DEBUG_PROCESS_MAKE_EXEC & 1 )
    12581257cycle = (uint32_t)hal_get_cycles();
    12591258if( CONFIG_DEBUG_PROCESS_MAKE_EXEC < cycle )
     
    12871286    assert( (new_thread->trdid == 0) , __FUNCTION__ , "main thread must have index 0\n" );
    12881287
    1289 #if CONFIG_DEBUG_PROCESS_MAKE_EXEC
     1288#if( CONFIG_DEBUG_PROCESS_MAKE_EXEC & 1 )
    12901289cycle = (uint32_t)hal_get_cycles();
    12911290if( CONFIG_DEBUG_PROCESS_MAKE_EXEC < cycle )
     
    13121311        thread_unblock( XPTR( local_cxy , new_thread ) , THREAD_BLOCKED_GLOBAL );
    13131312
     1313    // detach old_process from TXT
     1314    process_txt_detach( XPTR( local_cxy , old_process ) );
     1315
    13141316    // request old_thread destruction => old_process destruction
    1315     thread_block( old_thread , THREAD_BLOCKED_GLOBAL );
     1317    thread_block( XPTR( local_cxy , old_thread ) , THREAD_BLOCKED_GLOBAL );
    13161318    hal_atomic_or( &old_thread->flags , THREAD_FLAG_REQ_DELETE );
    13171319
     
    16001602if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle )
    16011603printk("\n[DBG] %s : thread %x enter for process %x / txt_id = %d  / cycle %d\n",
    1602 __FUNCTION__, CURRENT_THREAD, process, txt_id, cycle );
    1603 #endif
    1604 
    1605     // check process is reference
    1606     assert( (process->ref_xp == XPTR( local_cxy , process )) , __FUNCTION__ ,
    1607     "process is not the reference descriptor" );
     1604__FUNCTION__, CURRENT_THREAD, process->pid, txt_id, cycle );
     1605#endif
     1606
     1607    // check process is in owner cluster
     1608    assert( (CXY_FROM_PID( process->pid ) == local_cxy) , __FUNCTION__ ,
     1609    "process descriptor not in owner cluster" );
    16081610
    16091611    // check terminal index
     
    16291631if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle )
    16301632printk("\n[DBG] %s : thread %x exit for process %x / txt_id = %d / cycle %d\n",
    1631 __FUNCTION__, CURRENT_THREAD, process, txt_id , cycle );
     1633__FUNCTION__, CURRENT_THREAD, process->pid, txt_id , cycle );
    16321634#endif
    16331635
    16341636} // end process_txt_attach()
    16351637
    1636 //////////////////////////////////////////////
    1637 void process_txt_detach( process_t * process )
    1638 {
     1638/////////////////////////////////////////////
     1639void process_txt_detach( xptr_t  process_xp )
     1640{
     1641    process_t * process_ptr;  // local pointer on process in owner cluster
     1642    cxy_t       process_cxy;  // process owner cluster
     1643    pid_t       process_pid;  // process identifier
     1644    xptr_t      file_xp;      // extended pointer on stdin file
    16391645    xptr_t      chdev_xp;     // extended pointer on TXT_RX chdev
    16401646    cxy_t       chdev_cxy;    // TXT_RX chdev cluster
     
    16421648    xptr_t      lock_xp;      // extended pointer on list lock in chdev
    16431649
     1650    // get process cluster, local pointer, and PID
     1651    process_cxy = GET_CXY( process_xp );
     1652    process_ptr = GET_PTR( process_xp );
     1653    process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) );
     1654
     1655    // check process descriptor in owner cluster
     1656    assert( (CXY_FROM_PID( process_pid ) == process_cxy ) , __FUNCTION__ ,
     1657    "process descriptor not in owner cluster" );
     1658
    16441659#if CONFIG_DEBUG_PROCESS_TXT_ATTACH
    16451660uint32_t cycle = (uint32_t)hal_get_cycles();
    16461661if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle )
    16471662printk("\n[DBG] %s : thread %x enter for process %x / cycle %d\n",
    1648 __FUNCTION__, CURRENT_THREAD, process, cycle );
    1649 #endif
    1650 
    1651     // check process is reference
    1652     assert( (process->ref_xp == XPTR( local_cxy , process )) , __FUNCTION__ ,
    1653     "process is not the reference descriptor" );
    1654 
    1655     // get extended pointer on TXT_RX chdev
    1656     chdev_xp  = chdev_from_file( process->fd_array.array[0] );
     1663__FUNCTION__, CURRENT_THREAD, process_pid, cycle );
     1664#endif
     1665
     1666    // release TXT ownership (does nothing if not TXT owner)
     1667    process_txt_transfer_ownership( process_xp );
     1668
     1669    // get extended pointer on process stdin file
     1670    file_xp = (xptr_t)hal_remote_lwd( XPTR( process_cxy , &process_ptr->fd_array.array[0] ) );
     1671
     1672    // get pointers on TXT_RX chdev
     1673    chdev_xp  = chdev_from_file( file_xp );
    16571674    chdev_cxy = GET_CXY( chdev_xp );
    16581675    chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );
    16591676
    1660     // get extended pointer on lock of attached process list
     1677    // get extended pointer on lock protecting attached process list
    16611678    lock_xp = XPTR( chdev_cxy , &chdev_ptr->ext.txt.lock );
    16621679
    16631680    // unlink process from attached process list
    16641681    remote_spinlock_lock( lock_xp );
    1665     xlist_unlink( XPTR( local_cxy , &process->txt_list ) );
     1682    xlist_unlink( XPTR( process_cxy , &process_ptr->txt_list ) );
    16661683    remote_spinlock_unlock( lock_xp );
    1667    
     1684
     1685#if( CONFIG_DEBUG_PROCESS_TXT_ATTACH & 1 )
     1686if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle )
     1687{
     1688    xptr_t root_xp = XPTR( chdev_cxy , &chdev_ptr->ext.txt.root );
     1689    xptr_t iter_xp;
     1690    XLIST_FOREACH( root_xp , iter_xp )
     1691    {
     1692        xptr_t      current_xp  = XLIST_ELEMENT( iter_xp , process_t , txt_list );
     1693        process_t * current_ptr = GET_PTR( current_xp );
     1694
     1695        printk("\n[DBG] %s : attached_process %x (pid = %x)\n",
     1696        __FUNCTION__, current_ptr, current_ptr->pid );
     1697    }
     1698}
     1699#endif
     1700
    16681701#if CONFIG_DEBUG_PROCESS_TXT_ATTACH
    16691702cycle = (uint32_t)hal_get_cycles();
    16701703if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle )
    1671 printk("\n[DBG] %s : thread %x exit for process %x / cycle %d\n",
    1672 __FUNCTION__, CURRENT_THREAD, process, cycle );
     1704printk("\n[DBG] %s : thread %x exit / process %x detached from TXT / cycle %d\n",
     1705__FUNCTION__, CURRENT_THREAD, process->pid, cycle );
    16731706#endif
    16741707
     
    16801713    process_t * process_ptr;
    16811714    cxy_t       process_cxy;
     1715    pid_t       process_pid;
    16821716    xptr_t      file_xp;
    16831717    xptr_t      txt_xp;     
     
    16851719    cxy_t       txt_cxy;
    16861720
    1687     // get cluster and local pointer on process
     1721    // get pointers on process in owner cluster
    16881722    process_cxy = GET_CXY( process_xp );
    16891723    process_ptr = GET_PTR( process_xp );
     1724
     1725    // get process PID
     1726    process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) );
     1727
     1728    // check owner cluster
     1729    assert( (process_cxy == CXY_FROM_PID( process_pid )) , __FUNCTION__,
     1730    "process descriptor not in owner cluster\n" );
     1731
     1732#if CONFIG_DEBUG_PROCESS_TXT_ATTACH
     1733uint32_t cycle = (uint32_t)hal_get_cycles();
     1734if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle )
     1735printk("\n[DBG] %s : thread %x enter for process %x / cycle %d\n",
     1736__FUNCTION__, CURRENT_THREAD, process_pid, cycle );
     1737#endif
    16901738
    16911739    // get extended pointer on stdin pseudo file
     
    17001748    hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , process_xp );
    17011749
     1750#if CONFIG_DEBUG_PROCESS_TXT_ATTACH
     1751cycle = (uint32_t)hal_get_cycles();
     1752if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle )
     1753printk("\n[DBG] %s : thread %x exit for process %x / cycle %d\n",
     1754__FUNCTION__, CURRENT_THREAD, process_pid, cycle );
     1755#endif
     1756
    17021757}  // end process_txt_set ownership()
    17031758
    1704 /////////////////////////////////////////////////////
    1705 void process_txt_reset_ownership( xptr_t process_xp )
    1706 {
    1707     process_t * process_ptr;
    1708     cxy_t       process_cxy;
    1709     xptr_t      parent_xp;       // extended pointer on parent process
    1710     process_t * parent_ptr;
    1711     cxy_t       parent_cxy;
     1759////////////////////////////////////////////////////////
     1760void process_txt_transfer_ownership( xptr_t process_xp )
     1761{
     1762    process_t * process_ptr;     // local pointer on process releasing ownership
     1763    cxy_t       process_cxy;     // process cluster
     1764    pid_t       process_pid;     // process identifier
    17121765    xptr_t      file_xp;         // extended pointer on TXT_RX pseudo file
    17131766    xptr_t      txt_xp;          // extended pointer on TXT_RX chdev
     
    17171770    xptr_t      owner_xp;        // extended pointer on current TXT_RX owner
    17181771    xptr_t      root_xp;         // extended pointer on root of attached process list
     1772    xptr_t      lock_xp;         // extended pointer on lock protecting attached process list
    17191773    xptr_t      iter_xp;         // iterator for xlist
    17201774    xptr_t      current_xp;      // extended pointer on current process
    17211775    process_t * current_ptr;     // local pointer on current process
    17221776    cxy_t       current_cxy;     // cluster for current process
    1723     pid_t       ppid;            // parent process identifier for current process
    1724 
    1725     // get cluster and local pointer on process
     1777
     1778    // get pointers on process in owner cluster
    17261779    process_cxy = GET_CXY( process_xp );
    17271780    process_ptr = GET_PTR( process_xp );
     1781
     1782    // get process PID
     1783    process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) );
     1784
     1785    // check owner cluster
     1786    assert( (process_cxy == CXY_FROM_PID( process_pid )) , __FUNCTION__,
     1787    "process descriptor not in owner cluster\n" );
     1788
     1789#if CONFIG_DEBUG_PROCESS_TXT_ATTACH
     1790uint32_t cycle = (uint32_t)hal_get_cycles();
     1791if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle )
     1792printk("\n[DBG] %s : thread %x enter / process %x / pid %x / cycle %d\n",
     1793__FUNCTION__, CURRENT_THREAD, process_ptr, process_pid, cycle );
     1794#endif
    17281795
    17291796    // get extended pointer on stdin pseudo file
     
    17391806    txt_id   = hal_remote_lw ( XPTR( txt_cxy , &txt_ptr->channel ) );
    17401807
    1741     // transfer ownership to KSH if required
    1742     if( (owner_xp == process_xp) && (txt_id > 0) )   
    1743     {
    1744         // get extended pointer on root of list of attached processes
    1745         root_xp = hal_remote_lwd( XPTR( txt_cxy , &txt_ptr->ext.txt.root ) );
    1746 
    1747         // scan attached process list to find KSH process
    1748         XLIST_FOREACH( root_xp , iter_xp )
     1808#if( CONFIG_DEBUG_PROCESS_TXT_ATTACH & 1 )
     1809if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle )
     1810printk("\n[DBG] %s : file_ptr %x / txt_ptr %x / txt_id %d / owner_ptr = %x\n",
     1811__FUNCTION__, GET_PTR(file_xp), txt_ptr, txt_id, GET_PTR(owner_xp) );
     1812#endif
     1813
     1814    // transfer ownership only if process is the TXT owner
     1815    if( (owner_xp == process_xp) && (txt_id > 0) ) 
     1816    {
     1817        // get extended pointers on root and lock of attached processes list
     1818        root_xp = XPTR( txt_cxy , &txt_ptr->ext.txt.root );
     1819        lock_xp = XPTR( txt_cxy , &txt_ptr->ext.txt.lock );
     1820
     1821        // get lock
     1822        remote_spinlock_lock( lock_xp );
     1823
     1824        if( process_get_ppid( process_xp ) != 1 )           // process is not KSH
    17491825        {
    1750             current_xp  = XLIST_ELEMENT( iter_xp , process_t , txt_list );
    1751             current_cxy = GET_CXY( current_xp );
    1752             current_ptr = GET_PTR( current_xp );
    1753             parent_xp   = hal_remote_lwd( XPTR( current_cxy , &current_ptr->parent_xp ) );
    1754             parent_cxy  = GET_CXY( parent_xp );
    1755             parent_ptr  = GET_PTR( parent_xp );
    1756             ppid        = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) );
    1757 
    1758 printk("\n@@@ %s : pid = %x / process = %x\n", __FUNCTION__ , current_ptr->pid, current_ptr );
    1759 
    1760             if( ppid == 1 )  // current is KSH
     1826
     1827#if( CONFIG_DEBUG_PROCESS_TXT_ATTACH & 1 )
     1828if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle )
     1829printk("\n[DBG] %s : process is not the KSH process => search the KSH\n", __FUNCTION__ );
     1830#endif
     1831            // scan attached process list to find KSH process
     1832            XLIST_FOREACH( root_xp , iter_xp )
    17611833            {
    1762                 // set owner field in TXT chdev
    1763                 hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , current_xp );
    1764                 return;
     1834                current_xp  = XLIST_ELEMENT( iter_xp , process_t , txt_list );
     1835                current_cxy = GET_CXY( current_xp );
     1836                current_ptr = GET_PTR( current_xp );
     1837
     1838                if( process_get_ppid( current_xp ) == 1 )  // current is KSH
     1839                {
     1840                    // release lock
     1841                    remote_spinlock_unlock( lock_xp );
     1842
     1843                    // set owner field in TXT chdev
     1844                    hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , current_xp );
     1845
     1846#if CONFIG_DEBUG_PROCESS_TXT_ATTACH
     1847cycle = (uint32_t)hal_get_cycles();
     1848if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle )
     1849printk("\n[DBG] %s : thread %x exit / process %x to KSH process %x / cycle %d\n",
     1850__FUNCTION__, CURRENT_THREAD, process_pid,
     1851hal_remote_lw( XPTR( current_cxy , &current_ptr->pid ) ), cycle );
     1852#endif
     1853                     return;
     1854                }
    17651855            }
     1856 
     1857            // release lock
     1858            remote_spinlock_unlock( lock_xp );
     1859
     1860            // PANIC if KSH not found
     1861            assert( false , __FUNCTION__ , "KSH process not found for TXT %d" );
     1862
     1863            return;
    17661864        }
    1767 
    1768         assert( false , __FUNCTION__ , "KSH process not found" );
    1769     }
    1770 }  // end process_txt_reset_ownership()
    1771 
    1772 
    1773 //////////////////////////////////////////////////////     
    1774 inline pid_t process_get_txt_owner( uint32_t channel )
     1865        else                                               // process is KSH
     1866        {
     1867
     1868#if( CONFIG_DEBUG_PROCESS_TXT_ATTACH & 1 )
     1869if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle )
     1870printk("\n[DBG] %s : process is the KSH process => search another\n", __FUNCTION__ );
     1871#endif
     1872
     1873            // scan attached process list to find another process
     1874            XLIST_FOREACH( root_xp , iter_xp )
     1875            {
     1876                current_xp  = XLIST_ELEMENT( iter_xp , process_t , txt_list );
     1877                current_cxy = GET_CXY( current_xp );
     1878                current_ptr = GET_PTR( current_xp );
     1879
     1880                if( current_xp != process_xp )            // current is not KSH
     1881                {
     1882                    // release lock
     1883                    remote_spinlock_unlock( lock_xp );
     1884
     1885                    // set owner field in TXT chdev
     1886                    hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , current_xp );
     1887
     1888#if CONFIG_DEBUG_PROCESS_TXT_ATTACH
     1889cycle = (uint32_t)hal_get_cycles();
     1890if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle )
     1891printk("\n[DBG] %s : thread %x exit / KSH process %x to process %x / cycle %d\n",
     1892__FUNCTION__, CURRENT_THREAD, process_pid,
     1893hal_remote_lw( XPTR( current_cxy , &current_ptr->pid ) ), cycle );
     1894#endif
     1895                     return;
     1896                }
     1897            }
     1898
     1899            // release lock
     1900            remote_spinlock_unlock( lock_xp );
     1901
     1902            // no more owner for TXT if no other process found
     1903            hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , XPTR_NULL );
     1904
     1905#if CONFIG_DEBUG_PROCESS_TXT_ATTACH
     1906cycle = (uint32_t)hal_get_cycles();
     1907if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle )
     1908printk("\n[DBG] %s : thread %x exit / KSH process %x to nobody / cycle %d\n",
     1909__FUNCTION__, CURRENT_THREAD, process_pid, cycle );
     1910#endif
     1911            return;
     1912        }
     1913    }
     1914    else
     1915    {
     1916
     1917#if CONFIG_DEBUG_PROCESS_TXT_ATTACH
     1918cycle = (uint32_t)hal_get_cycles();
     1919if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle )
     1920printk("\n[DBG] %s : thread %x exit / process %x is not TXT owner / cycle %d\n",
     1921__FUNCTION__, CURRENT_THREAD, process_pid, cycle );
     1922#endif
     1923
     1924    }
     1925}  // end process_txt_transfer_ownership()
     1926
     1927
     1928////////////////////////////////////////////////     
     1929xptr_t process_txt_get_owner( uint32_t channel )
    17751930{
    17761931    xptr_t      txt_rx_xp  = chdev_dir.txt_rx[channel];
     
    17781933    chdev_t *   txt_rx_ptr = GET_PTR( txt_rx_xp );
    17791934
    1780     xptr_t process_xp = (xptr_t)hal_remote_lwd( XPTR( txt_rx_cxy,
    1781                                                 &txt_rx_ptr->ext.txt.owner_xp ) );
    1782 
    1783     cxy_t       process_cxy = GET_CXY( process_xp );
    1784     process_t * process_ptr = GET_PTR( process_xp );
    1785 
    1786     return (pid_t)hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) );
     1935    return (xptr_t)hal_remote_lwd( XPTR( txt_rx_cxy , &txt_rx_ptr->ext.txt.owner_xp ) );
    17871936}
    17881937
     
    18171966    remote_spinlock_lock( lock_xp );
    18181967
    1819     // scan attached process list to find KSH process
     1968    // scan attached process list
    18201969    XLIST_FOREACH( root_xp , iter_xp )
    18211970    {
Note: See TracChangeset for help on using the changeset viewer.