Changeset 581 for trunk/kernel/kern


Ignore:
Timestamp:
Oct 10, 2018, 3:11:53 PM (6 years ago)
Author:
alain
Message:

1) Improve the busylock debug infrastructure.
2) introduce a non-distributed, but portable implementation for the pthread_barrier.

Location:
trunk/kernel/kern
Files:
5 edited

Legend:

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

    r564 r581  
    154154    chdev_t * chdev_ptr = GET_PTR( chdev_xp );
    155155
    156 // check calling thread can yield
    157 assert( (this->busylocks == 0),
    158 "cannot yield : busylocks = %d\n", this->busylocks );
     156    // check calling thread can yield
     157    thread_assert_can_yield( this , __FUNCTION__ );
    159158
    160159    // get local and extended pointers on server thread
     
    197196    // build extended pointer on lock protecting chdev waiting queue
    198197    lock_xp            = XPTR( chdev_cxy , &chdev_ptr->wait_lock );
     198
     199    // TODO the hal_disable_irq() / hal_restore_irq()
     200    // in the sequence below is probably useless, as it is
     201    // already done by the busylock_acquire() / busylock_release()
     202    // => remove it [AG] october 2018
    199203
    200204    // critical section for the following sequence:
     
    206210    // (6) release the lock protecting waiting queue
    207211    // (7) deschedule
    208     // ... in this order
    209212
    210213    // enter critical section
  • trunk/kernel/kern/process.c

    r580 r581  
    112112    cxy_t       chdev_cxy;
    113113    pid_t       parent_pid;
    114     lpid_t      process_lpid;
    115     lpid_t      parent_lpid;
    116114
    117115    // get parent process cluster and local pointer
     
    121119    // get parent_pid
    122120    parent_pid = hal_remote_l32( XPTR( parent_cxy , &parent_ptr->pid ) );
    123 
    124     // get process and parent lpid
    125     process_lpid = LPID_FROM_PID( pid );
    126     parent_lpid  = LPID_FROM_PID( parent_pid );
    127121
    128122#if DEBUG_PROCESS_REFERENCE_INIT
     
    156150
    157151    // define the stdin/stdout/stderr pseudo files <=> select a TXT terminal.
    158     if( (process_lpid == 1) ||     // INIT process
    159         (parent_lpid  == 1) )      // KSH  process
    160     {
    161         // allocate a TXT channel
    162         if( process_lpid == 1 )  txt_id = 0;                     // INIT
    163         else                     txt_id = process_txt_alloc();   // KSH
     152    if( (pid == 1) || (parent_pid  == 1) )      // INIT or KSH  process
     153    {
     154        // select a TXT channel
     155        if( pid == 1 )  txt_id = 0;                     // INIT
     156        else            txt_id = process_txt_alloc();   // KSH
    164157
    165158        // attach process to TXT
     
    17911784    if( txt_owner_xp == process_xp )
    17921785    {
    1793         nolock_printk("PID %X | PPID %X | TS %X | %s (FG) | %X | %d | %s\n",
    1794         pid, ppid, state, txt_name, process_ptr, th_nr, elf_name );
     1786        nolock_printk("PID %X | %s (FG) | %X | PPID %X | TS %X | %d | %s\n",
     1787        pid, txt_name, process_ptr, ppid, state, th_nr, elf_name );
    17951788    }
    17961789    else
    17971790    {
    1798         nolock_printk("PID %X | PPID %X | TS %X | %s (BG) | %X | %d | %s\n",
    1799         pid, ppid, state, txt_name, process_ptr, th_nr, elf_name );
     1791        nolock_printk("PID %X | %s (BG) | %X | PPID %X | TS %X | %d | %s\n",
     1792        pid, txt_name, process_ptr, ppid, state, th_nr, elf_name );
    18001793    }
    18011794}  // end process_display()
     
    18061799////////////////////////////////////////////////////////////////////////////////////////
    18071800
    1808 ////////////////////////////
     1801//////////////////////////////////
    18091802uint32_t process_txt_alloc( void )
    18101803{
  • trunk/kernel/kern/rpc.c

    r564 r581  
    142142    client_core_lid = this->core->lid;
    143143
    144 // check calling thread can yield when it is not the idle thread
    145 assert( (this->busylocks == 0) || (this->type == THREAD_IDLE),
    146 "cannot yield : busylocks = %d\n", this->busylocks );
     144    // check calling thread can yield when client thread is not the IDLE thread
     145    // RPCs executed by the IDLE thread during kernel_init do not deschedule
     146    if( this->type != THREAD_IDLE ) thread_assert_can_yield( this , __FUNCTION__ );
    147147
    148148#if DEBUG_RPC_CLIENT_GENERIC
     
    204204
    205205    // wait RPC completion before returning if blocking RPC :
    206     // - descheduling without blocking if thread idle (in lernel init)
     206    // - descheduling without blocking if thread idle (in kernel init)
    207207    // - block and deschedule policy for any other thread
    208208    if ( rpc->blocking )
  • trunk/kernel/kern/scheduler.c

    r564 r581  
    411411#endif
    412412
    413 // check current thread busylocks counter
     413// This assert should never be false, as this check must be
     414// done before by any function that can possibly deschedule...
    414415assert( (current->busylocks == 0),
    415 "thread cannot yield : busylocks = %d\n", current->busylocks );
     416"unexpected descheduling of thread holding %d busylocks = %d\n", current->busylocks );
    416417
    417418    // activate or create an RPC thread if RPC_FIFO non empty
  • trunk/kernel/kern/thread.c

    r580 r581  
    190190    if( error )
    191191    {
    192         printk("\n[ERROR] in %s : cannot get TRDID\n", __FUNCTION__ );
     192        printk("\n[ERROR] in %s : thread %x in process %x cannot get TRDID in cluster %x\n"
     193        "    for thread %s in process %x / cycle %d\n",
     194        __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,
     195        local_cxy, thread_type_str(type), process->pid, (uint32_t)hal_get_cycles() );
    193196        return EINVAL;
    194197    }
     
    710713
    711714    assert( ( (type == THREAD_IDLE) || (type == THREAD_RPC) || (type == THREAD_DEV) ) ,
    712         "illegal thread type" );
     715    "illegal thread type" );
    713716
    714717    assert( (core_lid < LOCAL_CLUSTER->cores_nr) ,
    715             "illegal core_lid" );
     718    "illegal core_lid" );
    716719
    717720#if DEBUG_THREAD_KERNEL_CREATE
     
    725728    thread = thread_alloc();
    726729
    727     if( thread == NULL ) return ENOMEM;
     730    if( thread == NULL )
     731    {
     732        printk("\n[ERROR] in %s : thread %x in process %x\n"
     733        "   no memory for thread descriptor\n",
     734        __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid );
     735        return ENOMEM;
     736    }
    728737
    729738    // initialize thread descriptor
     
    738747    if( error ) // release allocated memory for thread descriptor
    739748    {
     749        printk("\n[ERROR] in %s : thread %x in process %x\n"
     750        "   cannot initialize thread descriptor\n",
     751        __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid );
    740752        thread_release( thread );
    741753        return ENOMEM;
     
    744756    // allocate & initialize CPU context
    745757        error = hal_cpu_context_alloc( thread );
     758
    746759    if( error )
    747760    {
     761        printk("\n[ERROR] in %s : thread %x in process %x\n"
     762        "   cannot cannot create CPU context\n",
     763        __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid );
    748764        thread_release( thread );
    749765        return EINVAL;
    750766    }
     767
    751768    hal_cpu_context_init( thread );
    752769
     
    13641381void thread_display_busylocks( xptr_t  thread_xp )
    13651382{
    1366     if( DEBUG_BUSYLOCK )
    1367     {
    1368         xptr_t    iter_xp;
    1369 
    1370         // get cluster and local pointer of target thread
    1371         cxy_t      thread_cxy = GET_CXY( thread_xp );
    1372         thread_t * thread_ptr = GET_PTR( thread_xp );
    1373 
    1374         // get target thread TRDID and busylocks
    1375         trdid_t  trdid = hal_remote_l32(XPTR( thread_cxy , &thread_ptr->trdid ));
    1376         uint32_t locks = hal_remote_l32(XPTR( thread_cxy , &thread_ptr->busylocks ));
    1377 
    1378         // get target thread process and PID;
    1379         process_t * process = hal_remote_lpt(XPTR( thread_cxy , &thread_ptr->process ));
    1380         pid_t       pid     = hal_remote_l32(XPTR( thread_cxy , &process->pid ));
    1381 
    1382         // get extended pointer on root of busylocks
    1383         xptr_t    root_xp = XPTR( thread_cxy , &thread_ptr->busylocks_root );
    1384 
    1385         // get pointers on TXT0 chdev
    1386         xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
    1387         cxy_t     txt0_cxy = GET_CXY( txt0_xp );
    1388         chdev_t * txt0_ptr = GET_PTR( txt0_xp );
    1389 
    1390         // get extended pointer on remote TXT0 lock
    1391         xptr_t  txt0_lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
    1392 
    1393         // get TXT0 lock
    1394         remote_busylock_acquire( txt0_lock_xp );
    1395 
    1396         // display header
    1397         nolock_printk("\n***** thread %x in process %x : %d busylocks at cycle %d\n",
    1398         trdid, pid, locks, (uint32_t)hal_get_cycles() );
    1399 
    1400         // scan the xlist of busylocks when required
    1401         if( locks )
     1383    // get cluster and local pointer of target thread
     1384    cxy_t      thread_cxy = GET_CXY( thread_xp );
     1385    thread_t * thread_ptr = GET_PTR( thread_xp );
     1386
     1387#if( DEBUG_BUSYLOCK )
     1388
     1389    xptr_t    iter_xp;
     1390
     1391    // get target thread TRDID and busylocks
     1392    trdid_t  trdid = hal_remote_l32(XPTR( thread_cxy , &thread_ptr->trdid ));
     1393    uint32_t locks = hal_remote_l32(XPTR( thread_cxy , &thread_ptr->busylocks ));
     1394
     1395    // get target thread process and PID;
     1396    process_t * process = hal_remote_lpt(XPTR( thread_cxy , &thread_ptr->process ));
     1397    pid_t       pid     = hal_remote_l32(XPTR( thread_cxy , &process->pid ));
     1398
     1399    // get extended pointer on root of busylocks
     1400    xptr_t    root_xp = XPTR( thread_cxy , &thread_ptr->busylocks_root );
     1401
     1402    // get pointers on TXT0 chdev
     1403    xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
     1404    cxy_t     txt0_cxy = GET_CXY( txt0_xp );
     1405    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
     1406
     1407    // get extended pointer on remote TXT0 lock
     1408    xptr_t  txt0_lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
     1409
     1410    // get TXT0 lock
     1411    remote_busylock_acquire( txt0_lock_xp );
     1412
     1413    // display header
     1414    nolock_printk("\n***** thread %x in process %x : %d busylocks at cycle %d\n",
     1415    trdid, pid, locks, (uint32_t)hal_get_cycles() );
     1416
     1417    // scan the xlist of busylocks when required
     1418    if( locks )
     1419    {
     1420        XLIST_FOREACH( root_xp , iter_xp )
    14021421        {
    1403             XLIST_FOREACH( root_xp , iter_xp )
    1404             {
    1405                 xptr_t       lock_xp   = XLIST_ELEMENT( iter_xp , busylock_t , xlist );
    1406                 cxy_t        lock_cxy  = GET_CXY( lock_xp );
    1407                 busylock_t * lock_ptr  = GET_PTR( lock_xp );
    1408                 uint32_t     lock_type = hal_remote_l32(XPTR( lock_cxy , &lock_ptr->type ));
    1409                 nolock_printk(" - %s in cluster %x\n", lock_type_str[lock_type] , lock_cxy );
    1410             }
     1422            xptr_t       lock_xp   = XLIST_ELEMENT( iter_xp , busylock_t , xlist );
     1423            cxy_t        lock_cxy  = GET_CXY( lock_xp );
     1424            busylock_t * lock_ptr  = GET_PTR( lock_xp );
     1425            uint32_t     lock_type = hal_remote_l32(XPTR( lock_cxy , &lock_ptr->type ));
     1426            nolock_printk(" - %s in cluster %x\n", lock_type_str[lock_type] , lock_cxy );
    14111427        }
    1412 
    1413         // release TXT0 lock
    1414         remote_busylock_release( txt0_lock_xp );
    1415     }
    1416     else
    1417     {
    1418         // display a warning
    1419         printk("\n[WARNING] set the DEBUG_BUSYLOCK parmeter in kernel_config.h"
    1420         " to use the %s function\n", __FUNCTION__ );
    1421     }
     1428    }
     1429
     1430    // release TXT0 lock
     1431    remote_busylock_release( txt0_lock_xp );
     1432
     1433    return;
     1434
     1435#endif
     1436
     1437    // display a warning
     1438    printk("\n[WARNING] set the DEBUG_BUSYLOCK parmeter in kernel_config.h"
     1439    " to display busylocks for thread %x/%x\n", thread_cxy, thread_ptr );
     1440
    14221441}  // end thread_display_busylock()
     1442
Note: See TracChangeset for help on using the changeset viewer.