Changeset 19
- Timestamp:
- Jun 3, 2017, 4:46:59 PM (7 years ago)
- Location:
- trunk/kernel/kern
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/cluster.c
r14 r19 1 1 /* 2 2 * cluster.c - Cluster-Manager related operations 3 * 3 * 4 4 * Author Ghassan Almaless (2008,2009,2010,2011,2012) 5 5 * Mohamed Lamine Karaoui (2015) … … 68 68 69 69 // initialize cluster global parameters 70 cluster->paddr_width = info->paddr_width; 70 cluster->paddr_width = info->paddr_width; 71 71 cluster->x_width = info->x_width; 72 72 cluster->y_width = info->y_width; … … 77 77 // initialize cluster local parameters 78 78 cluster->cores_nr = info->cores_nr; 79 cluster->cores_in_kernel = info->cores_nr; 80 81 // initialize the lock protecti g the embedded kcm allocator79 cluster->cores_in_kernel = info->cores_nr; // all cpus start in kernel mode 80 81 // initialize the lock protecting the embedded kcm allocator 82 82 spinlock_init( &cluster->kcm_lock ); 83 83 84 // initialises DQDT 85 cluster->dqdt_root_level = dqdt_init( info->x_size, 86 info->y_size, 84 // initialises DQDT 85 cluster->dqdt_root_level = dqdt_init( info->x_size, 86 info->y_size, 87 87 info->y_width ); 88 88 cluster->threads_var = 0; … … 96 96 // initialises embedded KHM 97 97 khm_init( &cluster->khm ); 98 99 // initialises embedded KCM 98 99 // initialises embedded KCM 100 100 kcm_init( &cluster->kcm , KMEM_KCM ); 101 101 … … 107 107 info->core[lid].gid ); // gid from boot_info_t 108 108 } 109 109 110 110 // initialises RPC fifo 111 111 rpc_fifo_init( &cluster->rpc_fifo ); … … 114 114 spinlock_init( &cluster->pmgr.pref_lock ); 115 115 cluster->pmgr.pref_nr = 0; 116 cluster->pmgr.pref_tbl[0] = XPTR( local_cxy , &process_zero ); 116 cluster->pmgr.pref_tbl[0] = XPTR( local_cxy , &process_zero ); 117 117 for( lpid = 1 ; lpid < CONFIG_MAX_PROCESS_PER_CLUSTER ; lpid++ ) 118 118 { … … 131 131 cluster->pmgr.copies_nr[lpid] = 0; 132 132 xlist_root_init( XPTR( local_cxy , &cluster->pmgr.copies_root[lpid] ) ); 133 } 133 } 134 134 135 135 hal_wbflush(); … … 148 148 uint32_t y = cxy & ((1<<y_width)-1); 149 149 150 if( x >= cluster->x_size ) return true; 151 if( y >= cluster->y_size ) return true; 150 if( x >= cluster->x_size ) return true; 151 if( y >= cluster->y_size ) return true; 152 152 153 153 return false; … … 188 188 sel = lid; 189 189 } 190 } 190 } 191 191 return sel; 192 192 } … … 198 198 ////////////////////////////////////////////////////////// 199 199 xptr_t cluster_get_reference_process_from_pid( pid_t pid ) 200 { 200 { 201 201 xptr_t xp; // extended pointer on process descriptor 202 202 … … 207 207 lpid_t lpid = LPID_FROM_PID( pid ); 208 208 209 // Check valid PID 209 // Check valid PID 210 210 if( lpid >= CONFIG_MAX_PROCESS_PER_CLUSTER ) 211 211 { … … 215 215 216 216 if( local_cxy == owner_cxy ) // local cluster is owner cluster 217 { 217 { 218 218 xp = cluster->pmgr.pref_tbl[lpid]; 219 219 } … … 264 264 { 265 265 error = EAGAIN; 266 } 266 } 267 267 268 268 // release the processs_manager lock … … 307 307 list_entry_t * iter; 308 308 process_t * process; 309 309 310 310 LIST_FOREACH( root , iter ) 311 311 { … … 370 370 xptr_t copies_entry = XPTR( local_cxy , &process->copies_list ); 371 371 372 // get lock protecting copies_list[lpid] 372 // get lock protecting copies_list[lpid] 373 373 remote_spinlock_lock( copies_lock ); 374 374 … … 376 376 hal_remote_atomic_add( XPTR( owner_cxy , &pm->copies_nr[lpid] ) , 1 ); 377 377 378 // release lock protecting copies_list[lpid] 378 // release lock protecting copies_list[lpid] 379 379 remote_spinlock_unlock( copies_lock ); 380 380 } … … 396 396 xptr_t copies_entry = XPTR( local_cxy , &process->copies_list ); 397 397 398 // get lock protecting copies_list[lpid] 398 // get lock protecting copies_list[lpid] 399 399 remote_spinlock_lock( copies_lock ); 400 400 … … 402 402 hal_remote_atomic_add( XPTR( owner_cxy , &pm->copies_nr[lpid] ) , -1 ); 403 403 404 // release lock protecting copies_list[lpid] 404 // release lock protecting copies_list[lpid] 405 405 remote_spinlock_unlock( copies_lock ); 406 406 } … … 408 408 //////////////////////////////////////////////////////////////////////////////////////// 409 409 // TODO Il me semble que la seule chose que fait ce kernel thread à chaque réveil 410 // est de mettre à jour la DQDT, et de se rendormir... A-t-on besoin d'un thread ? [AG] 410 // est de mettre à jour la DQDT, et de se rendormir... A-t-on besoin d'un thread ? [AG] 411 411 ////////////////////////////////////////////////////////////////////////////////////////// 412 412 … … 437 437 isRootMgr = (cluster == root_home) ? true : false; 438 438 cntr = 0; 439 period = (isRootMgr) ? 440 CONFIG_DQDT_ROOTMGR_PERIOD * MSEC_PER_TICK : 439 period = (isRootMgr) ? 440 CONFIG_DQDT_ROOTMGR_PERIOD * MSEC_PER_TICK : 441 441 CONFIG_DQDT_MGR_PERIOD * MSEC_PER_TICK; 442 442 … … 444 444 event_set_priority(&event, E_CHR); 445 445 event_set_handler(&event, &manager_alarm_event_handler); 446 446 447 447 info.event = &event; 448 448 thread_preempt_disable(CURRENT_THREAD); … … 459 459 if((cntr % 10) == 0) 460 460 { 461 printk(INFO, "INFO: cpu %d, DQDT update ended [ %u - %u ]\n", 462 cpu_id, 463 tm_end, 461 printk(INFO, "INFO: cpu %d, DQDT update ended [ %u - %u ]\n", 462 cpu_id, 463 tm_end, 464 464 tm_end - tm_start); 465 465 … … 480 480 { 481 481 struct thread_s *manager; 482 482 483 483 manager = event_get_senderId(event); 484 484 485 485 thread_preempt_disable(CURRENT_THREAD); 486 486 … … 488 488 489 489 sched_wakeup(manager); 490 490 491 491 thread_preempt_enable(CURRENT_THREAD); 492 492 … … 513 513 { 514 514 ckey->val = key; 515 cluster->keys_tbl[key] = (void *) 0x1; // Reserved 515 cluster->keys_tbl[key] = (void *) 0x1; // Reserved 516 516 cluster->next_key = key; 517 517 event_set_error(event, 0); -
trunk/kernel/kern/cluster.h
r14 r19 1 1 /* 2 2 * cluster.h - Cluster-Manager definition 3 * 3 * 4 4 * authors Ghassan Almaless (2008,2009,2010,2011,2012) 5 5 * Mohamed Lamine Karaoui (2015) … … 55 55 * This structure defines the process manager, that is part of the cluster manager. 56 56 * For any process P, the process descriptor is replicated in all clusters containing 57 * at least one thread of process P, but only the "reference" cluster descriptor contains 57 * at least one thread of process P, but only the "reference" cluster descriptor contains 58 58 * the reference (complete) structures such as the GPT, the VSL, or the FDT. 59 * The "owner" cluster is in charge to allocate a lpid (local process index), 59 * The "owner" cluster is in charge to allocate a lpid (local process index), 60 60 * for all process owned by a cluster K, and to register the "reference" cluster for 61 * all process owned by K. 62 * 63 * Warning : the "owner" cluster, and the "reference" cluster can be different clusters. 61 * all process owned by K. 62 * 63 * Warning : the "owner" cluster, and the "reference" cluster can be different clusters. 64 64 * 65 65 * The process manager of a cluster K maintains three structures: … … 69 69 * A process descriptor P is present in K, as soon as P has a thread in cluster K. 70 70 * 3) The copies_root[] array is indexed by lpid. Each entry contains the root of 71 * the xlist of copies for a given process owned by cluster K. 71 * the xlist of copies for a given process owned by cluster K. 72 72 ******************************************************************************************/ 73 73 … … 82 82 uint32_t local_nr; /*! number of process in cluster */ 83 83 84 xlist_entry_t copies_root[CONFIG_MAX_PROCESS_PER_CLUSTER]; /*! roots of lists */ 84 xlist_entry_t copies_root[CONFIG_MAX_PROCESS_PER_CLUSTER]; /*! roots of lists */ 85 85 remote_spinlock_t copies_lock[CONFIG_MAX_PROCESS_PER_CLUSTER]; /*! one lock per list */ 86 86 uint32_t copies_nr[CONFIG_MAX_PROCESS_PER_CLUSTER]; /*! number of copies */ … … 90 90 /******************************************************************************************* 91 91 * This structure defines a cluster manager. 92 * It contains both global platform information s, and cluster specific ressources92 * It contains both global platform information, and cluster specific resources 93 93 * managed by the local kernel instance. 94 94 ******************************************************************************************/ … … 135 135 pmgr_t pmgr; /*! embedded process manager */ 136 136 137 char name[CONFIG_SYSFS_NAME_LEN]; 137 char name[CONFIG_SYSFS_NAME_LEN]; 138 138 139 139 // sysfs_entry_t node; 140 } 140 } 141 141 cluster_t; 142 142 143 143 /****************************************************************************************** 144 144 * This global variable is allocated in the kernel_init.c file. 145 * There is one cluster_manager per cluster, with the same local address, 146 * but different content, in all clusters containing a kernel instance. 145 * There is one cluster_manager per cluster, with the same local address, 146 * but different content, in all clusters containing a kernel instance. 147 147 *****************************************************************************************/ 148 148 … … 156 156 157 157 /****************************************************************************************** 158 * This generic function initialises the local cluster manager from information sfound158 * This generic function initialises the local cluster manager from information found 159 159 * in the local boot-info structure. It initializes the following local resources: 160 160 * - the global platform parameters, … … 170 170 * @ info : pointer on the local boot_info_t structure build by the bootloader. 171 171 *****************************************************************************************/ 172 error_t cluster_init( boot_info_t * info ); 173 174 /****************************************************************************************** 175 * This function che ks the validity of a cluster identifier. TODO useful ??? [AG]172 error_t cluster_init( boot_info_t * info ); 173 174 /****************************************************************************************** 175 * This function checks the validity of a cluster identifier. TODO useful ??? [AG] 176 176 ****************************************************************************************** 177 177 * @ cxy : cluster identifier to be checked. … … 200 200 xptr_t cluster_get_reference_process_from_pid( pid_t pid ); 201 201 202 /****************************************************************************************** 202 /****************************************************************************************** 203 203 * This function allocates a new PID in local cluster, that becomes the process owner. 204 * It register the process descriptor extended pointer in the local processs manager204 * It registers the process descriptor extended pointer in the local processs manager 205 205 * pref_tbl[] array. This function is called by the rpc_process_alloc_pid() function for 206 206 * remote registration, or by the process_init_create() function for local registration. … … 208 208 * @ process : [in] extended pointer on the process descriptor. 209 209 * @ pid : [out] allocated PID. 210 * @ return 0 if success / return EAGAIN if no PID slot available 210 * @ return 0 if success / return EAGAIN if no PID slot available 211 211 *****************************************************************************************/ 212 212 error_t cluster_pid_alloc( xptr_t process_xp, 213 213 pid_t * pid ); 214 214 215 /****************************************************************************************** 215 /****************************************************************************************** 216 216 * This function removes a PID from the local process manager pref_tbl[] array. 217 217 * It checks that removed process is owned by the local cluster and the lpid is legal. … … 237 237 * @ process : pointer on local process descriptor. 238 238 *****************************************************************************************/ 239 void cluster_process_local_link( struct process_s * process ); 239 void cluster_process_local_link( struct process_s * process ); 240 240 241 241 /****************************************************************************************** … … 244 244 * @ process : pointer on local process descriptor. 245 245 *****************************************************************************************/ 246 void cluster_process_local_unlink( struct process_s * process ); 246 void cluster_process_local_unlink( struct process_s * process ); 247 247 248 248 /****************************************************************************************** … … 252 252 * @ process : pointer on local process descriptor. 253 253 *****************************************************************************************/ 254 void cluster_process_copies_link( struct process_s * process ); 254 void cluster_process_copies_link( struct process_s * process ); 255 255 256 256 /****************************************************************************************** … … 260 260 * @ process : pointer on local process descriptor. 261 261 *****************************************************************************************/ 262 void cluster_process_copies_unlink( struct process_s * process ); 262 void cluster_process_copies_unlink( struct process_s * process ); 263 263 264 264 -
trunk/kernel/kern/core.c
r14 r19 1 1 /* 2 2 * core.c - core descriptor access function. 3 * 3 * 4 4 * Author Ghassan Almaless (2008,2009,2010,2011,2012) 5 5 * Mohamed Lamine Karaoui (2015) … … 41 41 42 42 ///////////////////////////////// 43 void core_init( core_t * core, 44 lid_t lid, 43 void core_init( core_t * core, 44 lid_t lid, 45 45 gid_t gid ) 46 46 { … … 53 53 core->usage = 0; 54 54 core->spurious_irqs = 0; 55 55 core->rpc_threads = 0; 56 56 57 57 rpc_fifo_init( &core->rpc_fifo ); 58 58 59 60 61 62 63 59 list_root_init( &core->rpc_free_list ); 60 61 core->thread_rpc = NULL; 62 core->thread_idle = NULL; 63 core->fpu_owner = NULL; 64 64 core->rand_last = hal_time_stamp() & 0xFFF; 65 65 … … 70 70 inline uint32_t core_get_rand( core_t * core ) 71 71 { 72 73 74 75 72 uint32_t value = ((core->rand_last * CONFIG_RDNG_PARAM_A) + 73 CONFIG_RDNG_PARAM_C) ^ (hal_time_stamp() & 0xFFF); 74 core->rand_last = value; 75 return value; 76 76 } 77 77 … … 79 79 inline uint64_t core_get_cycles( core_t * core ) 80 80 { 81 82 81 uint32_t elapsed; 82 uint64_t cycles; 83 83 uint32_t time_stamp = core->time_stamp; 84 84 uint32_t time_now = hal_time_stamp(); 85 85 86 86 // compute number of elapsed cycles, taking into account 32 bits register wrap 87 87 if(time_now < time_stamp) elapsed = (0xFFFFFFFF - time_stamp) + time_now; 88 88 else elapsed = (time_now - time_stamp); 89 89 90 91 92 93 94 90 cycles = core->cycles + elapsed; 91 92 // update core time 93 core->time_stamp = time_now; 94 core->cycles = cycles; 95 95 hal_wbflush(); 96 96 … … 100 100 //////////////////////////////////// 101 101 void core_get_time( core_t * core, 102 uint32_t * tm_ms, 102 uint32_t * tm_ms, 103 103 uint32_t * tm_us ) 104 104 { 105 105 // uint64_t cycles = core_get_cycles( core ); 106 106 107 107 // TODO ces deux ligne ne compilent pas : "undefined referenc to __udivdi3" 108 108 109 109 // *tm_ms = (cycles / CONFIG_CYCLES_PER_MS); 110 110 // *tm_us = (cycles % CONFIG_CYCLES_PER_MS) / (CONFIG_CYCLES_PER_MS / 1000000); 111 111 112 112 printk("\n[PANIC] in %s : not implemented yet\n", __FUNCTION__ ); 113 113 } 114 114 … … 116 116 void core_time_update( core_t * core ) 117 117 { 118 118 uint32_t elapsed; 119 119 uint32_t ticks_nr = core->ticks_nr; 120 120 uint64_t cycles = core->cycles; … … 122 122 uint32_t time_now = hal_time_stamp(); 123 123 124 // compute number of elapsed cycles taking into account 32 bits register wrap 124 // compute number of elapsed cycles taking into account 32 bits register wrap 125 125 if( time_now < time_stamp ) elapsed = (0xFFFFFFFF - time_stamp) + time_now; 126 126 else elapsed = time_now - time_stamp; 127 127 128 128 cycles += elapsed; 129 129 ticks_nr = elapsed / core->ticks_period; … … 140 140 uint32_t ticks; 141 141 142 142 // update cycles and ticks counter 143 143 core_time_update( core ); 144 144 145 145 // get current ticks number 146 146 ticks = core->ticks_nr; 147 147 148 148 // handle pending alarms TODO ??? [AG] 149 149 // alarm_clock( &core->alarm_mgr , ticks ); 150 150 151 152 153 154 155 151 // handle scheduler TODO improve the scheduling condition ... AG 152 if( (ticks % 10) == 0 ) sched_yield(); 153 154 // update DQDT TODO This update should depend on the cluster identifier, 155 // to avoid simultaneous updates from various clusters ... AG 156 156 if( ((ticks % CONFIG_DQDT_PERIOD) == 0) && (core->lid == 0) ) dqdt_global_update(); 157 157 } 158 158 159 159 //////////////////////////////////////// 160 void core_compute_stats( core_t * core ) 160 void core_compute_stats( core_t * core ) 161 161 { 162 162 thread_t * idle = core->thread_idle; … … 167 167 uint32_t usage; 168 168 169 // compute cumulated usage 169 // compute cumulated usage 170 170 ticks = (ticks) ? ticks : 1; 171 171 idle_percent = (idle->ticks_nr * 100) / ticks; … … 174 174 usage = (busy_percent + core->usage) / 2; 175 175 176 176 // update core descriptor 177 177 core->usage = usage; 178 178 hal_wbflush(); … … 204 204 chdev_t * chdev ) 205 205 { 206 207 208 209 } 206 if ( irq_type == WTI_TYPE ) core->wti_vector[irq_id] = chdev; 207 else if( irq_type == HWI_TYPE ) core->hwi_vector[irq_id] = chdev; 208 else core->pti_vector[irq_id] = chdev; 209 } -
trunk/kernel/kern/core.h
r16 r19 1 1 /* 2 2 * core.h - core descriptor and associated access functions définition 3 * 3 * 4 4 * Authors Ghassan Almaless (2008,2009,2010,2011,2012) 5 5 * Mohamed Lamine Karaoui (2015) … … 49 49 { 50 50 lid_t lid; /*! core local index in cluster */ 51 gid_t gid; /*! core global identifier (hardware index) */ 51 gid_t gid; /*! core global identifier (hardware index) */ 52 52 uint64_t cycles; /*! total number of cycles (from hard reset) */ 53 53 uint32_t time_stamp; /*! previous time stamp (read from register) */ … … 58 58 struct thread_s * thread_rpc; /*! pointer on current RPC thread descriptor */ 59 59 struct thread_s * thread_idle; /*! pointer on idle thread descriptor */ 60 struct thread_s * fpu_owner; /*! pointer on current FPU owner thread */ 60 struct thread_s * fpu_owner; /*! pointer on current FPU owner thread */ 61 61 uint32_t rand_last; /*! last computed random value */ 62 62 uint32_t rpc_threads; /*! total number of RPC threads for this core */ … … 71 71 72 72 // sysfs_entry_t node; 73 } 73 } 74 74 core_t; 75 75 … … 87 87 *************************************************************************************** 88 88 * @ core : pointer on core descriptor to initialise. 89 * @ lid : local core index 89 * @ lid : local core index 90 90 * @ gid : global core identifier (hardware index) 91 91 **************************************************************************************/ 92 void core_init( core_t * core, 93 lid_t lid, 92 void core_init( core_t * core, 93 lid_t lid, 94 94 gid_t gid ); 95 95 … … 104 104 105 105 /*************************************************************************************** 106 * This function returns the current date (cycles) from both 107 * the hardware 32 bits cycles counter and the core descriptor cycles counter, 106 * This function returns the current date (cycles) from both 107 * the hardware 32 bits cycles counter and the core descriptor cycles counter, 108 108 * taking into account the 32 bits hardware register overflow. 109 109 * The core descriptor time is updated. … … 116 116 /*************************************************************************************** 117 117 * This function returns the current date (seconds & micro-seconds) from both 118 * the hardware 32 bits cycles counter and the core descriptor cycles counter, 118 * the hardware 32 bits cycles counter and the core descriptor cycles counter, 119 119 * taking into account the 32 bits hardware register overflow. 120 120 * The core descriptor time is updated. … … 132 132 * It updates the cycles and ticks counter in the calling core descriptor. 133 133 * It handles all pending alarms depending on the ticks counter value. 134 * It handles the scheduling, depending on the ticks counter value. 134 * It handles the scheduling, depending on the ticks counter value. 135 135 * It handles the global DQDT update, depending on the ticks counter vakue. 136 136 *************************************************************************************** … … 140 140 141 141 /*************************************************************************************** 142 * This function updates the usage statistics for the calling core descriptor, 142 * This function updates the usage statistics for the calling core descriptor, 143 143 * based on the ratio between the idle_ticks and total_ticks. 144 144 *************************************************************************************** … … 157 157 * This function set/reset a selected entry in one interrupt vector for a remote core. 158 158 * The written value is an extended pointer on the "source" device (or the XPTR_NULL 159 * value in case of reset). As it uses remote access, this function can be called by 159 * value in case of reset). As it uses remote access, this function can be called by 160 160 * any thread in any cluster. 161 161 *************************************************************************************** -
trunk/kernel/kern/dqdt.c
r14 r19 1 1 /* 2 2 * dqdt.c - Distributed Quaternary Decision Tree implementation. 3 * 3 * 4 4 * Author : Alain Greiner (2016) 5 5 * … … 63 63 } 64 64 } 65 } 66 65 } 66 67 67 //////////////////////////////////// 68 68 uint32_t dqdt_init( uint32_t x_size, … … 113 113 node->children[2] = XPTR_NULL; 114 114 node->children[3] = XPTR_NULL; 115 115 116 116 // compute masks depending on level : 0x1, 0x3, 0x7, 0xF, 0x1F etc. 117 117 mask = (1<<level)-1; … … 121 121 if( ((x & mask) == 0) && ((y & mask) == 0) ); 122 122 { 123 // set parent extended pointer 123 // set parent extended pointer 124 124 p_cxy = ((x & ~pmask)<<y_width) + (y & ~pmask); 125 125 node->parent = XPTR( p_cxy , &cluster->dqdt_tbl[level+1] ); 126 126 127 // set child[0] extended pointer (same [x,y] coordinates) 127 // set child[0] extended pointer (same [x,y] coordinates) 128 128 if ( level > 0 ) 129 129 { … … 188 188 if ( parent != XPTR_NULL ) 189 189 { 190 dqdt_propagate( parent, threads_var, pages_var ); 190 dqdt_propagate( parent, threads_var, pages_var ); 191 191 } 192 192 } … … 217 217 { 218 218 cluster_t * cluster = LOCAL_CLUSTER; 219 220 // register change for future propagation in DQDT 219 220 // register change for future propagation in DQDT 221 221 hal_atomic_add( &cluster->threads_var , increment ); 222 222 … … 229 229 { 230 230 cluster_t * cluster = LOCAL_CLUSTER; 231 232 // register change for future propagation in DQDT 231 232 // register change for future propagation in DQDT 233 233 hal_atomic_add( &cluster->pages_var , increment ); 234 234 … … 270 270 { 271 271 cxy = (cxy_t)GET_CXY( child ); 272 ptr = (dqdt_node_t *)GET_PTR( child ); 272 ptr = (dqdt_node_t *)GET_PTR( child ); 273 273 if( for_memory ) load = hal_remote_lw( XPTR( cxy , &ptr->pages ) ); 274 274 else load = hal_remote_lw( XPTR( cxy , &ptr->threads ) ); … … 276 276 { 277 277 load_min = load; 278 select = i; 279 } 278 select = i; 279 } 280 280 } 281 281 } 282 282 283 283 // select the child with the lowest load 284 return dqdt_select_cluster( node_copy.children[select], for_memory ); 284 return dqdt_select_cluster( node_copy.children[select], for_memory ); 285 285 } 286 286 … … 294 294 295 295 // call recursive function 296 return dqdt_select_cluster( root , false ); 296 return dqdt_select_cluster( root , false ); 297 297 } 298 298 … … 306 306 307 307 // call recursive function 308 return dqdt_select_cluster( root , true ); 309 } 310 308 return dqdt_select_cluster( root , true ); 309 } 310 -
trunk/kernel/kern/dqdt.h
r14 r19 1 1 /* 2 2 * kern/dqdt.h - Distributed Quad Decision Tree 3 * 3 * 4 4 * Author : Alain Greiner (2016) 5 5 * … … 35 35 * - If X_SIZE or Y_SIZE are equal to 1, it makes the assumption that the cluster 36 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 37 * quad-tree covering this one-dimensionnal vector. If the number of clusters 38 38 * is not a power of 4, the tree is truncated as required. 39 39 * TODO : the mapping for the one dimensionnal topology is not implemented yet [AG]. 40 * 41 * - If both Y_SIZE and Y_SIZE are larger than 1, it makes the assumption that 42 * the cluster topology is a 2D mesh. The [X,Y] coordinates of a cluster are 43 * obtained from the CXY identifier using the following rules : 40 * 41 * - If both Y_SIZE and Y_SIZE are larger than 1, it makes the assumption that 42 * the cluster topology is a 2D mesh. The [X,Y] coordinates of a cluster are 43 * obtained from the CXY identifier using the following rules : 44 44 * X = CXY >> Y_WIDTH / Y = CXY & ((1<<Y_WIDTH)-1) 45 * If the mesh X_SIZE and Y_SIZE dimensions are not equal, or are not power of 2, 45 * If the mesh X_SIZE and Y_SIZE dimensions are not equal, or are not power of 2, 46 46 * we build the smallest two dimensionnal quad-tree covering all clusters, 47 47 * and this tree is truncated as required. 48 48 * The root node is always implemented in cluster [0,0] 49 49 * The mesh size is supposed to contain at most 32 * 32 clusters. 50 * There are at most 6 DQDT nodes in a cluster 50 * There are at most 6 DQDT nodes in a cluster 51 51 * . Level 0 nodes exist on all clusters and have no children. 52 * . Level 1 nodes exist when both X and Y coordinates are multiple of 2 52 * . Level 1 nodes exist when both X and Y coordinates are multiple of 2 53 53 * . Level 2 nodes exist when both X and Y coordinates are multiple of 4 54 54 * . Level 3 nodes exist when both X and Y coordinates are multiple of 8 … … 76 76 77 77 /**************************************************************************************** 78 * This local function initializes the local DQDT structures. 78 * This local function initializes the local DQDT structures. 79 79 * The information describing the hardware platform topology and the cluster 80 80 * indexing policy is defined by the three arguments below. 81 * This initialisation is done in parallel, locally in each cluster, because the DQDT 81 * This initialisation is done in parallel, locally in each cluster, because the DQDT 82 82 * is allocated as a global variable in the cluster_manager, and the local addresses 83 83 * are identical in all clusters. … … 118 118 * This local function updates both the total number of threads, 119 119 * in the level 0 DQDT node, and the variation of the number of threads 120 * for future propagation to the DQDT upper levels. 120 * for future propagation to the DQDT upper levels. 121 121 * It should be called on each thread creation or destruction. 122 122 **************************************************************************************** … … 128 128 * This local function updates both the total number of allocated pages, 129 129 * in the level 0 DQDT node, and the variation of the number of pages 130 * for future propagation to the DQDT upper levels. 130 * for future propagation to the DQDT upper levels. 131 131 * It should be called on each memory allocation or release. 132 132 **************************************************************************************** … … 146 146 /**************************************************************************************** 147 147 * This function can be called in any cluster. It traverses the DQDT tree 148 * from the root to the bottom, to analyse the memory load and select the cluster 148 * from the root to the bottom, to analyse the memory load and select the cluster 149 149 * with the lowest memory load for dynamic memory allocation with no locality constraint. 150 150 **************************************************************************************** -
trunk/kernel/kern/kernel_init.c
r14 r19 82 82 // This variable defines the local cluster manager 83 83 __attribute__((section(".kdata"))) 84 cluster_t cluster_manager CONFIG_CACHE_LINE_ALIGNED; 84 cluster_t cluster_manager CONFIG_CACHE_LINE_ALIGNED; 85 85 86 86 // This variables define the kernel process0 descriptor 87 87 __attribute__((section(".kdata"))) 88 process_t process_zero CONFIG_CACHE_LINE_ALIGNED; 88 process_t process_zero CONFIG_CACHE_LINE_ALIGNED; 89 89 90 90 // This variable defines extended pointers on the distributed chdevs … … 197 197 { 198 198 cxy_t cxy = (x<<info->y_width) + y; 199 hal_remote_swd( XPTR( cxy , &chdev_dir.txt[0] ) , 199 hal_remote_swd( XPTR( cxy , &chdev_dir.txt[0] ) , 200 200 XPTR( local_cxy , &txt0_chdev ) ); 201 201 } … … 204 204 kinit_dmsg("\n[INFO] %s : core[%x][0] created TXT0 chdev" 205 205 " / paddr = %l at cycle %d\n", 206 __FUNCTION__ , local_cxy , chdev_func_str( func ), 206 __FUNCTION__ , local_cxy , chdev_func_str( func ), 207 207 XPTR(local_cxy , &txt0_chdev) , hal_time_stamp() ); 208 208 } … … 257 257 // make ICU specific initialisation 258 258 // TODO remove these three parameters 259 dev_icu_init( chdev_ptr , dev->param0 , dev->param1 , dev->param2 ); 259 dev_icu_init( chdev_ptr , dev->param0 , dev->param1 , dev->param2 ); 260 260 261 261 // initialize the ICU field in the chdev_dir[x][y] structures … … 532 532 } // end if match 533 533 534 // increment chdev global index (matching or not) 534 // increment chdev global index (matching or not) 535 535 chdev_gid++; 536 536 … … 608 608 uint32_t i; 609 609 gid_t global_id; 610 610 611 611 // get global identifier from hardware register 612 612 global_id = hal_get_gid(); … … 624 624 } 625 625 return EINVAL; 626 } 626 } 627 627 628 628 /////////////////////////////////////////////////////////////////////////////////////////// 629 629 // This function is the entry point for the kernel initialisation. 630 // It is executed by all cores in all clusters, but only core[0], called CP0, 630 // It is executed by all cores in all clusters, but only core[0], called CP0, 631 631 // initializes the shared resources such as the cluster manager, or the local peripherals. 632 // To comply with the multi-kernels paradigm, it access only local cluster memory, using633 // only information scontained in the local boot_info_t structure, set by the bootloader.632 // To comply with the multi-kernels paradigm, it accesses only local cluster memory, using 633 // only information contained in the local boot_info_t structure, set by the bootloader. 634 634 /////////////////////////////////////////////////////////////////////////////////////////// 635 635 // @ info : pointer on the local boot-info structure. … … 681 681 } 682 682 683 // CP0 initialize local cluster manager (cores and memory allocators)683 // CP0 initializes the local cluster manager (cores and memory allocators) 684 684 if( core_lid == 0 ) 685 685 { … … 713 713 core = &cluster->core_tbl[core_lid]; 714 714 715 // CP0 initialize process_zero descriptor715 // CP0 initializes the process_zero descriptor 716 716 if( core_lid == 0 ) process_zero_init( info ); 717 717 718 // CP0 allocate and initialise internal peripheral chdev descriptors.718 // CP0 allocates and initialises the internal peripheral chdev descriptors. 719 719 // Each CP0[cxy] scan the set of its internal (private) peripherals, 720 720 // and allocate memory for the corresponding chdev descriptors.
Note: See TracChangeset
for help on using the changeset viewer.