Ignore:
Timestamp:
Apr 4, 2018, 2:49:02 PM (7 years ago)
Author:
alain
Message:

Fix a bug in scheduler related to RPC blocking.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/syscalls/sys_fork.c

    r435 r438  
    4545    pid_t             parent_pid;           // parent process identifier
    4646    thread_t        * parent_thread_ptr;    // local pointer on local parent thread descriptor
     47    cxy_t             parent_cxy;           // parent thread cluster
    4748
    4849    pid_t             child_pid;            // child process identifier
    4950    thread_t        * child_thread_ptr;     // local pointer on remote child thread descriptor
    50     cxy_t             target_cxy;           // target cluster for forked child process
     51    cxy_t             child_cxy;            // target cluster for forked child process
    5152 
    5253    xptr_t            ref_process_xp;       // extended pointer on reference parent process
     
    6263        parent_process_ptr = parent_thread_ptr->process;
    6364    parent_pid         = parent_process_ptr->pid;
    64 
    65 #if CONFIG_DEBUG_SYS_FORK
     65    parent_cxy         = local_cxy;
     66
     67#if DEBUG_SYS_FORK
    6668uint64_t          tm_start;
    6769uint64_t          tm_end;
    6870tm_start = hal_get_cycles();
    69 if( CONFIG_DEBUG_SYS_FORK < tm_start )
    70 printk("\n[DBG] %s : thread %x enter / parent %x / cycle =  %d\n",
     71if( DEBUG_SYS_FORK < tm_start )
     72printk("\n[DBG] %s : parent_thread %x enter / parent_pid %x / cycle =  %d\n",
    7173__FUNCTION__, parent_thread_ptr, parent_pid, (uint32_t)tm_start );
    7274#endif
    7375
    74     // get infos on reference process
     76    // get infos on reference parent process
    7577    ref_process_xp  = parent_process_ptr->ref_xp;
    7678    ref_process_cxy = GET_CXY( ref_process_xp );
     
    8284        {
    8385
    84 #if CONFIG_DEBUG_SYSCALLS_ERROR
     86#if DEBUG_SYSCALLS_ERROR
    8587printk("\n[ERROR] in %s : too much children processes\n", __FUNCTION__);
    8688#endif
     
    9193
    9294    // Select target cluster for child process and main thread.
    93     // If placement is not user-defined, the placement is defined by the DQDT.
    94         if( parent_thread_ptr->fork_user )    // user defined placement
    95         {
    96         target_cxy = parent_thread_ptr->fork_cxy;
     95    // If placement is not user-defined, it is defined by the DQDT.
     96        if( parent_thread_ptr->fork_user )
     97        {
     98        child_cxy = parent_thread_ptr->fork_cxy;
    9799        parent_thread_ptr->fork_user = false;
    98100        }
    99101        else                                  // DQDT placement
    100102        {
    101                 target_cxy = dqdt_get_cluster_for_process();
    102         }
     103                child_cxy = dqdt_get_cluster_for_process();
     104        }
     105
     106#if( DEBUG_SYS_FORK & 1)
     107
     108// dqdt_display();
     109
     110if( local_cxy == 0 )
     111{
     112    sched_display( 0 );
     113    rpc_sched_display_client( 1 , 0 );
     114}
     115else
     116{
     117    sched_display( 0 );
     118    rpc_sched_display_client( 0 , 0 );
     119}
     120
     121if( DEBUG_SYS_FORK < tm_start )
     122printk("\n[DBG] %s : parent_thread %x selected cluster %x\n",
     123__FUNCTION__, parent_thread_ptr, child_cxy );
     124#endif
    103125
    104126    // call process_make_fork in target cluster
    105     if( target_cxy == local_cxy )
     127    if( child_cxy == local_cxy )
    106128    {
    107129        error = process_make_fork( ref_process_xp,
     
    112134    else
    113135    {
    114         rpc_process_make_fork_client( target_cxy,
     136        rpc_process_make_fork_client( child_cxy,
    115137                                      ref_process_xp,
    116138                                      parent_thread_xp,
     
    123145    {
    124146
    125 #if CONFIG_DEBUG_SYSCALLS_ERROR
     147#if DEBUG_SYSCALLS_ERROR
    126148printk("\n[ERROR] in %s : cannot fork process %x in cluster %x\n",
    127149__FUNCTION__, parent_pid, local_cxy );
     
    135157        if( CURRENT_THREAD->core->fpu_owner == parent_thread_ptr )
    136158        {
    137                 hal_fpu_context_save( XPTR( target_cxy , child_thread_ptr ) );
    138         }
    139 
    140     // set remote child CPU context from  parent_thread register values
    141     hal_cpu_context_fork( XPTR( target_cxy , child_thread_ptr ) );
    142 
    143     // From this point, both parent and child threads execute the following code.
    144     // They can be distinguished by the CURRENT_THREAD value, and child will only
    145     // execute it when it is unblocked by parent.
     159                hal_fpu_context_save( XPTR( child_cxy , child_thread_ptr ) );
     160        }
     161
     162    // set remote child CPU context from parent_thread register values
     163    hal_cpu_context_fork( XPTR( child_cxy , child_thread_ptr ) );
     164
     165    // From this point, both parent and child threads execute the following code,
     166    // but they can be distinguished by the (CURRENT_THREAD,local_cxy) values.
    146167    // - parent unblock child, and return child PID to user application.
    147168    // - child thread does nothing, and return 0 to user pplication
     169    // The child thread will only execute it when it is unblocked by parent thread.
    148170
    149171    thread_t * current = CURRENT_THREAD;
    150172
    151     if( current == parent_thread_ptr )    // current == parent thread
     173    if( (current == parent_thread_ptr) && (local_cxy == parent_cxy) )   // parent thread
    152174    {
    153175        // parent_thread unblock child_thread
    154         thread_unblock( XPTR( target_cxy , child_thread_ptr ) , THREAD_BLOCKED_GLOBAL );
    155 
    156 #if CONFIG_DEBUG_SYS_FORK
     176        thread_unblock( XPTR( child_cxy , child_thread_ptr ) , THREAD_BLOCKED_GLOBAL );
     177
     178#if DEBUG_SYS_FORK
    157179tm_end = hal_get_cycles();
    158 if( CONFIG_DEBUG_SYS_FORK < tm_end )
    159 printk("\n[DBG] %s : parent_thread %x exit / cost = %d / cycle %d\n",
    160 __FUNCTION__ , parent_thread_ptr, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end );
     180if( DEBUG_SYS_FORK < tm_end )
     181printk("\n[DBG] %s : parent_thread %x on cluster %x exit / cost = %d / cycle %d\n",
     182__FUNCTION__, parent_thread_ptr, parent_cxy, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end );
    161183#endif
    162184
    163185        return child_pid;
    164186    }
    165         else                                   // current == child_thread
    166     {
    167 
    168 #if CONFIG_DEBUG_SYS_FORK
     187        else                                                               // child_thread
     188    {
     189
     190#if DEBUG_SYS_FORK
    169191tm_end = hal_get_cycles();
    170 if( CONFIG_DEBUG_SYS_FORK < tm_end )
    171 printk("\n[DBG] %s : child_thread %x exit / cost = %d / cycle %d\n",
    172 __FUNCTION__ , child_thread_ptr, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end );
     192if( DEBUG_SYS_FORK < tm_end )
     193printk("\n[DBG] %s : child_thread %x on cluster %x exit / cost = %d / cycle %d\n",
     194__FUNCTION__, child_thread_ptr, child_cxy, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end );
    173195#endif
    174196
Note: See TracChangeset for help on using the changeset viewer.