Changeset 637 for trunk/kernel/kern


Ignore:
Timestamp:
Jul 18, 2019, 2:06:55 PM (5 years ago)
Author:
alain
Message:

Introduce the non-standard pthread_parallel_create() system call
and re-write the <fft> and <sort> applications to improve the
intrinsic paralelism in applications.

Location:
trunk/kernel/kern
Files:
10 edited

Legend:

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

    r635 r637  
    7676
    7777    // initialize the cluster_info[][] array
    78     for (x = 0; x < CONFIG_MAX_CLUSTERS_X; x++)
    79     {
    80         for (y = 0; y < CONFIG_MAX_CLUSTERS_Y;y++)
     78    for( x = 0 ; x < CONFIG_MAX_CLUSTERS_X ; x++ )
     79    {
     80        for( y = 0; y < CONFIG_MAX_CLUSTERS_Y ; y++ )
    8181        {
    8282            cluster->cluster_info[x][y] = info->cluster_info[x][y];
     
    9595    }
    9696
    97     // initialize number of cores
     97    // initialize number of local cores
    9898        cluster->cores_nr  = info->cores_nr;
    9999
    100100}  // end cluster_info_init()
     101
     102//////////////////////////////////////
     103void cluster_info_display( cxy_t cxy )
     104{
     105    uint32_t  x;
     106    uint32_t  y;
     107    uint32_t  ncores;
     108
     109    cluster_t * cluster = LOCAL_CLUSTER;
     110
     111    // get x_size & y_size from target cluster
     112    uint32_t  x_size = hal_remote_l32( XPTR( cxy , &cluster->x_size ) );
     113    uint32_t  y_size = hal_remote_l32( XPTR( cxy , &cluster->y_size ) );
     114
     115    // get pointers on TXT0 chdev
     116    xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
     117    cxy_t     txt0_cxy = GET_CXY( txt0_xp );
     118    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
     119
     120    // get extended pointer on remote TXT0 lock
     121    xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
     122
     123    // get TXT0 lock
     124    remote_busylock_acquire( lock_xp );
     125
     126    nolock_printk("\n***** cluster_info in cluster %x / x_size %d / y_size %d\n",
     127    cxy, x_size, y_size );
     128 
     129    for( x = 0 ; x < x_size ; x++ )
     130    {
     131        for( y = 0 ; y < y_size ; y++ )
     132        {
     133            ncores = (uint32_t)hal_remote_lb( XPTR( cxy , &cluster->cluster_info[x][y] ) );
     134            nolock_printk(" - ncores[%d][%d] = %d\n", x, y, ncores );
     135        }
     136    }
     137
     138    // release TXT0 lock
     139    remote_busylock_release( lock_xp );
     140
     141}  // end cluster_info_display()
    101142
    102143/////////////////////////////////////////////////////////
     
    115156printk("\n[%s] thread[%x,%x] enters for cluster %x / cycle %d\n",
    116157__FUNCTION__, this->process->pid, this->trdid, local_cxy , cycle );
     158#endif
     159
     160#if (DEBUG_CLUSTER_INIT & 1)
     161cluster_info_display( local_cxy );
    117162#endif
    118163
     
    243288}
    244289
    245 ////////////////////////////////////////
    246 bool_t cluster_is_undefined( cxy_t cxy )
    247 {
    248     uint32_t  x_size = LOCAL_CLUSTER->x_size;
    249     uint32_t  y_size = LOCAL_CLUSTER->y_size;
    250 
    251     uint32_t  x      = HAL_X_FROM_CXY( cxy );
    252     uint32_t  y      = HAL_Y_FROM_CXY( cxy );
    253 
    254     if( x >= x_size ) return true;
    255     if( y >= y_size ) return true;
    256 
    257     return false;
    258 }
    259 
    260 //////////////////////////////////////
    261 bool_t cluster_is_active ( cxy_t cxy )
     290/////////////////////////////////////////////
     291inline bool_t cluster_is_active ( cxy_t cxy )
    262292{
    263293    uint32_t x = HAL_X_FROM_CXY( cxy );
     
    271301////////////////////////////////////////////////////////////////////////////////////
    272302
    273 ///////////////////////////////////////
    274 lid_t cluster_select_local_core( void )
    275 {
    276     uint32_t      min = 1000;
     303/////////////////////////////////////////////
     304lid_t cluster_select_local_core( cxy_t  cxy )
     305{
     306    uint32_t      min = 1000000;
    277307    lid_t         sel = 0;
    278308    uint32_t      nthreads;
    279309    lid_t         lid;
    280310    scheduler_t * sched;
    281 
    282     cluster_t * cluster = LOCAL_CLUSTER;
    283 
    284     for( lid = 0 ; lid < cluster->cores_nr ; lid++ )
    285     {
    286         sched    = &cluster->core_tbl[lid].scheduler;
    287         nthreads = sched->u_threads_nr + sched->k_threads_nr;
     311    cluster_t   * cluster = LOCAL_CLUSTER;
     312    uint32_t      ncores = hal_remote_l32( XPTR( cxy , &cluster->cores_nr ) );
     313
     314    for( lid = 0 ; lid < ncores ; lid++ )
     315    {
     316        sched  = &cluster->core_tbl[lid].scheduler;
     317
     318        nthreads = hal_remote_l32( XPTR( cxy , &sched->u_threads_nr ) ) +
     319                   hal_remote_l32( XPTR( cxy , &sched->k_threads_nr ) );
    288320
    289321        if( nthreads < min )
     
    700732    uint32_t      pref_nr;       // number of owned processes in cluster cxy
    701733
    702 assert( (cluster_is_undefined( cxy ) == false), "illegal cluster index" );
     734assert( (cluster_is_active( cxy ) ), "illegal cluster index" );
    703735
    704736    // get extended pointer on root and lock for local process list in cluster
  • trunk/kernel/kern/cluster.h

    r635 r637  
    44 * authors  Ghassan Almaless (2008,2009,2010,2011,2012)
    55 *          Mohamed Lamine Karaoui (2015)
    6  *          Alain Greiner (2016,2017,2018)
     6 *          Alain Greiner (2016,2017,2018,2019)
    77 *
    88 * Copyright (c) UPMC Sorbonne Universites
     
    112112    uint32_t        nb_fbf_channels;   /*! number of FBF channels                         */
    113113
    114     char            cluster_info[CONFIG_MAX_CLUSTERS_X][CONFIG_MAX_CLUSTERS_Y];
     114    // number of cores for each cluster in the mesh
     115    uint8_t         cluster_info[CONFIG_MAX_CLUSTERS_X][CONFIG_MAX_CLUSTERS_Y];
    115116
    116117    // local parameters
     
    162163 * in the local boot-info structure <info> build by the boot-loader.
    163164 * 1) the cluster_info_init() function is called first, to initialize the structural
    164  *    constants, and cannot use the TXT0 kernel terminal.
    165  * 2) the cluster_manager_init() function initialize various complex structures:
     165 *    constants, including the cluster_info[x][y] array.
     166 *    It cannot use the TXT0 kernel terminal.
     167 * 2) the cluster_manager_init() function initializes various complex structures:
    166168 *    - the local DQDT nodes,
    167169 *    - the PPM, KHM, and KCM allocators,
     
    169171 *    - the local RPC FIFO,
    170172 *    - the process manager.
    171  *    It does NOT initialise the local device descriptors.
    172173 *    It can use the TXT0 kernel terminal.
    173174 ******************************************************************************************
     
    178179
    179180/******************************************************************************************
    180  * This function checks the validity of a cluster identifier.
    181  ******************************************************************************************
    182  * @ cxy    : cluster identifier to be checked.
    183  * @ returns true if the identified cluster does not exist.
    184  *****************************************************************************************/
    185 bool_t cluster_is_undefined( cxy_t cxy );
    186 
    187 /******************************************************************************************
    188  * This function uses the local cluster_info[][] array in cluster descriptor,
    189  * and returns true when the cluster identified by the <cxy> argument is active.
    190  ******************************************************************************************
    191  * @ cxy   : cluster identifier.
     181 * This debug function displays the current values stored in the cluster_info[][] array
     182 * of a remote cluster identified by the <cxy> argument.
     183 * It can be called by a thread running in any cluster.
     184 ******************************************************************************************
     185 * @ cxy   : remote cluster identifier.
     186 *****************************************************************************************/
     187void cluster_info_display( cxy_t  cxy );
     188
     189/******************************************************************************************
     190 * This function access the local cluster_info[][] array and returns true when the
     191 * cluster identified by the <cxy> argument is active (contains a kernel instance).
     192 ******************************************************************************************
     193 * @ cxy   : checked cluster identifier.
    192194 * @ return true if cluster contains a kernel instance.
    193195 *****************************************************************************************/
     
    300302 * This function displays on the kernel terminal TXT0 all user processes registered
    301303 * in the cluster defined by the <cxy> argument.
    302  * It can be called by a thread running in any cluster, because is use remote accesses
    303  * to scan the xlist of registered processes.
     304 * It can be called by a thread running in any cluster.
    304305 ******************************************************************************************
    305306 * @ cxy   : cluster identifier.
     
    310311
    311312/******************************************************************************************
    312  * This function uses the local boot_inforeturns the core local index that has the lowest usage in local cluster.
    313  *****************************************************************************************/
    314 lid_t cluster_select_local_core( void );
     313 * This function selects the core that has the lowest usage in a - possibly remote -
     314 * cluster identified by the <cxy> argument.
     315 * It can be called by a thread running in any cluster.
     316 ******************************************************************************************
     317 * @ cxy    : target cluster identifier.
     318 * @ return the selected core local index.
     319 *****************************************************************************************/
     320lid_t cluster_select_local_core( cxy_t  cxy );
    315321
    316322             
  • trunk/kernel/kern/do_syscall.c

    r626 r637  
    9595
    9696    sys_get_config,         // 40
    97     sys_get_core,           // 41
     97    sys_get_core_id,        // 41
    9898    sys_get_cycle,          // 42
    9999    sys_display,            // 43
     
    108108    sys_sync,               // 51
    109109    sys_fsync,              // 52
     110    sys_get_best_core,      // 53
     111    sys_get_nb_cores,       // 54
    110112};
    111113
     
    160162
    161163    case SYS_GET_CONFIG:                   return "GET_CONFIG";       // 40
    162     case SYS_GET_CORE:                     return "GET_CORE";         // 41
     164    case SYS_GET_CORE_ID:                  return "GET_CORE_ID";      // 41
    163165    case SYS_GET_CYCLE:                    return "GET_CYCLE";        // 42
    164166    case SYS_DISPLAY:                      return "DISPLAY";          // 43
     
    172174    case SYS_EXIT:                         return "EXIT";             // 50
    173175    case SYS_SYNC:                         return "SYNC";             // 51
    174     case SYS_FSYNC:                        return "FSYNc";            // 52
     176    case SYS_FSYNC:                        return "FSYNC";            // 52
     177    case SYS_GET_BEST_CORE:                return "GET_BEST_CORE";    // 53
     178    case SYS_GET_NB_CORES:                 return "GET_NB_CORES";     // 54
    175179
    176180    default:                               return "undefined";
  • trunk/kernel/kern/dqdt.c

    r632 r637  
    22 * dqdt.c - Distributed Quaternary Decision Tree implementation.
    33 *
    4  * Author : Alain Greiner (2016,2017,2018)
     4 * Author : Alain Greiner (2016,2017,2018,2019)
    55 *
    66 * Copyright (c)  UPMC Sorbonne Universites
     
    5555
    5656    // display node content
    57         nolock_printk("- level %d / cluster %x : threads = %x / pages = %x / clusters %d / cores %d\n",
    58     node.level, GET_CXY( node_xp ), node.threads, node.pages, node.clusters, node.cores );
     57        nolock_printk("- [%d,%x] : threads %x / pages %x / clusters %d / cores %d / parent_cxy %x\n",
     58                  node.level, GET_CXY( node_xp ),
     59                  node.threads, node.pages,
     60                  node.clusters, node.cores,
     61                  GET_CXY( node.parent ) );
    5962
    6063    // recursive call on children if node is not terminal
     
    116119                                  xptr_t   parent_xp )
    117120{
    118     assert( (level < 5) , __FUNCTION__, "illegal DQDT level %d\n", level );
     121    assert( (level <= 5) , __FUNCTION__, "illegal DQDT level %d\n", level );
    119122 
    120123    uint32_t node_x;         // node X coordinate
     
    147150
    148151#if DEBUG_DQDT_INIT
    149 printk("\n[DBG] %s : cxy(%d,%d) / level %d / mask %x / half %d / ptr %x\n",
     152printk("\n[%s] thread[%x,%x] : cxy(%d,%d) / level %d / mask %x / half %d / ptr %x\n",
    150153__FUNCTION__, node_x, node_y, level, mask, half, node_ptr );
    151154#endif
     
    336339void dqdt_init( void )
    337340{
    338     // get x_size & y_size from cluster manager
    339     cluster_t * cluster = &cluster_manager;
     341    // get x_size & y_size
     342    cluster_t * cluster = LOCAL_CLUSTER;
    340343    uint32_t    x_size  = cluster->x_size;
    341344    uint32_t    y_size  = cluster->y_size;
     
    349352    uint32_t  level_max  = bits_log2( size_ext );
    350353
    351     // each CP0 register the DQDT root in local cluster manager
     354    // all CP0s register the DQDT root in local cluster manager
    352355    cluster->dqdt_root_xp = XPTR( 0 , &cluster->dqdt_tbl[level_max] );
    353356
     357    // only CP0 in cluster 0 build the DQDT
     358    if( local_cxy == 0 )
     359    {
     360
    354361#if DEBUG_DQDT_INIT
    355 if( local_cxy == 0 )
    356 printk("\n[DBG] %s : x_size = %d / y_size = %d / level_max = %d\n",
    357 __FUNCTION__, x_size, y_size, level_max );
     362thread_t * this = CURRENT_THREAD;
     363printk("\n[%s] thread[%x,%x] enters : x_size = %d / y_size = %d / level_max = %d\n",
     364__FUNCTION__, this->process->pid, this->trdid, x_size, y_size, level_max );
    358365#endif
    359366   
     
    362369
    363370#if DEBUG_DQDT_INIT
    364 if( local_cxy == 0 ) dqdt_display();
    365 #endif
    366 
     371dqdt_display();
     372#endif
     373
     374    }
    367375}  // end dqdt_init()
    368376
     
    516524}
    517525
     526///////////////////////////////////
     527xptr_t dqdt_get_root( cxy_t    cxy,
     528                      uint32_t level )
     529{
     530    xptr_t        node_xp;
     531    cxy_t         node_cxy;
     532    dqdt_node_t * node_ptr;
     533    uint32_t      current_level;
     534
     535assert( (level <= 5) , __FUNCTION__, "illegal DQDT level %d\n", level );
     536
     537#if DEBUG_DQDT_GET_ROOT
     538thread_t * this = CURRENT_THREAD;
     539printk("\n[%s] thread[%x,%x] enters / cxy %x / level %d\n",
     540__FUNCTION__, this->process->pid, this->trdid, cxy, level );
     541#endif
     542
     543    // check macro-cluster
     544    if( cluster_is_active( cxy ) )
     545    {   
     546        // initialise node_xp and current_level
     547        node_xp       = XPTR( cxy , &LOCAL_CLUSTER->dqdt_tbl[0] );
     548        current_level = 0;
     549
     550        // traverse the quad-tree from bottom to root
     551        while( current_level < level )
     552        {
     553            node_cxy = GET_CXY( node_xp );
     554            node_ptr = GET_PTR( node_xp );
     555
     556            node_xp = hal_remote_l64( XPTR( node_cxy , &node_ptr->parent ) );
     557            current_level++;
     558        }
     559    }
     560    else
     561    {
     562        node_xp =  XPTR_NULL;
     563    }
     564
     565#if DEBUG_DQDT_GET_ROOT
     566printk("\n[%s] thread[%x,%x] exit / root_xp[%x,%x]\n",
     567__FUNCTION__, this->process->pid, this->trdid, GET_CXY( node_xp ), GET_PTR( node_xp ) );
     568#endif
     569
     570    return node_xp;
     571   
     572}
    518573
    519574/////////////////////////////////////////////////////////////////////////////////////
     
    584639
    585640
    586 //////////////////////////////////////////
    587 cxy_t dqdt_get_cluster_for_process( void )
     641///////////////////////////////////////////////////
     642cxy_t dqdt_get_cluster_for_thread( xptr_t root_xp )
    588643{
    589644    // call recursive function
    590     cxy_t cxy = dqdt_select_cluster( LOCAL_CLUSTER->dqdt_root_xp , false );
    591 
    592 #if DEBUG_DQDT_SELECT_FOR_PROCESS
     645    cxy_t cxy = dqdt_select_cluster( root_xp , false );
     646
     647#if DEBUG_DQDT_SELECT_FOR_THREAD
    593648uint32_t cycle = hal_get_cycles();
    594649if( cycle > DEBUG_DQDT_SELECT_FOR_PROCESS )
     
    600655}
    601656
    602 /////////////////////////////////////////
    603 cxy_t dqdt_get_cluster_for_memory( void )
     657///////////////////////////////////////////////////
     658cxy_t dqdt_get_cluster_for_memory( xptr_t root_xp )
    604659{
    605660    // call recursive function
    606     cxy_t cxy = dqdt_select_cluster( LOCAL_CLUSTER->dqdt_root_xp , true );
     661    cxy_t cxy = dqdt_select_cluster( root_xp , true );
    607662
    608663#if DEBUG_DQDT_SELECT_FOR_MEMORY
  • trunk/kernel/kern/dqdt.h

    r632 r637  
    22 * kern/dqdt.h - Distributed Quad Decision Tree
    33 *
    4  * Author : Alain Greiner (2016,2017,2018)
     4 * Author : Alain Greiner (2016,2017,2018,2019)
    55 *
    66 * Copyright (c)  UPMC Sorbonne Universites
     
    3131/****************************************************************************************
    3232 * This DQDT infrastructure maintains a topological description of ressources usage
    33  * in each cluster: number of threads, and number of physical pages allocated.
     33 * in each cluster: number of threads per core, and number of physical pages allocated.
    3434 *
    35  * - If X_SIZE or Y_SIZE are equal to 1, it makes the assumption that the cluster
    36  *   topology is a one dimensionnal vector, an build the smallest one-dimensionnal
    37  *   quad-tree covering this one-dimensionnal vector. If the number of clusters
    38  *   is not a power of 4, the tree is truncated as required.
    39  *
    40  *   TODO : the mapping for the one dimensionnal topology is not implemented yet [AG].
    41  *
    42  * - If both Y_SIZE and Y_SIZE are larger than 1, it makes the assumption that
    43  *   the clusters topology is a 2D mesh. The [X,Y] coordinates of a cluster are
    44  *   obtained from the CXY identifier using the Rrelevant macros.
    45  *      X = CXY >> Y_WIDTH   /  Y = CXY & ((1<<Y_WIDTH)-1)
    46  * - If the mesh X_SIZE and Y_SIZE dimensions are not equal, or are not power of 2,
    47  *   or the mesh contains "holes" reported in the cluster_info[x][y] array,
    48  *   we build the smallest two dimensionnal quad-tree covering all clusters,
    49  *   and this tree is truncated as required.
    50  * - The mesh size is supposed to contain at most 32 * 32 clusters.
    51  *   Therefore, it can exist at most 6 DQDT nodes in a given cluster:
    52  *   . Level 0 nodes exist on all clusters and have no children.
    53  *   . Level 1 nodes exist when both X and Y coordinates are multiple of 2
    54  *   . Level 2 nodes exist when both X and Y coordinates are multiple of 4
    55  *   . Level 3 nodes exist when both X and Y coordinates are multiple of 8
    56  *   . Level 4 nodes exist when both X and Y coordinates are multiple of 16
    57  *   . Level 5 nodes exist when both X and Y coordinates are multiple of 32
    58  * - For nodes other than level 0, the placement is defined as follow:
    59  *   . The root node is placed in the cluster containing the core executing
    60  *     the dqdt_init() function.
    61  *   . An intermediate node (representing a given sub-tree) is placed in one
    62  *     cluster covered by the subtree, pseudo-randomly selected.
     35 * It is organized as a quad-tree, where the leaf cells are the clusters, organised
     36 * as a 2D mesh. Each node in the quad-tree (including the root and the leaf cells,
     37 * covers a "macro-cluster", that is a square array of clusters where the number
     38 * in the macro-cluster is a power of 4, and the macro-cluster side is a power of two.
     39 * Each node contains informations on ressources usage (physical memory and cores)
     40 * in the covered macro-cluster.
     41 * This quad-tree can be truncated, if the physical mesh X_SIZE and Y_SIZE dimensions
     42 * are not equal, or are not power of 2, or if the physical mesh contains "holes".
     43 * The mesh size is supposed to contain at most 32*32 clusters in this implementation.
     44 *   . Level 0 nodes exist in all clusters and have no children.
     45 *   . Level 1 nodes can be placed in any cluster of the covered  2*2  macro-cluster.
     46 *   . Level 2 nodes can be placed in any cluster of the covered  4*4  macro-cluster.
     47 *   . Level 3 nodes can be placed in any cluster of the covered  8*8  macro-cluster.
     48 *   . Level 4 nodes can be placed in any cluster of the covered 16*16 macro-cluster.
     49 *   . Level 5 nodes can be placed in any cluster of the covered 32*32 macro-cluster.
     50 * The root node is placed in the cluster containing the core executing the dqdt_init()
     51 * function. Other (non level 0) nodes are placed pseudo-randomly.
    6352 ***************************************************************************************/
    6453
     
    6655 * This structure describes a node of the DQDT.
    6756 * The max number of children is 4, but it can be smaller for some nodes.
    68  * Level 0 nodes are the clusters, and have no children.
    69  * The root node has no parent.
     57 * Level 0 nodes have no children. The root node has no parent.
    7058 ***************************************************************************************/
    7159
     
    7462        uint32_t      level;            /*! node level                                     */
    7563        uint32_t      arity;            /*! actual children number in this node            */
    76     uint32_t      threads;          /*! current number of threads in macro-cluster     */
    77     uint32_t      pages;            /*! current number of pages in macro-cluster       */
     64    uint32_t      threads;          /*! number of threads in macro-cluster             */
     65    uint32_t      pages;            /*! number of allocated pages in macro-cluster     */
    7866    uint32_t      cores;            /*! number of active cores in macro cluster        */
    79     uint32_t      clusters;         /*! number of active cluster in macro cluster      */
     67    uint32_t      clusters;         /*! number of active clusters in macro cluster     */
    8068        xptr_t        parent;           /*! extended pointer on parent node                */
    8169        xptr_t        children[2][2];   /*! extended pointers on children nodes            */
     
    8775 * This function recursively initializes the DQDT structure from informations
    8876 * stored in cluster manager (x_size, y_size and cluster_info[x][y].
    89  * It is executed in all clusters by the local CP0, to compute level_max and register
     77 * It is called in all clusters by the local CP0, to compute level_max and register
    9078 * the DQDT root node in each cluster manager, but only CPO in cluster 0 build actually
    9179 * the quad-tree covering all active clusters.
     
    10290 ***************************************************************************************/
    10391void dqdt_increment_threads( void );
     92
    10493void dqdt_decrement_threads( void );
    10594
     
    121110
    122111/****************************************************************************************
    123  * This function can be called in any cluster. It traverses the DQDT tree
    124  * from the root to the bottom, to analyse the computing load and select the cluster
    125  * with the lowest number ot threads to place a new process.
     112 * This function returns an extended pointer on the dqdt node that is the root of
     113 * the sub-tree covering the macro-cluster defined by the <level> argument and
     114 * containing the cluster defined by the <cxy> argument. It returns XPTR_NULL if
     115 * this macro-cluster is undefined (when the cxy cluster contains no core).
    126116 ****************************************************************************************
     117 * @ cxy   : cluster identifier.
     118 * @ level   : level of the sub-tree.
     119 * @ returns  root_xp if success / return XPTR_NULL if no active core in macro_cluster.
     120 ***************************************************************************************/
     121xptr_t dqdt_get_root( cxy_t    cxy,
     122                      uint32_t level );
     123
     124/****************************************************************************************
     125 * This function can be called in any cluster. It traverses the DQDT tree from the
     126 * local root of a macro-cluster, defined by the <root_xp> argument, to the bottom.
     127 * It analyses the computing load & select the cluster containing the lowest number
     128 * ot threads.
     129 ****************************************************************************************
     130 * @ root_xp  : extended pointer on DQDT node root.
    127131 * @ returns the cluster identifier with the lowest computing load.
    128132 ***************************************************************************************/
    129 cxy_t dqdt_get_cluster_for_process( void );
     133cxy_t dqdt_get_cluster_for_thread( xptr_t root_xp );
    130134
    131135/****************************************************************************************
    132  * This function can be called in any cluster. It traverses the DQDT tree
    133  * from the root to the bottom, to analyse the memory load and select the cluster
    134  * with the lowest memory load for dynamic memory allocation with no locality constraint.
     136 * This function can be called in any cluster. It traverses the DQDT tree from the
     137 * local root of a macro-cluster, defined by the <root_xp> argument, to the bottom.
     138 * It analyses the memory load & select the cluster with the lowest number of allocated
     139 * physical pages.
    135140 ****************************************************************************************
     141 * @ root_xp  : extended pointer on DQDT node root.
    136142 * @ returns the cluster identifier with the lowest memory load.
    137143 ***************************************************************************************/
    138 cxy_t dqdt_get_cluster_for_memory( void );
     144cxy_t dqdt_get_cluster_for_memory( xptr_t root_xp );
    139145
    140146/****************************************************************************************
    141147 * This function displays on kernel TXT0 the DQDT state for all nodes in the quad-tree.
    142  * It traverses the quadtree from root to bottom, and can be called by a thread
    143  * running in any cluster
     148 * It traverses the quadtree from the global root to bottom.
     149 * It can be called by a thread running in any cluster
    144150 ***************************************************************************************/
    145151void dqdt_display( void );
  • trunk/kernel/kern/kernel_init.c

    r635 r637  
    10081008
    10091009    /////////////////////////////////////////////////////////////////////////////////
    1010     // STEP 2 : core[0] initializes the cluter manager,
    1011     //          including the physical memory allocator.
     1010    // STEP 2 : core[0] initializes the cluster manager,
     1011    //          including the physical memory allocators.
    10121012    /////////////////////////////////////////////////////////////////////////////////
    10131013
     
    11021102
    11031103    ////////////////////////////////////////////////////////////////////////////////
    1104     // STEP 5 : core[0] initializes the distibuted LAPIC descriptor.
    1105     //          core[0] initializes the internal chdev descriptors
     1104    // STEP 5 : core[0] initialize the distibuted LAPIC descriptor.
     1105    //          core[0] initialize the internal chdev descriptors
    11061106    //          core[0] initialize the local external chdev descriptors
    11071107    ////////////////////////////////////////////////////////////////////////////////
  • trunk/kernel/kern/process.c

    r635 r637  
    19091909
    19101910    // select a core in local cluster to execute the main thread
    1911     lid  = cluster_select_local_core();
     1911    lid  = cluster_select_local_core( local_cxy );
    19121912
    19131913    // initialize pthread attributes for main thread
  • trunk/kernel/kern/rpc.c

    r635 r637  
    10531053
    10541054    // select one core
    1055     core_lid = cluster_select_local_core();
     1055    core_lid = cluster_select_local_core( local_cxy );
    10561056
    10571057    // call local kernel function
  • trunk/kernel/kern/scheduler.h

    r564 r637  
    4141{
    4242    busylock_t        lock;            /*! lock protecting scheduler state                  */
    43     uint16_t          u_threads_nr;    /*! total number of attached user threads            */
    44     uint16_t          k_threads_nr;    /*! total number of attached kernel threads          */
     43    uint32_t          u_threads_nr;    /*! total number of attached user threads            */
     44    uint32_t          k_threads_nr;    /*! total number of attached kernel threads          */
    4545    list_entry_t      u_root;          /*! root of list of user threads                     */
    4646    list_entry_t      k_root;          /*! root of list of kernel threads                   */
  • trunk/kernel/kern/thread.c

    r635 r637  
    247247    else
    248248    {
    249         core_lid = cluster_select_local_core();
     249        core_lid = cluster_select_local_core( local_cxy );
    250250    }
    251251
     
    375375printk("\n[%s] CPU & FPU contexts created\n",
    376376__FUNCTION__, thread->trdid );
    377 hal_vmm_display( process , true );
     377hal_vmm_display( XPTR( local_cxy , process ) , true );
    378378#endif
    379379
     
    418418
    419419    // select a target core in local cluster
    420     core_lid = cluster_select_local_core();
     420    core_lid = cluster_select_local_core( local_cxy );
    421421
    422422#if (DEBUG_THREAD_USER_FORK & 1)
     
    724724printk("\n[%s] thread[%x,%x] set CPU context & jump to user code / cycle %d\n",
    725725__FUNCTION__, process->pid, thread->trdid, cycle );
    726 hal_vmm_display( process , true );
     726hal_vmm_display( XPTR( local_cxy , process ) , true );
    727727#endif
    728728
     
    13321332    // check trdid argument
    13331333        if( (target_thread_ltid >= CONFIG_THREADS_MAX_PER_CLUSTER) ||
    1334         cluster_is_undefined( target_cxy ) )         return XPTR_NULL;
     1334        cluster_is_active( target_cxy ) == false )                return XPTR_NULL;
    13351335
    13361336    // get root of list of process descriptors in target cluster
Note: See TracChangeset for help on using the changeset viewer.