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

Last change on this file since 627 was 627, checked in by alain, 5 years ago

Replace the queuelock protectingthe FAT by a rwlock in the FATFS.

File size: 23.2 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
[593]115uint32_t   cycle = (uint32_t)hal_get_cycles();
116thread_t * this  = CURRENT_THREAD;
[438]117if( DEBUG_CLUSTER_INIT < cycle )
[593]118printk("\n[%s] thread[%x,%x] enters for cluster %x / cycle %d\n",
119__FUNCTION__, this->process->pid, this->trdid, local_cxy , cycle );
[433]120#endif
[50]121
[1]122    // initialises embedded PPM
[50]123        error = hal_ppm_init( info );
[1]124
[50]125    if( error )
126    {
127        printk("\n[ERROR] in %s : cannot initialize PPM in cluster %x\n",
128               __FUNCTION__ , local_cxy );
129        return ENOMEM;
130    }
131
[438]132#if( DEBUG_CLUSTER_INIT & 1 )
[433]133cycle = (uint32_t)hal_get_cycles();
[438]134if( DEBUG_CLUSTER_INIT < cycle )
[593]135printk("\n[%s] PPM initialized in cluster %x / cycle %d\n",
[433]136__FUNCTION__ , local_cxy , cycle );
137#endif
[50]138
[1]139    // initialises embedded KHM
140        khm_init( &cluster->khm );
[19]141
[438]142#if( DEBUG_CLUSTER_INIT & 1 )
[457]143cycle = (uint32_t)hal_get_cycles();
[438]144if( DEBUG_CLUSTER_INIT < cycle )
[593]145printk("\n[%s] KHM initialized in cluster %x at cycle %d\n",
[437]146__FUNCTION__ , local_cxy , hal_get_cycles() );
147#endif
[50]148
[19]149    // initialises embedded KCM
[5]150        kcm_init( &cluster->kcm , KMEM_KCM );
[1]151
[438]152#if( DEBUG_CLUSTER_INIT & 1 )
[457]153cycle = (uint32_t)hal_get_cycles();
[438]154if( DEBUG_CLUSTER_INIT < cycle )
[593]155printk("\n[%s] KCM initialized in cluster %x at cycle %d\n",
[437]156__FUNCTION__ , local_cxy , hal_get_cycles() );
157#endif
[50]158
[296]159    // initialises all cores descriptors
[1]160        for( lid = 0 ; lid < cluster->cores_nr; lid++ )
161        {
162                core_init( &cluster->core_tbl[lid],    // target core descriptor
163                       lid,                        // local core index
164                       info->core[lid].gid );      // gid from boot_info_t
165        }
[19]166
[438]167#if( DEBUG_CLUSTER_INIT & 1 )
[433]168cycle = (uint32_t)hal_get_cycles();
[438]169if( DEBUG_CLUSTER_INIT < cycle )
[593]170printk("\n[%s] cores initialized in cluster %x / cycle %d\n",
[433]171__FUNCTION__ , local_cxy , cycle );
172#endif
[50]173
[440]174    // initialises RPC FIFOs
175        for( lid = 0 ; lid < cluster->cores_nr; lid++ )
176    {
[564]177            remote_fifo_init( &cluster->rpc_fifo[lid] );
[440]178        cluster->rpc_threads[lid] = 0;
179    }
[1]180
[438]181#if( DEBUG_CLUSTER_INIT & 1 )
[437]182cycle = (uint32_t)hal_get_cycles();
[438]183if( DEBUG_CLUSTER_INIT < cycle )
[593]184printk("\n[%s] RPC fifo inialized in cluster %x at cycle %d\n",
[407]185__FUNCTION__ , local_cxy , hal_get_cycles() );
[437]186#endif
[50]187
[1]188    // initialise pref_tbl[] in process manager
[564]189        queuelock_init( &cluster->pmgr.pref_lock , LOCK_CLUSTER_PREFTBL );
[1]190    cluster->pmgr.pref_nr = 0;
[19]191    cluster->pmgr.pref_tbl[0] = XPTR( local_cxy , &process_zero );
[580]192    for( lpid = 0 ; lpid < CONFIG_MAX_PROCESS_PER_CLUSTER ; lpid++ )
[1]193    {
194        cluster->pmgr.pref_tbl[lpid] = XPTR_NULL;
195    }
196
197    // initialise local_list in process manager
[23]198    xlist_root_init( XPTR( local_cxy , &cluster->pmgr.local_root ) );
[1]199    cluster->pmgr.local_nr = 0;
[564]200        remote_queuelock_init( XPTR( local_cxy , &cluster->pmgr.local_lock ) ,
201                           LOCK_CLUSTER_LOCALS );
[1]202
203    // initialise copies_lists in process manager
[101]204    for( lpid = 0 ; lpid < CONFIG_MAX_PROCESS_PER_CLUSTER ; lpid++ )
[1]205    {
206        cluster->pmgr.copies_nr[lpid] = 0;
207        xlist_root_init( XPTR( local_cxy , &cluster->pmgr.copies_root[lpid] ) );
[564]208            remote_queuelock_init( XPTR( local_cxy , &cluster->pmgr.copies_lock[lpid] ),
209                               LOCK_CLUSTER_COPIES );
[19]210    }
[1]211
[438]212#if DEBUG_CLUSTER_INIT
[433]213cycle = (uint32_t)hal_get_cycles();
[438]214if( DEBUG_CLUSTER_INIT < cycle )
[593]215printk("\n[%s] thread[%x,%x] exit for cluster %x / cycle %d\n",
216__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
[433]217#endif
[50]218
[124]219    hal_fence();
[1]220
221        return 0;
[564]222} // end cluster_manager_init()
[1]223
[564]224///////////////////////////////////
[561]225cxy_t cluster_random_select( void )
226{
227    uint32_t  index;
[564]228    uint32_t  x;   
[561]229    uint32_t  y;
[564]230    cxy_t     cxy;
[561]231
[564]232    uint32_t  x_size    = LOCAL_CLUSTER->x_size;
233    uint32_t  y_size    = LOCAL_CLUSTER->y_size;
234
235    do 
236    {
[561]237        index     = ( hal_get_cycles() + hal_get_gid() ) % (x_size * y_size);
238        x         = index / y_size;
239        y         = index % y_size;
[564]240        cxy       = HAL_CXY_FROM_XY( x , y );
241    }
242    while ( cluster_is_active( cxy ) == false );
[561]243
[564]244    return ( cxy );
[561]245}
246
[1]247////////////////////////////////////////
248bool_t cluster_is_undefined( cxy_t cxy )
249{
[564]250    uint32_t  x_size = LOCAL_CLUSTER->x_size;
251    uint32_t  y_size = LOCAL_CLUSTER->y_size;
[1]252
[564]253    uint32_t  x      = HAL_X_FROM_CXY( cxy );
254    uint32_t  y      = HAL_Y_FROM_CXY( cxy );
[1]255
[564]256    if( x >= x_size ) return true;
257    if( y >= y_size ) return true;
[1]258
259    return false;
260}
261
[564]262//////////////////////////////////////
263bool_t cluster_is_active ( cxy_t cxy )
264{
265    uint32_t x = HAL_X_FROM_CXY( cxy );
266    uint32_t y = HAL_Y_FROM_CXY( cxy );
267
268    return ( LOCAL_CLUSTER->cluster_info[x][y] != 0 );
269}
270
[1]271////////////////////////////////////////////////////////////////////////////////////
272//  Cores related functions
273////////////////////////////////////////////////////////////////////////////////////
274
[583]275///////////////////////////////////////
[485]276lid_t cluster_select_local_core( void )
[1]277{
[440]278    uint32_t      min = 1000;
279    lid_t         sel = 0;
280    uint32_t      nthreads;
281    lid_t         lid;
282    scheduler_t * sched;
[1]283
284    cluster_t * cluster = LOCAL_CLUSTER;
285
286    for( lid = 0 ; lid < cluster->cores_nr ; lid++ )
287    {
[440]288        sched    = &cluster->core_tbl[lid].scheduler;
289        nthreads = sched->u_threads_nr + sched->k_threads_nr;
290
291        if( nthreads < min )
[1]292        {
[440]293            min = nthreads;
[1]294            sel = lid;
295        }
[19]296    }
[1]297    return sel;
298}
299
300////////////////////////////////////////////////////////////////////////////////////
[428]301//  Process related functions
[1]302////////////////////////////////////////////////////////////////////////////////////
303
[433]304
305//////////////////////////////////////////////////////
[443]306xptr_t cluster_get_process_from_pid_in_cxy( cxy_t cxy,
307                                            pid_t pid )
308{
309    xptr_t      root_xp;       // xptr on root of list of processes in owner cluster
310    xptr_t      lock_xp;       // xptr on lock protecting this list
311    xptr_t      iter_xp;       // iterator
312    xptr_t      current_xp;    // xptr on current process descriptor
313    bool_t      found;
314
315    cluster_t * cluster = LOCAL_CLUSTER;
316
317    // get owner cluster and lpid
318    cxy_t   owner_cxy = CXY_FROM_PID( pid );
319    lpid_t  lpid      = LPID_FROM_PID( pid );
320
321    // get lock & root of list of copies from owner cluster
322    root_xp = XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] );
323    lock_xp = XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] );
324
325    // take the lock protecting the list of processes
[564]326    remote_queuelock_acquire( lock_xp );
[443]327
328    // scan list of processes
329    found = false;
330    XLIST_FOREACH( root_xp , iter_xp )
331    {
332        current_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
333
334        if( GET_CXY( current_xp ) == cxy )
335        {
336            found = true;
337            break;
338        }
339    }
340
341    // release the lock protecting the list of processes
[564]342    remote_queuelock_release( lock_xp );
[443]343
344    // return extended pointer on process descriptor in owner cluster
345    if( found ) return current_xp;
346    else        return XPTR_NULL;
347
348}  // end cluster_get_process_from_pid_in_cxy()
349
350
351//////////////////////////////////////////////////////
[433]352xptr_t cluster_get_owner_process_from_pid( pid_t pid )
353{
354    xptr_t      root_xp;       // xptr on root of list of processes in owner cluster
[436]355    xptr_t      lock_xp;       // xptr on lock protecting this list
[433]356    xptr_t      iter_xp;       // iterator
357    xptr_t      current_xp;    // xptr on current process descriptor
358    process_t * current_ptr;   // local pointer on current process
359    pid_t       current_pid;   // current process identifier
360    bool_t      found;
361
362    cluster_t * cluster = LOCAL_CLUSTER;
363
364    // get owner cluster and lpid
365    cxy_t  owner_cxy = CXY_FROM_PID( pid );
366
367    // get lock & root of list of process in owner cluster
368    root_xp = XPTR( owner_cxy , &cluster->pmgr.local_root );
369    lock_xp = XPTR( owner_cxy , &cluster->pmgr.local_lock );
370
371    // take the lock protecting the list of processes
[564]372    remote_queuelock_acquire( lock_xp );
[433]373
374    // scan list of processes in owner cluster
375    found = false;
376    XLIST_FOREACH( root_xp , iter_xp )
377    {
378        current_xp  = XLIST_ELEMENT( iter_xp , process_t , local_list );
379        current_ptr = GET_PTR( current_xp );
[564]380        current_pid = hal_remote_l32( XPTR( owner_cxy , &current_ptr->pid ) );
[433]381
382        if( current_pid == pid )
383        {
384            found = true;
385            break;
386        }
387    }
388
389    // release the lock protecting the list of processes
[564]390    remote_queuelock_release( lock_xp );
[433]391
392    // return extended pointer on process descriptor in owner cluster
393    if( found ) return current_xp;
394    else        return XPTR_NULL;
395
[436]396}  // end cluster_get_owner_process_from_pid()
397
[443]398
[1]399//////////////////////////////////////////////////////////
400xptr_t cluster_get_reference_process_from_pid( pid_t pid )
[19]401{
[23]402    xptr_t ref_xp;   // extended pointer on reference process descriptor
[1]403
404    cluster_t * cluster = LOCAL_CLUSTER;
405
406    // get owner cluster and lpid
407    cxy_t  owner_cxy = CXY_FROM_PID( pid );
408    lpid_t lpid      = LPID_FROM_PID( pid );
409
[19]410    // Check valid PID
[23]411    if( lpid >= CONFIG_MAX_PROCESS_PER_CLUSTER )  return XPTR_NULL;
[1]412
413    if( local_cxy == owner_cxy )   // local cluster is owner cluster
[19]414    {
[23]415        ref_xp = cluster->pmgr.pref_tbl[lpid];
[1]416    }
417    else                              // use a remote_lwd to access owner cluster
418    {
[564]419        ref_xp = (xptr_t)hal_remote_l64( XPTR( owner_cxy , &cluster->pmgr.pref_tbl[lpid] ) );
[1]420    }
421
[23]422    return ref_xp;
[1]423}
424
[416]425///////////////////////////////////////////////
426error_t cluster_pid_alloc( process_t * process,
427                           pid_t     * pid )
[1]428{
429    lpid_t      lpid;
430    bool_t      found;
431
[440]432#if DEBUG_CLUSTER_PID_ALLOC
[593]433uint32_t   cycle = (uint32_t)hal_get_cycles();
434thread_t * this  = CURRENT_THREAD;
[440]435if( DEBUG_CLUSTER_PID_ALLOC < cycle )
[593]436printk("\n[%s] thread[%x,%x] enters in cluster %x / cycle %d\n",
437__FUNCTION__ , this->process->pid , this->trdid , local_cxy , cycle );
[440]438#endif
439
[1]440    pmgr_t    * pm         = &LOCAL_CLUSTER->pmgr;
441
[564]442    // get the lock protecting pref_tbl
443    queuelock_acquire( &pm->pref_lock );
[1]444
445    // search an empty slot
446    found = false;
447    for( lpid = 0 ; lpid < CONFIG_MAX_PROCESS_PER_CLUSTER ; lpid++ )
448    {
449        if( pm->pref_tbl[lpid] == XPTR_NULL )
450        {
451            found = true;
452            break;
453        }
454    }
455
456    if( found )
457    {
458        // register process in pref_tbl[]
[416]459        pm->pref_tbl[lpid] = XPTR( local_cxy , process );
[1]460        pm->pref_nr++;
461
462        // returns pid
463        *pid = PID( local_cxy , lpid );
464
[416]465        // release the processs_manager lock
[564]466        queuelock_release( &pm->pref_lock );
[416]467
468        return 0;
[1]469    }
470    else
471    {
[564]472        // release the lock
473        queuelock_release( &pm->pref_lock );
[416]474
[564]475        return 0xFFFFFFFF;
[19]476    }
[1]477
[440]478#if DEBUG_CLUSTER_PID_ALLOC
479cycle = (uint32_t)hal_get_cycles();
480if( DEBUG_CLUSTER_PID_ALLOC < cycle )
[593]481printk("\n[%s] thread[%x,%x] exit in cluster %x / cycle %d\n",
482__FUNCTION__ , this->process->pid , this->trdid , local_cxy , cycle );
[440]483#endif
484
[1]485} // end cluster_pid_alloc()
486
487/////////////////////////////////////
488void cluster_pid_release( pid_t pid )
489{
[440]490
491#if DEBUG_CLUSTER_PID_RELEASE
[593]492uint32_t   cycle = (uint32_t)hal_get_cycles();
493thread_t * this  = CURRENT_THREAD;
494if( DEBUG_CLUSTER_PID_ALLOC < cycle )
495printk("\n[%s] thread[%x,%x] enters in cluster %x / pid %x / cycle %d\n",
496__FUNCTION__ , this->process->pid , this->trdid , local_cxy , pid, cycle );
[440]497#endif
498
[1]499    cxy_t  owner_cxy  = CXY_FROM_PID( pid );
500    lpid_t lpid       = LPID_FROM_PID( pid );
501
[409]502    pmgr_t  * pm = &LOCAL_CLUSTER->pmgr;
503
[440]504    // check lpid
[492]505    assert( (lpid < CONFIG_MAX_PROCESS_PER_CLUSTER),
[440]506    "illegal LPID = %d" , lpid );
[1]507
[440]508    // check owner cluster
[492]509    assert( (owner_cxy == local_cxy) ,
[440]510    "local_cluster %x !=  owner_cluster %x" , local_cxy , owner_cxy );
511
[564]512    // get the lock protecting pref_tbl
513    queuelock_acquire( &pm->pref_lock );
[1]514
515    // remove process from pref_tbl[]
516    pm->pref_tbl[lpid] = XPTR_NULL;
517    pm->pref_nr--;
518
519    // release the processs_manager lock
[564]520    queuelock_release( &pm->pref_lock );
[1]521
[440]522#if DEBUG_CLUSTER_PID_RELEASE
523cycle = (uint32_t)hal_get_cycles();
[593]524if( DEBUG_CLUSTER_PID_ALLOC < cycle )
525printk("\n[%s] thread[%x,%x] exit in cluster %x / cycle %d\n",
526__FUNCTION__ , this->process->pid , this->trdid , local_cxy , cycle );
[440]527#endif
528
[1]529} // end cluster_pid_release()
530
531///////////////////////////////////////////////////////////
532process_t * cluster_get_local_process_from_pid( pid_t pid )
533{
[23]534    xptr_t         process_xp;
535    process_t    * process_ptr;
536    xptr_t         root_xp;
537    xptr_t         iter_xp;
538    bool_t         found;
[19]539
[23]540    found   = false;
541    root_xp = XPTR( local_cxy , &LOCAL_CLUSTER->pmgr.local_root );
542
543    XLIST_FOREACH( root_xp , iter_xp )
[1]544    {
[23]545        process_xp  = XLIST_ELEMENT( iter_xp , process_t , local_list );
546        process_ptr = (process_t *)GET_PTR( process_xp );
547        if( process_ptr->pid == pid )
[1]548        {
[23]549            found = true;
[1]550            break;
551        }
552    }
553
[23]554    if (found ) return process_ptr;
555    else        return NULL;
556
[1]557}  // end cluster_get_local_process_from_pid()
558
559//////////////////////////////////////////////////////
560void cluster_process_local_link( process_t * process )
561{
562    pmgr_t * pm = &LOCAL_CLUSTER->pmgr;
563
[443]564    // get extended pointers on local process list root & lock
565    xptr_t root_xp = XPTR( local_cxy , &pm->local_root );
566    xptr_t lock_xp = XPTR( local_cxy , &pm->local_lock );
567
[564]568    // get lock protecting the local list
569    remote_queuelock_acquire( lock_xp );
[1]570
[443]571    // register process in local list
572    xlist_add_last( root_xp , XPTR( local_cxy , &process->local_list ) );
[1]573    pm->local_nr++;
574
[564]575    // release lock protecting the local list
576    remote_queuelock_release( lock_xp );
[1]577}
578
579////////////////////////////////////////////////////////
580void cluster_process_local_unlink( process_t * process )
581{
582    pmgr_t * pm = &LOCAL_CLUSTER->pmgr;
583
[443]584    // get extended pointers on local process list lock
585    xptr_t lock_xp = XPTR( local_cxy , &pm->local_lock );
586
[564]587    // get lock protecting the local list
588    remote_queuelock_acquire( lock_xp );
[1]589
[443]590    // remove process from local list
[23]591    xlist_unlink( XPTR( local_cxy , &process->local_list ) );
[1]592    pm->local_nr--;
593
[564]594    // release lock protecting the local list
595    remote_queuelock_release( lock_xp );
[1]596}
597
598///////////////////////////////////////////////////////
599void cluster_process_copies_link( process_t * process )
600{
601    pmgr_t * pm = &LOCAL_CLUSTER->pmgr;
602
[438]603#if DEBUG_CLUSTER_PROCESS_COPIES
[593]604uint32_t   cycle = (uint32_t)hal_get_cycles();
605thread_t * this  = CURRENT_THREAD;
[438]606if( DEBUG_CLUSTER_PROCESS_COPIES < cycle )
[593]607printk("\n[%s] thread[%x,%x] enters for process %x / cycle %d\n",
608__FUNCTION__ , this->process->pid , this->trdid , process->pid , cycle );
[436]609#endif
610
[1]611    // get owner cluster identifier CXY and process LPID
612    pid_t    pid        = process->pid;
613    cxy_t    owner_cxy  = CXY_FROM_PID( pid );
614    lpid_t   lpid       = LPID_FROM_PID( pid );
615
616    // get extended pointer on lock protecting copies_list[lpid]
[120]617    xptr_t copies_lock  = XPTR( owner_cxy , &pm->copies_lock[lpid] );
[1]618
619    // get extended pointer on the copies_list[lpid] root
[120]620    xptr_t copies_root  = XPTR( owner_cxy , &pm->copies_root[lpid] );
[1]621
622    // get extended pointer on the local copies_list entry
623    xptr_t copies_entry = XPTR( local_cxy , &process->copies_list );
624
[19]625    // get lock protecting copies_list[lpid]
[564]626    remote_queuelock_acquire( copies_lock );
[1]627
[436]628    // add copy to copies_list
[1]629    xlist_add_first( copies_root , copies_entry );
630    hal_remote_atomic_add( XPTR( owner_cxy , &pm->copies_nr[lpid] ) , 1 );
631
[19]632    // release lock protecting copies_list[lpid]
[564]633    remote_queuelock_release( copies_lock );
[1]634
[438]635#if DEBUG_CLUSTER_PROCESS_COPIES
[436]636cycle = (uint32_t)hal_get_cycles();
[438]637if( DEBUG_CLUSTER_PROCESS_COPIES < cycle )
[593]638printk("\n[%s] thread[%x,%x] exit for process %x / cycle %d\n",
639__FUNCTION__ , this->process->pid , this->trdid , process->pid , cycle );
[436]640#endif
641
642}  // end cluster_process_copies_link()
643
[1]644/////////////////////////////////////////////////////////
645void cluster_process_copies_unlink( process_t * process )
646{
647    pmgr_t * pm = &LOCAL_CLUSTER->pmgr;
648
[438]649#if DEBUG_CLUSTER_PROCESS_COPIES
[593]650uint32_t   cycle = (uint32_t)hal_get_cycles();
651thread_t * this  = CURRENT_THREAD;
[438]652if( DEBUG_CLUSTER_PROCESS_COPIES < cycle )
[593]653printk("\n[%s] thread[%x,%x] enters for process %x / cycle %d\n",
654__FUNCTION__ , this->process->pid , this->trdid , process->pid , cycle );
[436]655#endif
656
[1]657    // get owner cluster identifier CXY and process LPID
658    pid_t    pid        = process->pid;
659    cxy_t    owner_cxy  = CXY_FROM_PID( pid );
660    lpid_t   lpid       = LPID_FROM_PID( pid );
661
662    // get extended pointer on lock protecting copies_list[lpid]
[436]663    xptr_t copies_lock  = XPTR( owner_cxy , &pm->copies_lock[lpid] );
[1]664
665    // get extended pointer on the local copies_list entry
666    xptr_t copies_entry = XPTR( local_cxy , &process->copies_list );
667
[19]668    // get lock protecting copies_list[lpid]
[564]669    remote_queuelock_acquire( copies_lock );
[1]670
[436]671    // remove copy from copies_list
[1]672    xlist_unlink( copies_entry );
673    hal_remote_atomic_add( XPTR( owner_cxy , &pm->copies_nr[lpid] ) , -1 );
674
[19]675    // release lock protecting copies_list[lpid]
[564]676    remote_queuelock_release( copies_lock );
[1]677
[438]678#if DEBUG_CLUSTER_PROCESS_COPIES
[436]679cycle = (uint32_t)hal_get_cycles();
[438]680if( DEBUG_CLUSTER_PROCESS_COPIES < cycle )
[593]681printk("\n[%s] thread[%x,%x] exit for process %x / cycle %d\n",
682__FUNCTION__ , this->process->pid , this->trdid , process->pid , cycle );
[436]683#endif
684
685}  // end cluster_process_copies_unlink()
686
[583]687////////////////////////////////////////////
688void cluster_processes_display( cxy_t   cxy,
689                                bool_t  owned )
[1]690{
[428]691    xptr_t        root_xp;
[443]692    xptr_t        lock_xp;
[428]693    xptr_t        iter_xp;
[443]694    xptr_t        process_xp;
[583]695    process_t   * process_ptr;
696    cxy_t         process_cxy;
697    pid_t         pid;
[443]698    cxy_t         txt0_cxy;
699    chdev_t     * txt0_ptr;
700    xptr_t        txt0_xp;
701    xptr_t        txt0_lock_xp;
[627]702    uint32_t      pref_nr;       // number of owned processes in cluster cxy
[1]703
[583]704assert( (cluster_is_undefined( cxy ) == false), "illegal cluster index" );
[443]705
706    // get extended pointer on root and lock for local process list in cluster
[428]707    root_xp = XPTR( cxy , &LOCAL_CLUSTER->pmgr.local_root );
[443]708    lock_xp = XPTR( cxy , &LOCAL_CLUSTER->pmgr.local_lock );
[1]709
[627]710    // get number of owned processes in cluster cxy
711    pref_nr = hal_remote_l32( XPTR( cxy , &LOCAL_CLUSTER->pmgr.pref_nr ) );
712
713    // display nothing if no user process in cluster cxy
714    if( (owned != false) && (pref_nr < 2) ) return;
715   
[443]716    // get pointers on TXT0 chdev
717    txt0_xp  = chdev_dir.txt_tx[0];
718    txt0_cxy = GET_CXY( txt0_xp );
719    txt0_ptr = GET_PTR( txt0_xp );
[1]720
[443]721    // get extended pointer on TXT0 lock
722    txt0_lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
723
724    // get lock on local process list
[564]725    remote_queuelock_acquire( lock_xp );
[443]726
[564]727    // get TXT0 lock
728    remote_busylock_acquire( txt0_lock_xp );
[443]729     
730    nolock_printk("\n***** processes in cluster %x / cycle %d\n",
731    cxy , (uint32_t)hal_get_cycles() );
732
733    // loop on all processes in cluster cxy
[428]734    XLIST_FOREACH( root_xp , iter_xp )
735    {
[583]736        process_xp  = XLIST_ELEMENT( iter_xp , process_t , local_list );
737        process_ptr = GET_PTR( process_xp );
738        process_cxy = GET_CXY( process_xp );
739
740        // get process PID
741        pid = hal_remote_l32( XPTR( process_cxy , &process_ptr->pid ) );
742
743        if( owned )  // display only user & owned processes
744        {
745            if( (CXY_FROM_PID( pid ) == cxy) && (LPID_FROM_PID( pid ) != 0) )
746            {
747                process_display( process_xp );
748            }
749        }
750        else         // display all local processes
751        {
752            process_display( process_xp );
753        }
[428]754    }
[443]755
[564]756    // release TXT0 lock
757    remote_busylock_release( txt0_lock_xp );
[443]758
759    // release lock on local process list
[564]760    remote_queuelock_release( lock_xp );
[443]761
[428]762}  // end cluster_processes_display()
[1]763
[19]764
Note: See TracBrowser for help on using the repository browser.