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

Last change on this file since 444 was 443, checked in by alain, 7 years ago

Fix few bugs whike debugging the sort multi-thread application.

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