source: trunk/kernel/kern/cluster.c @ 582

Last change on this file since 582 was 582, checked in by alain, 3 years ago

New DQDT implementation supporting missing clusters
thanks to the cluster_info[x][y] array.

File size: 22.0 KB
RevLine 
[1]1/*
2 * cluster.c - Cluster-Manager related operations
[19]3 *
[1]4 * Author  Ghassan Almaless (2008,2009,2010,2011,2012)
5 *         Mohamed Lamine Karaoui (2015)
[437]6 *         Alain Greiner (2016,2017,2018)
[1]7 *
8 * Copyright (c) UPMC Sorbonne Universites
9 *
10 * This file is part of ALMOS-MKH..
11 *
12 * ALMOS-MKH. is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; version 2.0 of the License.
15 *
16 * ALMOS-MKH. is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with ALMOS-MKH.; if not, write to the Free Software Foundation,
23 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
[14]26#include <kernel_config.h>
[456]27#include <hal_kernel_types.h>
[1]28#include <hal_atomic.h>
29#include <hal_special.h>
[50]30#include <hal_ppm.h>
[564]31#include <hal_macros.h>
[407]32#include <remote_fifo.h>
[1]33#include <printk.h>
34#include <errno.h>
[564]35#include <queuelock.h>
[1]36#include <core.h>
[443]37#include <chdev.h>
[1]38#include <scheduler.h>
39#include <list.h>
40#include <cluster.h>
41#include <boot_info.h>
42#include <bits.h>
43#include <ppm.h>
44#include <thread.h>
45#include <kmem.h>
46#include <process.h>
47#include <dqdt.h>
48
[408]49/////////////////////////////////////////////////////////////////////////////////////
[1]50// Extern global variables
[408]51/////////////////////////////////////////////////////////////////////////////////////
[1]52
[564]53extern process_t           process_zero;     // allocated in kernel_init.c
54extern chdev_directory_t   chdev_dir;        // allocated in kernel_init.c
[1]55
[564]56
57
58///////////////////////////////////////////////////
59void cluster_info_init( struct boot_info_s * info )
[1]60{
[428]61    boot_device_t * dev;      // pointer on external peripheral
62    uint32_t        func;     // external peripheral functionnal type
[564]63    uint32_t        x;
64    uint32_t        y;
65    uint32_t        i;   
[1]66
67        cluster_t * cluster = LOCAL_CLUSTER;
68
69    // initialize cluster global parameters
[19]70        cluster->paddr_width     = info->paddr_width;
[1]71        cluster->x_width         = info->x_width;
72        cluster->y_width         = info->y_width;
73        cluster->x_size          = info->x_size;
74        cluster->y_size          = info->y_size;
75        cluster->io_cxy          = info->io_cxy;
76
[557]77    // initialize the cluster_info[][] array
[564]78    for (x = 0; x < CONFIG_MAX_CLUSTERS_X; x++) 
79    {
80        for (y = 0; y < CONFIG_MAX_CLUSTERS_Y;y++) 
81        {
[557]82            cluster->cluster_info[x][y] = info->cluster_info[x][y];
83        }
84    }
[564]85
[428]86    // initialize external peripherals channels
87    for( i = 0 ; i < info->ext_dev_nr ; i++ )
88    {
89        dev  = &info->ext_dev[i];
90        func = FUNC_FROM_TYPE( dev->type );   
91        if( func == DEV_FUNC_TXT ) cluster->nb_txt_channels = dev->channels;
92        if( func == DEV_FUNC_NIC ) cluster->nb_nic_channels = dev->channels;
93        if( func == DEV_FUNC_IOC ) cluster->nb_ioc_channels = dev->channels;
94        if( func == DEV_FUNC_FBF ) cluster->nb_fbf_channels = dev->channels;
95    }
96
[564]97    // initialize number of cores
98        cluster->cores_nr  = info->cores_nr;
[1]99
[564]100}  // end cluster_info_init()
101
102/////////////////////////////////////////////////////////
103error_t cluster_manager_init( struct boot_info_s * info )
104{
105    error_t         error;
106    lpid_t          lpid;     // local process_index
107    lid_t           lid;      // local core index
108
109        cluster_t * cluster = LOCAL_CLUSTER;
110
[19]111    // initialize the lock protecting the embedded kcm allocator
[564]112        busylock_init( &cluster->kcm_lock , LOCK_CLUSTER_KCM );
[1]113
[438]114#if DEBUG_CLUSTER_INIT
[433]115uint32_t cycle = (uint32_t)hal_get_cycles();
[438]116if( DEBUG_CLUSTER_INIT < cycle )
[564]117printk("\n[DBG] %s : thread %x in process %x enters for cluster %x / cycle %d\n",
118__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, local_cxy , cycle );
[433]119#endif
[50]120
[1]121    // initialises embedded PPM
[50]122        error = hal_ppm_init( info );
[1]123
[50]124    if( error )
125    {
126        printk("\n[ERROR] in %s : cannot initialize PPM in cluster %x\n",
127               __FUNCTION__ , local_cxy );
128        return ENOMEM;
129    }
130
[438]131#if( DEBUG_CLUSTER_INIT & 1 )
[433]132cycle = (uint32_t)hal_get_cycles();
[438]133if( DEBUG_CLUSTER_INIT < cycle )
[437]134printk("\n[DBG] %s : PPM initialized in cluster %x / cycle %d\n",
[433]135__FUNCTION__ , local_cxy , cycle );
136#endif
[50]137
[1]138    // initialises embedded KHM
139        khm_init( &cluster->khm );
[19]140
[438]141#if( DEBUG_CLUSTER_INIT & 1 )
[457]142cycle = (uint32_t)hal_get_cycles();
[438]143if( DEBUG_CLUSTER_INIT < cycle )
[437]144printk("\n[DBG] %s : KHM initialized in cluster %x at cycle %d\n",
145__FUNCTION__ , local_cxy , hal_get_cycles() );
146#endif
[50]147
[19]148    // initialises embedded KCM
[5]149        kcm_init( &cluster->kcm , KMEM_KCM );
[1]150
[438]151#if( DEBUG_CLUSTER_INIT & 1 )
[457]152cycle = (uint32_t)hal_get_cycles();
[438]153if( DEBUG_CLUSTER_INIT < cycle )
[437]154printk("\n[DBG] %s : KCM initialized in cluster %x at cycle %d\n",
155__FUNCTION__ , local_cxy , hal_get_cycles() );
156#endif
[50]157
[296]158    // initialises all cores descriptors
[1]159        for( lid = 0 ; lid < cluster->cores_nr; lid++ )
160        {
161                core_init( &cluster->core_tbl[lid],    // target core descriptor
162                       lid,                        // local core index
163                       info->core[lid].gid );      // gid from boot_info_t
164        }
[19]165
[438]166#if( DEBUG_CLUSTER_INIT & 1 )
[433]167cycle = (uint32_t)hal_get_cycles();
[438]168if( DEBUG_CLUSTER_INIT < cycle )
[437]169printk("\n[DBG] %s : cores initialized in cluster %x / cycle %d\n",
[433]170__FUNCTION__ , local_cxy , cycle );
171#endif
[50]172
[440]173    // initialises RPC FIFOs
174        for( lid = 0 ; lid < cluster->cores_nr; lid++ )
175    {
[564]176            remote_fifo_init( &cluster->rpc_fifo[lid] );
[440]177        cluster->rpc_threads[lid] = 0;
178    }
[1]179
[438]180#if( DEBUG_CLUSTER_INIT & 1 )
[437]181cycle = (uint32_t)hal_get_cycles();
[438]182if( DEBUG_CLUSTER_INIT < cycle )
[437]183printk("\n[DBG] %s : RPC fifo inialized in cluster %x at cycle %d\n",
[407]184__FUNCTION__ , local_cxy , hal_get_cycles() );
[437]185#endif
[50]186
[1]187    // initialise pref_tbl[] in process manager
[564]188        queuelock_init( &cluster->pmgr.pref_lock , LOCK_CLUSTER_PREFTBL );
[1]189    cluster->pmgr.pref_nr = 0;
[19]190    cluster->pmgr.pref_tbl[0] = XPTR( local_cxy , &process_zero );
[580]191    for( lpid = 0 ; lpid < CONFIG_MAX_PROCESS_PER_CLUSTER ; lpid++ )
[1]192    {
193        cluster->pmgr.pref_tbl[lpid] = XPTR_NULL;
194    }
195
196    // initialise local_list in process manager
[23]197    xlist_root_init( XPTR( local_cxy , &cluster->pmgr.local_root ) );
[1]198    cluster->pmgr.local_nr = 0;
[564]199        remote_queuelock_init( XPTR( local_cxy , &cluster->pmgr.local_lock ) ,
200                           LOCK_CLUSTER_LOCALS );
[1]201
202    // initialise copies_lists in process manager
[101]203    for( lpid = 0 ; lpid < CONFIG_MAX_PROCESS_PER_CLUSTER ; lpid++ )
[1]204    {
205        cluster->pmgr.copies_nr[lpid] = 0;
206        xlist_root_init( XPTR( local_cxy , &cluster->pmgr.copies_root[lpid] ) );
[564]207            remote_queuelock_init( XPTR( local_cxy , &cluster->pmgr.copies_lock[lpid] ),
208                               LOCK_CLUSTER_COPIES );
[19]209    }
[1]210
[438]211#if DEBUG_CLUSTER_INIT
[433]212cycle = (uint32_t)hal_get_cycles();
[438]213if( DEBUG_CLUSTER_INIT < cycle )
[564]214printk("\n[DBG] %s : thread %x in process %x exit for cluster %x / cycle %d\n",
215__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid , local_cxy , cycle );
[433]216#endif
[50]217
[124]218    hal_fence();
[1]219
220        return 0;
[564]221} // end cluster_manager_init()
[1]222
[564]223///////////////////////////////////
[561]224cxy_t cluster_random_select( void )
225{
226    uint32_t  index;
[564]227    uint32_t  x;   
[561]228    uint32_t  y;
[564]229    cxy_t     cxy;
[561]230
[564]231    uint32_t  x_size    = LOCAL_CLUSTER->x_size;
232    uint32_t  y_size    = LOCAL_CLUSTER->y_size;
233
234    do 
235    {
[561]236        index     = ( hal_get_cycles() + hal_get_gid() ) % (x_size * y_size);
237        x         = index / y_size;
238        y         = index % y_size;
[564]239        cxy       = HAL_CXY_FROM_XY( x , y );
240    }
241    while ( cluster_is_active( cxy ) == false );
[561]242
[564]243    return ( cxy );
[561]244}
245
[1]246////////////////////////////////////////
247bool_t cluster_is_undefined( cxy_t cxy )
248{
[564]249    uint32_t  x_size = LOCAL_CLUSTER->x_size;
250    uint32_t  y_size = LOCAL_CLUSTER->y_size;
[1]251
[564]252    uint32_t  x      = HAL_X_FROM_CXY( cxy );
253    uint32_t  y      = HAL_Y_FROM_CXY( cxy );
[1]254
[564]255    if( x >= x_size ) return true;
256    if( y >= y_size ) return true;
[1]257
258    return false;
259}
260
[564]261//////////////////////////////////////
262bool_t cluster_is_active ( cxy_t cxy )
263{
264    uint32_t x = HAL_X_FROM_CXY( cxy );
265    uint32_t y = HAL_Y_FROM_CXY( cxy );
266
267    return ( LOCAL_CLUSTER->cluster_info[x][y] != 0 );
268}
269
[1]270////////////////////////////////////////////////////////////////////////////////////
271//  Cores related functions
272////////////////////////////////////////////////////////////////////////////////////
273
274/////////////////////////////////
[485]275lid_t cluster_select_local_core( void )
[1]276{
[440]277    uint32_t      min = 1000;
278    lid_t         sel = 0;
279    uint32_t      nthreads;
280    lid_t         lid;
281    scheduler_t * sched;
[1]282
283    cluster_t * cluster = LOCAL_CLUSTER;
284
285    for( lid = 0 ; lid < cluster->cores_nr ; lid++ )
286    {
[440]287        sched    = &cluster->core_tbl[lid].scheduler;
288        nthreads = sched->u_threads_nr + sched->k_threads_nr;
289
290        if( nthreads < min )
[1]291        {
[440]292            min = nthreads;
[1]293            sel = lid;
294        }
[19]295    }
[1]296    return sel;
297}
298
299////////////////////////////////////////////////////////////////////////////////////
[428]300//  Process related functions
[1]301////////////////////////////////////////////////////////////////////////////////////
302
[433]303
304//////////////////////////////////////////////////////
[443]305xptr_t cluster_get_process_from_pid_in_cxy( cxy_t cxy,
306                                            pid_t pid )
307{
308    xptr_t      root_xp;       // xptr on root of list of processes in owner cluster
309    xptr_t      lock_xp;       // xptr on lock protecting this list
310    xptr_t      iter_xp;       // iterator
311    xptr_t      current_xp;    // xptr on current process descriptor
312    bool_t      found;
313
314    cluster_t * cluster = LOCAL_CLUSTER;
315
316    // get owner cluster and lpid
317    cxy_t   owner_cxy = CXY_FROM_PID( pid );
318    lpid_t  lpid      = LPID_FROM_PID( pid );
319
320    // get lock & root of list of copies from owner cluster
321    root_xp = XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] );
322    lock_xp = XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] );
323
324    // take the lock protecting the list of processes
[564]325    remote_queuelock_acquire( lock_xp );
[443]326
327    // scan list of processes
328    found = false;
329    XLIST_FOREACH( root_xp , iter_xp )
330    {
331        current_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
332
333        if( GET_CXY( current_xp ) == cxy )
334        {
335            found = true;
336            break;
337        }
338    }
339
340    // release the lock protecting the list of processes
[564]341    remote_queuelock_release( lock_xp );
[443]342
343    // return extended pointer on process descriptor in owner cluster
344    if( found ) return current_xp;
345    else        return XPTR_NULL;
346
347}  // end cluster_get_process_from_pid_in_cxy()
348
349
350//////////////////////////////////////////////////////
[433]351xptr_t cluster_get_owner_process_from_pid( pid_t pid )
352{
353    xptr_t      root_xp;       // xptr on root of list of processes in owner cluster
[436]354    xptr_t      lock_xp;       // xptr on lock protecting this list
[433]355    xptr_t      iter_xp;       // iterator
356    xptr_t      current_xp;    // xptr on current process descriptor
357    process_t * current_ptr;   // local pointer on current process
358    pid_t       current_pid;   // current process identifier
359    bool_t      found;
360
361    cluster_t * cluster = LOCAL_CLUSTER;
362
363    // get owner cluster and lpid
364    cxy_t  owner_cxy = CXY_FROM_PID( pid );
365
366    // get lock & root of list of process in owner cluster
367    root_xp = XPTR( owner_cxy , &cluster->pmgr.local_root );
368    lock_xp = XPTR( owner_cxy , &cluster->pmgr.local_lock );
369
370    // take the lock protecting the list of processes
[564]371    remote_queuelock_acquire( lock_xp );
[433]372
373    // scan list of processes in owner cluster
374    found = false;
375    XLIST_FOREACH( root_xp , iter_xp )
376    {
377        current_xp  = XLIST_ELEMENT( iter_xp , process_t , local_list );
378        current_ptr = GET_PTR( current_xp );
[564]379        current_pid = hal_remote_l32( XPTR( owner_cxy , &current_ptr->pid ) );
[433]380
381        if( current_pid == pid )
382        {
383            found = true;
384            break;
385        }
386    }
387
388    // release the lock protecting the list of processes
[564]389    remote_queuelock_release( lock_xp );
[433]390
391    // return extended pointer on process descriptor in owner cluster
392    if( found ) return current_xp;
393    else        return XPTR_NULL;
394
[436]395}  // end cluster_get_owner_process_from_pid()
396
[443]397
[1]398//////////////////////////////////////////////////////////
399xptr_t cluster_get_reference_process_from_pid( pid_t pid )
[19]400{
[23]401    xptr_t ref_xp;   // extended pointer on reference process descriptor
[1]402
403    cluster_t * cluster = LOCAL_CLUSTER;
404
405    // get owner cluster and lpid
406    cxy_t  owner_cxy = CXY_FROM_PID( pid );
407    lpid_t lpid      = LPID_FROM_PID( pid );
408
[19]409    // Check valid PID
[23]410    if( lpid >= CONFIG_MAX_PROCESS_PER_CLUSTER )  return XPTR_NULL;
[1]411
412    if( local_cxy == owner_cxy )   // local cluster is owner cluster
[19]413    {
[23]414        ref_xp = cluster->pmgr.pref_tbl[lpid];
[1]415    }
416    else                              // use a remote_lwd to access owner cluster
417    {
[564]418        ref_xp = (xptr_t)hal_remote_l64( XPTR( owner_cxy , &cluster->pmgr.pref_tbl[lpid] ) );
[1]419    }
420
[23]421    return ref_xp;
[1]422}
423
[416]424///////////////////////////////////////////////
425error_t cluster_pid_alloc( process_t * process,
426                           pid_t     * pid )
[1]427{
428    lpid_t      lpid;
429    bool_t      found;
430
[440]431#if DEBUG_CLUSTER_PID_ALLOC
432uint32_t cycle = (uint32_t)hal_get_cycles();
433if( DEBUG_CLUSTER_PID_ALLOC < cycle )
434printk("\n[DBG] %s : thread %x enters in cluster %x / cycle %d\n",
435__FUNCTION__ , CURRENT_THREAD , local_cxy , cycle );
436#endif
437
[1]438    pmgr_t    * pm         = &LOCAL_CLUSTER->pmgr;
439
[564]440    // get the lock protecting pref_tbl
441    queuelock_acquire( &pm->pref_lock );
[1]442
443    // search an empty slot
444    found = false;
445    for( lpid = 0 ; lpid < CONFIG_MAX_PROCESS_PER_CLUSTER ; lpid++ )
446    {
447        if( pm->pref_tbl[lpid] == XPTR_NULL )
448        {
449            found = true;
450            break;
451        }
452    }
453
454    if( found )
455    {
456        // register process in pref_tbl[]
[416]457        pm->pref_tbl[lpid] = XPTR( local_cxy , process );
[1]458        pm->pref_nr++;
459
460        // returns pid
461        *pid = PID( local_cxy , lpid );
462
[416]463        // release the processs_manager lock
[564]464        queuelock_release( &pm->pref_lock );
[416]465
466        return 0;
[1]467    }
468    else
469    {
[564]470        // release the lock
471        queuelock_release( &pm->pref_lock );
[416]472
[564]473        return 0xFFFFFFFF;
[19]474    }
[1]475
[440]476#if DEBUG_CLUSTER_PID_ALLOC
477cycle = (uint32_t)hal_get_cycles();
478if( DEBUG_CLUSTER_PID_ALLOC < cycle )
479printk("\n[DBG] %s : thread %x exit in cluster %x / pid %x / cycle %d\n",
480__FUNCTION__ , CURRENT_THREAD , local_cxy , *pid , cycle );
481#endif
482
[1]483} // end cluster_pid_alloc()
484
485/////////////////////////////////////
486void cluster_pid_release( pid_t pid )
487{
[440]488
489#if DEBUG_CLUSTER_PID_RELEASE
490uint32_t cycle = (uint32_t)hal_get_cycles();
491if( DEBUG_CLUSTER_PID_RELEASE < cycle )
492printk("\n[DBG] %s : thread %x enters in cluster %x / pid %x / cycle %d\n",
493__FUNCTION__ , CURRENT_THREAD , local_cxy , pid , cycle );
494#endif
495
[1]496    cxy_t  owner_cxy  = CXY_FROM_PID( pid );
497    lpid_t lpid       = LPID_FROM_PID( pid );
498
[409]499    pmgr_t  * pm = &LOCAL_CLUSTER->pmgr;
500
[440]501    // check lpid
[492]502    assert( (lpid < CONFIG_MAX_PROCESS_PER_CLUSTER),
[440]503    "illegal LPID = %d" , lpid );
[1]504
[440]505    // check owner cluster
[492]506    assert( (owner_cxy == local_cxy) ,
[440]507    "local_cluster %x !=  owner_cluster %x" , local_cxy , owner_cxy );
508
[564]509    // get the lock protecting pref_tbl
510    queuelock_acquire( &pm->pref_lock );
[1]511
512    // remove process from pref_tbl[]
513    pm->pref_tbl[lpid] = XPTR_NULL;
514    pm->pref_nr--;
515
516    // release the processs_manager lock
[564]517    queuelock_release( &pm->pref_lock );
[1]518
[440]519#if DEBUG_CLUSTER_PID_RELEASE
520cycle = (uint32_t)hal_get_cycles();
521if( DEBUG_CLUSTER_PID_RELEASE < cycle )
522printk("\n[DBG] %s : thread %x exit in cluster %x / cycle %d\n",
523__FUNCTION__ , CURRENT_THREAD , local_cxy , cycle );
524#endif
525
[1]526} // end cluster_pid_release()
527
528///////////////////////////////////////////////////////////
529process_t * cluster_get_local_process_from_pid( pid_t pid )
530{
[23]531    xptr_t         process_xp;
532    process_t    * process_ptr;
533    xptr_t         root_xp;
534    xptr_t         iter_xp;
535    bool_t         found;
[19]536
[23]537    found   = false;
538    root_xp = XPTR( local_cxy , &LOCAL_CLUSTER->pmgr.local_root );
539
540    XLIST_FOREACH( root_xp , iter_xp )
[1]541    {
[23]542        process_xp  = XLIST_ELEMENT( iter_xp , process_t , local_list );
543        process_ptr = (process_t *)GET_PTR( process_xp );
544        if( process_ptr->pid == pid )
[1]545        {
[23]546            found = true;
[1]547            break;
548        }
549    }
550
[23]551    if (found ) return process_ptr;
552    else        return NULL;
553
[1]554}  // end cluster_get_local_process_from_pid()
555
556//////////////////////////////////////////////////////
557void cluster_process_local_link( process_t * process )
558{
559    pmgr_t * pm = &LOCAL_CLUSTER->pmgr;
560
[443]561    // get extended pointers on local process list root & lock
562    xptr_t root_xp = XPTR( local_cxy , &pm->local_root );
563    xptr_t lock_xp = XPTR( local_cxy , &pm->local_lock );
564
[564]565    // get lock protecting the local list
566    remote_queuelock_acquire( lock_xp );
[1]567
[443]568    // register process in local list
569    xlist_add_last( root_xp , XPTR( local_cxy , &process->local_list ) );
[1]570    pm->local_nr++;
571
[564]572    // release lock protecting the local list
573    remote_queuelock_release( lock_xp );
[1]574}
575
576////////////////////////////////////////////////////////
577void cluster_process_local_unlink( process_t * process )
578{
579    pmgr_t * pm = &LOCAL_CLUSTER->pmgr;
580
[443]581    // get extended pointers on local process list lock
582    xptr_t lock_xp = XPTR( local_cxy , &pm->local_lock );
583
[564]584    // get lock protecting the local list
585    remote_queuelock_acquire( lock_xp );
[1]586
[443]587    // remove process from local list
[23]588    xlist_unlink( XPTR( local_cxy , &process->local_list ) );
[1]589    pm->local_nr--;
590
[564]591    // release lock protecting the local list
592    remote_queuelock_release( lock_xp );
[1]593}
594
595///////////////////////////////////////////////////////
596void cluster_process_copies_link( process_t * process )
597{
598    pmgr_t * pm = &LOCAL_CLUSTER->pmgr;
599
[438]600#if DEBUG_CLUSTER_PROCESS_COPIES
[436]601uint32_t cycle = (uint32_t)hal_get_cycles();
[438]602if( DEBUG_CLUSTER_PROCESS_COPIES < cycle )
[436]603printk("\n[DBG] %s enters / cluster %x / process %x / cycle %d\n",
604__FUNCTION__ , local_cxy , process , cycle );
605#endif
606
[1]607    // get owner cluster identifier CXY and process LPID
608    pid_t    pid        = process->pid;
609    cxy_t    owner_cxy  = CXY_FROM_PID( pid );
610    lpid_t   lpid       = LPID_FROM_PID( pid );
611
612    // get extended pointer on lock protecting copies_list[lpid]
[120]613    xptr_t copies_lock  = XPTR( owner_cxy , &pm->copies_lock[lpid] );
[1]614
615    // get extended pointer on the copies_list[lpid] root
[120]616    xptr_t copies_root  = XPTR( owner_cxy , &pm->copies_root[lpid] );
[1]617
618    // get extended pointer on the local copies_list entry
619    xptr_t copies_entry = XPTR( local_cxy , &process->copies_list );
620
[19]621    // get lock protecting copies_list[lpid]
[564]622    remote_queuelock_acquire( copies_lock );
[1]623
[436]624    // add copy to copies_list
[1]625    xlist_add_first( copies_root , copies_entry );
626    hal_remote_atomic_add( XPTR( owner_cxy , &pm->copies_nr[lpid] ) , 1 );
627
[19]628    // release lock protecting copies_list[lpid]
[564]629    remote_queuelock_release( copies_lock );
[1]630
[438]631#if DEBUG_CLUSTER_PROCESS_COPIES
[436]632cycle = (uint32_t)hal_get_cycles();
[438]633if( DEBUG_CLUSTER_PROCESS_COPIES < cycle )
[436]634printk("\n[DBG] %s exit / cluster %x / process %x / cycle %d\n",
635__FUNCTION__ , local_cxy , process , cycle );
636#endif
637
638}  // end cluster_process_copies_link()
639
[1]640/////////////////////////////////////////////////////////
641void cluster_process_copies_unlink( process_t * process )
642{
643    pmgr_t * pm = &LOCAL_CLUSTER->pmgr;
644
[438]645#if DEBUG_CLUSTER_PROCESS_COPIES
[436]646uint32_t cycle = (uint32_t)hal_get_cycles();
[438]647if( DEBUG_CLUSTER_PROCESS_COPIES < cycle )
[436]648printk("\n[DBG] %s enters / cluster %x / process %x / cycle %d\n",
649__FUNCTION__ , local_cxy , process , cycle );
650#endif
651
[1]652    // get owner cluster identifier CXY and process LPID
653    pid_t    pid        = process->pid;
654    cxy_t    owner_cxy  = CXY_FROM_PID( pid );
655    lpid_t   lpid       = LPID_FROM_PID( pid );
656
657    // get extended pointer on lock protecting copies_list[lpid]
[436]658    xptr_t copies_lock  = XPTR( owner_cxy , &pm->copies_lock[lpid] );
[1]659
660    // get extended pointer on the local copies_list entry
661    xptr_t copies_entry = XPTR( local_cxy , &process->copies_list );
662
[19]663    // get lock protecting copies_list[lpid]
[564]664    remote_queuelock_acquire( copies_lock );
[1]665
[436]666    // remove copy from copies_list
[1]667    xlist_unlink( copies_entry );
668    hal_remote_atomic_add( XPTR( owner_cxy , &pm->copies_nr[lpid] ) , -1 );
669
[19]670    // release lock protecting copies_list[lpid]
[564]671    remote_queuelock_release( copies_lock );
[1]672
[438]673#if DEBUG_CLUSTER_PROCESS_COPIES
[436]674cycle = (uint32_t)hal_get_cycles();
[438]675if( DEBUG_CLUSTER_PROCESS_COPIES < cycle )
[436]676printk("\n[DBG] %s exit / cluster %x / process %x / cycle %d\n",
677__FUNCTION__ , local_cxy , process , cycle );
678#endif
679
680}  // end cluster_process_copies_unlink()
681
[428]682///////////////////////////////////////////
683void cluster_processes_display( cxy_t cxy )
[1]684{
[428]685    xptr_t        root_xp;
[443]686    xptr_t        lock_xp;
[428]687    xptr_t        iter_xp;
[443]688    xptr_t        process_xp;
689    cxy_t         txt0_cxy;
690    chdev_t     * txt0_ptr;
691    xptr_t        txt0_xp;
692    xptr_t        txt0_lock_xp;
[1]693
[443]694    assert( (cluster_is_undefined( cxy ) == false),
[492]695    "illegal cluster index" );
[443]696
697    // get extended pointer on root and lock for local process list in cluster
[428]698    root_xp = XPTR( cxy , &LOCAL_CLUSTER->pmgr.local_root );
[443]699    lock_xp = XPTR( cxy , &LOCAL_CLUSTER->pmgr.local_lock );
[1]700
[443]701    // get pointers on TXT0 chdev
702    txt0_xp  = chdev_dir.txt_tx[0];
703    txt0_cxy = GET_CXY( txt0_xp );
704    txt0_ptr = GET_PTR( txt0_xp );
[1]705
[443]706    // get extended pointer on TXT0 lock
707    txt0_lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
708
709    // get lock on local process list
[564]710    remote_queuelock_acquire( lock_xp );
[443]711
[564]712    // get TXT0 lock
713    remote_busylock_acquire( txt0_lock_xp );
[443]714     
715    // display header
716    nolock_printk("\n***** processes in cluster %x / cycle %d\n",
717    cxy , (uint32_t)hal_get_cycles() );
718
719    // loop on all processes in cluster cxy
[428]720    XLIST_FOREACH( root_xp , iter_xp )
721    {
722        process_xp = XLIST_ELEMENT( iter_xp , process_t , local_list );
723        process_display( process_xp );
724    }
[443]725
[564]726    // release TXT0 lock
727    remote_busylock_release( txt0_lock_xp );
[443]728
729    // release lock on local process list
[564]730    remote_queuelock_release( lock_xp );
[443]731
[428]732}  // end cluster_processes_display()
[1]733
[19]734
Note: See TracBrowser for help on using the repository browser.