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

Last change on this file since 635 was 635, checked in by alain, 15 months ago

This version is a major evolution: The physical memory allocators,
defined in the kmem.c, ppm.c, and kcm.c files have been modified
to support remote accesses. The RPCs that were previously user
to allocate physical memory in a remote cluster have been removed.
This has been done to cure a dead-lock in case of concurrent page-faults.

This version 2.2 has been tested on a (4 clusters / 2 cores per cluster)
TSAR architecture, for both the "sort" and the "fft" applications.

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