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

Last change on this file since 690 was 683, checked in by alain, 4 years ago

All modifications required to support the <tcp_chat> application
including error recovery in case of packet loss.A

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