source: soft/giet_vm/applications/classif/main.c @ 695

Last change on this file since 695 was 669, checked in by alain, 9 years ago

Introduce support for the "shared" argument in the giet_tty_alloc() system call,
and replace the giet_shr_printf() system call by giet_tty_printf().

File size: 24.6 KB
RevLine 
[502]1///////////////////////////////////////////////////////////////////////////////////////
[457]2// File   : main.c   (for classif application)
3// Date   : november 2014
4// author : Alain Greiner
[502]5///////////////////////////////////////////////////////////////////////////////////////
[480]6// This multi-threaded application takes a stream of Gigabit Ethernet packets,
7// and makes packet analysis and classification, based on the source MAC address.
[488]8// It uses the NIC peripheral, and the distributed kernel chbufs accessed by the CMA
9// component to receive and send packets on the Gigabit Ethernet port.
[457]10//
[502]11// It can run on architectures containing up to 16 * 16 clusters,
12// and up to 8 processors per cluster.
13//
[669]14// It requires N+2 TTY terminals, as each task in cluster[0][0] displays messages.
15//
[502]16// This application is described as a TCG (Task and Communication Graph)
17// containing (N+2) tasks per cluster:
[488]18// - one "load" task
[502]19// - one "store" task
[488]20// - N "analyse" tasks
[502]21// The containers are distributed (N+2 containers per cluster):
[488]22// - one RX container (part of the kernel rx_chbuf), in the kernel heap.
23// - one TX container (part of the kernel tx-chbuf), in the kernel heap.
24// - N working containers (one per analysis task), in the user heap.
25// In each cluster, the "load", analysis" and "store" tasks communicates through
26// three local MWMR fifos:
27// - fifo_l2a : tranfer a full container from "load" to "analyse" task.
28// - fifo_a2s : transfer a full container from "analyse" to "store" task.
29// - fifo_s2l : transfer an empty container from "store" to "load" task.
30// For each fifo, one item is a 32 bits word defining the index of an
31// available working container.
32// The pointers on the working containers, and the pointers on the MWMR fifos
33// are global arrays stored in cluster[0][0].
[457]34// a local MWMR fifo containing NB_PROCS_MAX containers (one item = one container).
[480]35// The MWMR fifo descriptors array is defined as a global variable in cluster[0][0].
[457]36//
[542]37// Initialisation is done in three steps by the "load" & "store" tasks:
[549]38// 1) Task "load" in cluster[0][0] initialises the heaps in all clusters. Other tasks
39//    are waiting on the global_sync synchronisation variable.
40// 2) Then task "load" in cluster[0][0] initialises the barrier between all "load"
41//    tasks, allocates NIC & CMA RX channel, and starts the NIC_CMA RX transfer.
42//    Other "load" tasks are waiting on the load_sync synchronisation variable.
43//    Task "store" in cluster[0][0] initialises the barrier between all "store" tasks,
44//    allocates NIC & CMA TX channels, and starts the NIC_CMA TX transfer.
45//    Other "store" tasks are waiting on the store_sync synchronisation variable.
46// 3) When this global initialisation is completed, the "load" task in all clusters
47//    allocates the working containers and the MWMR fifos descriptors from the
48//    user local heap. In each cluster, the "analyse" and "store" tasks are waiting
49//    the local initialisation completion on the local_sync[x][y] variables.
[488]50//
51// When initialisation is completed, all tasks loop on containers:
52// 1) The "load" task get an empty working container from the fifo_s2l,
53//    transfer one container from the kernel rx_chbuf to this user container,
54//    and transfer ownership of this container to one "analysis" task by writing
55//    into the fifo_l2a.   
56// 2) The "analyse" task get one working container from the fifo_l2a, analyse
57//    each packet header, compute the packet type (depending on the SRC MAC address),
58//    increment the correspondint classification counter, and transpose the SRC
59//    and the DST MAC addresses fot TX tranmission.
60// 3) The "store" task transfer get a full working container from the fifo_a2s,
61//    transfer this user container content to the the kernel tx_chbuf,
62//    and transfer ownership of this empty container to the "load" task by writing
63//    into the fifo_s2l.   
[502]64//     
65// Instrumentation results display is done by the "store" task in cluster[0][0]
66// when all "store" tasks completed the number of clusters specified by the
67// CONTAINERS_MAX parameter.
68///////////////////////////////////////////////////////////////////////////////////////
[457]69
70#include "stdio.h"
[502]71#include "user_barrier.h"
[457]72#include "malloc.h"
73#include "user_lock.h"
74#include "mwmr_channel.h"
75
[502]76#define X_SIZE_MAX      16
77#define Y_SIZE_MAX      16
78#define NPROCS_MAX      8
[536]79#define CONTAINERS_MAX  50
[502]80#define VERBOSE_ANALYSE 0
[457]81
[502]82///////////////////////////////////////////////////////////////////////////////////////
[473]83//    Global variables
[488]84// The MWMR channels (descriptors and buffers), as well as the working containers
85// used by the "analysis" tasks are distributed in clusters.
[549]86// But the pointers on these distributed structures are stored in cluster[0][0].
[502]87///////////////////////////////////////////////////////////////////////////////////////
[457]88
[502]89// pointers on distributed containers
90unsigned int*       container[X_SIZE_MAX][Y_SIZE_MAX][NPROCS_MAX-2]; 
[457]91
[488]92// pointers on distributed mwmr fifos containing : temp[x][y][l] container descriptors
[502]93mwmr_channel_t*     mwmr_l2a[X_SIZE_MAX][Y_SIZE_MAX]; 
94mwmr_channel_t*     mwmr_a2s[X_SIZE_MAX][Y_SIZE_MAX];
95mwmr_channel_t*     mwmr_s2l[X_SIZE_MAX][Y_SIZE_MAX]; 
[457]96
[488]97// local synchros signaling local MWMR fifos initialisation completion
[502]98volatile unsigned int        local_sync[X_SIZE_MAX][Y_SIZE_MAX]; 
[457]99
[488]100// global synchro signaling global initialisation completion
[542]101volatile unsigned int        global_sync = 0;
102volatile unsigned int        load_sync   = 0; 
103volatile unsigned int        store_sync  = 0; 
[457]104
[488]105// instrumentation counters
106unsigned int        counter[16];
[457]107
[502]108// distributed barrier between "load" tasks
109giet_sqt_barrier_t  rx_barrier;
[457]110
[502]111// distributed barrier between "store" tasks
112giet_sqt_barrier_t  tx_barrier;
113
[488]114// NIC_RX and NIC_TX channel index
115unsigned int        nic_rx_channel;
116unsigned int        nic_tx_channel;
117
[480]118/////////////////////////////////////////
[457]119__attribute__ ((constructor)) void load()
[480]120/////////////////////////////////////////
[457]121{
[502]122    // each "load" task get platform parameters
[542]123    unsigned int    x_size;                     // number of clusters in a row
[502]124    unsigned int    y_size;                     // number of clusters in a column
125    unsigned int    nprocs;                     // number of processors per cluster
126    giet_procs_number( &x_size, &y_size, &nprocs );
127
128    giet_assert( (x_size <= X_SIZE_MAX) && 
129                 (y_size <= Y_SIZE_MAX) && 
130                 (nprocs <= NPROCS_MAX) , 
131                 "[CLASSIF ERROR] illegal platform parameters" );
132
[488]133    // each "load" task get processor identifiers
[457]134    unsigned int    x;
135    unsigned int    y;
136    unsigned int    l;
137    giet_proc_xyp( &x, &y, &l );
138
[542]139    // "load" task[0][0]
140    // - initialises the heap in every cluster
141    // - initialises barrier between all load tasks,
142    // - allocates the NIC & CMA RX channels, and start the NIC_CMA RX transfer.
[488]143    // Other "load" tasks wait completion
144    if ( (x==0) && (y==0) )
145    {
[669]146        // allocate a private TTY
147        giet_tty_alloc(0);
[549]148
149        giet_tty_printf("\n*** Task load on P[%d][%d][%d] starts at cycle %d\n"
[502]150                        "  x_size = %d / y_size = %d / nprocs = %d\n",
151                        x , y , l , giet_proctime() , x_size, y_size, nprocs );
[542]152
[549]153        unsigned int xid;  // x cluster coordinate index
154        unsigned int yid;  // y cluster coordinate index
[542]155
[549]156        for ( xid = 0 ; xid < x_size ; xid++ )
157        {
158                for ( yid = 0 ; yid < y_size ; yid++ )
159                {
160                    heap_init( xid, yid );
161                }
162        }
[542]163   
[549]164            global_sync = 1;
[542]165
[502]166        sqt_barrier_init( &rx_barrier, x_size , y_size , 1 );
167        nic_rx_channel = giet_nic_rx_alloc( x_size , y_size );
[488]168        giet_nic_rx_start( nic_rx_channel );
169        load_sync = 1;
170    }
171    else
172    {
173        while ( load_sync == 0 ) asm volatile ("nop");
174    }   
[457]175
[502]176    // each load tasks allocates containers[x][y][n] (from local heap)
[488]177    // and register pointers in the local stack
178    unsigned int   n;
[502]179    unsigned int*  cont[NPROCS_MAX-2]; 
180    unsigned int   analysis_tasks = nprocs-2;
[473]181
[502]182    for ( n = 0 ; n < analysis_tasks ; n++ )
[488]183    {
184        container[x][y][n] = malloc( 4096 );
185        cont[n]            = container[x][y][n];
186    }
187   
[502]188    // each load task allocates data buffers for mwmr fifos (from local heap)
189    unsigned int*  data_l2a = malloc( analysis_tasks<<2 );
190    unsigned int*  data_a2s = malloc( analysis_tasks<<2 );
191    unsigned int*  data_s2l = malloc( analysis_tasks<<2 );
[473]192
[502]193    // each load task allocates mwmr fifos descriptors (from local heap)
[488]194    mwmr_l2a[x][y] = malloc( sizeof(mwmr_channel_t) );
195    mwmr_a2s[x][y] = malloc( sizeof(mwmr_channel_t) );
196    mwmr_s2l[x][y] = malloc( sizeof(mwmr_channel_t) );
[473]197
[502]198    // each load task registers local pointers on mwmr fifos in local stack
[488]199    mwmr_channel_t* fifo_l2a = mwmr_l2a[x][y];
200    mwmr_channel_t* fifo_a2s = mwmr_a2s[x][y];
201    mwmr_channel_t* fifo_s2l = mwmr_s2l[x][y];
202
[502]203    // each load task initialises local mwmr fifos descriptors
[488]204    // ( width = 4 bytes / depth = number of analysis tasks )
[502]205    mwmr_init( fifo_l2a , data_l2a , 1 , analysis_tasks );
206    mwmr_init( fifo_a2s , data_a2s , 1 , analysis_tasks );
207    mwmr_init( fifo_s2l , data_s2l , 1 , analysis_tasks );
[488]208
209   
[502]210    // each load task initialises local containers as empty in fifo_s2l
211    for ( n = 0 ; n < analysis_tasks ; n++ ) mwmr_write( fifo_s2l , &n , 1 );
[488]212
[502]213    // each load task[x][y] signals mwmr fifos initialisation completion
[488]214    // to other tasks in same cluster[x][y]
215    local_sync[x][y] = 1;
216
[502]217    // load task[0][0] displays status
[488]218    if ( (x==0) && (y==0) )
[549]219    giet_tty_printf("\n*** Task load on P[%d,%d,%d] enters main loop at cycle %d\n"
[488]220                    "      nic_rx_channel = %d / nic_tx_channel = %d\n"
221                    "      &mwmr_l2a  = %x / &data_l2a  = %x\n"
222                    "      &mwmr_a2s  = %x / &data_a2s  = %x\n"
223                    "      &mwmr_s2l  = %x / &data_s2l  = %x\n"
224                    "      &cont[0]   = %x\n"
[473]225                    "      x_size = %d / y_size = %d / nprocs = %d\n",
[488]226                    x , y , l , giet_proctime(), 
227                    nic_rx_channel , nic_tx_channel,
228                    (unsigned int)fifo_l2a, (unsigned int)data_l2a,
229                    (unsigned int)fifo_a2s, (unsigned int)data_a2s,
230                    (unsigned int)fifo_s2l, (unsigned int)data_s2l,
231                    (unsigned int)cont[0],
[502]232                    x_size, y_size, nprocs );
[488]233 
234    /////////////////////////////////////////////////////////////
[502]235    // All load tasks enter the main loop (on containers)
236    unsigned int  count = 0;     // loaded containers count
237    unsigned int  index;         // available container index
238    unsigned int* temp;          // pointer on available container
[457]239
[488]240    while ( count < CONTAINERS_MAX ) 
241    { 
[502]242        // get one empty container index from fifo_s2l
[488]243        mwmr_read( fifo_s2l , &index , 1 );
244        temp = cont[index];
245
[502]246        // get one container from  kernel rx_chbuf
[488]247        giet_nic_rx_move( nic_rx_channel, temp );
248
249        // get packets number
250        unsigned int npackets = temp[0] & 0x0000FFFF;
251        unsigned int nwords   = temp[0] >> 16;
252
[502]253        if ( (x==0) && (y==0) )
[549]254        giet_tty_printf("\n*** Task load on P[%d,%d,%d] get container %d at cycle %d"
[488]255                        " : %d packets / %d words\n",
256                        x, y, l, count, giet_proctime(), npackets, nwords );
257
[502]258        // put the full container index to fifo_l2a
[488]259        mwmr_write( fifo_l2a, &index , 1 );
260
261        count++;
262    }
263
264    // all "load" tasks synchronise before stats
[502]265    sqt_barrier_wait( &rx_barrier );
[488]266
267    // "load" task[0][0] stops the NIC_CMA RX transfer and displays stats
268    if ( (x==0) && (y==0) ) 
[457]269    {
[488]270        giet_nic_rx_stop( nic_rx_channel );
271        giet_nic_rx_stats( nic_rx_channel );
272    }
[457]273
[488]274    // all "load" task exit
275    giet_exit("Task completed");
276 
277} // end load()
[457]278
279
[488]280//////////////////////////////////////////
281__attribute__ ((constructor)) void store()
282//////////////////////////////////////////
283{
[502]284    // each "load" task get platform parameters
285    unsigned int    x_size;                                             // number of clusters in row
286    unsigned int    y_size;                     // number of clusters in a column
287    unsigned int    nprocs;                     // number of processors per cluster
288    giet_procs_number( &x_size, &y_size, &nprocs );
289
[488]290    // get processor identifiers
291    unsigned int    x;
292    unsigned int    y;
293    unsigned int    l;
294    giet_proc_xyp( &x, &y, &l );
295
[542]296    // "Store" tasks wait completion of heaps initialization
297    while ( global_sync == 0 ) asm volatile ("nop");
298
[488]299    // "store" task[0][0] initialises the barrier between all "store" tasks,
300    // allocates NIC & CMA TX channels, and starts the NIC_CMA TX transfer.
301    // Other "store" tasks wait completion.
302    if ( (x==0) && (y==0) )
303    {
[669]304        // allocate a private TTY
305        giet_tty_alloc(0);
[549]306
307        giet_tty_printf("\n*** Task store on P[%d][%d][%d] starts at cycle %d\n"
[502]308                        "  x_size = %d / y_size = %d / nprocs = %d\n",
309                        x , y , l , giet_proctime() , x_size, y_size, nprocs );
[488]310 
[502]311        sqt_barrier_init( &tx_barrier , x_size , y_size , 1 );
312        nic_tx_channel = giet_nic_tx_alloc( x_size , y_size );
[488]313        giet_nic_tx_start( nic_tx_channel );
314        store_sync = 1;
[457]315    }
316    else
317    {
[488]318        while ( store_sync == 0 ) asm volatile ("nop");
[457]319    }   
320
[488]321    // all "store" tasks wait mwmr channels initialisation
322    while ( local_sync[x][y] == 0 ) asm volatile ("nop");
[457]323
[502]324    // each "store" tasks register pointers on working containers in local stack
[488]325    unsigned int   n;
[502]326    unsigned int   analysis_tasks = nprocs-2;
327    unsigned int*  cont[NPROCS_MAX-2]; 
328
329    for ( n = 0 ; n < analysis_tasks ; n++ )
[488]330    {
331        cont[n] = container[x][y][n];
332    }
333   
334    // all "store" tasks register pointers on mwmr fifos in local stack
335    mwmr_channel_t* fifo_l2a = mwmr_l2a[x][y];
336    mwmr_channel_t* fifo_a2s = mwmr_a2s[x][y];
337    mwmr_channel_t* fifo_s2l = mwmr_s2l[x][y];
338
339    // "store" task[0][0] displays status
340    if ( (x==0) && (y==0) )
[549]341    giet_tty_printf("\n*** Task store on P[%d,%d,%d] enters main loop at cycle %d\n"
[488]342                    "      &mwmr_l2a  = %x\n"
343                    "      &mwmr_a2s  = %x\n"
344                    "      &mwmr_s2l  = %x\n"
345                    "      &cont[0]   = %x\n",
346                    x , y , l , giet_proctime(), 
347                    (unsigned int)fifo_l2a,
348                    (unsigned int)fifo_a2s,
349                    (unsigned int)fifo_s2l,
350                    (unsigned int)cont[0] );
351
352
353    /////////////////////////////////////////////////////////////
354    // all "store" tasks enter the main loop (on containers)
355    unsigned int count = 0;     // stored containers count
356    unsigned int index;         // empty container index
357    unsigned int* temp;         // pointer on empty container
358
359    while ( count < CONTAINERS_MAX ) 
[457]360    { 
[488]361        // get one working container index from fifo_a2s
362        mwmr_read( fifo_a2s , &index , 1 );
363        temp = cont[index];
[457]364
[488]365        // put one container to  kernel tx_chbuf
366        giet_nic_tx_move( nic_tx_channel, temp );
367
[457]368        // get packets number
369        unsigned int npackets = temp[0] & 0x0000FFFF;
370        unsigned int nwords   = temp[0] >> 16;
371
[502]372        if ( (x==0) && (y==0) )
[549]373        giet_tty_printf("\n*** Task store on P[%d,%d,%d] get container %d at cycle %d"
[457]374                        " : %d packets / %d words\n",
[488]375                        x, y, l, count, giet_proctime(), npackets, nwords );
[457]376
[488]377        // put the working container index to fifo_s2l
378        mwmr_write( fifo_s2l, &index , 1 );
[457]379
[488]380        count++;
[457]381    }
382
[488]383    // all "store" tasks synchronise before result display
[502]384    sqt_barrier_wait( &tx_barrier );
[457]385
[488]386    // "store" task[0,0] stops NIC_CMA TX transfer and displays results
[457]387    if ( (x==0) && (y==0) )
388    {
[488]389        giet_nic_tx_stop( nic_tx_channel );
[473]390
[549]391        giet_tty_printf("\n@@@@ Classification Results @@@\n"
[457]392                        " - TYPE 0 : %d packets\n"
393                        " - TYPE 1 : %d packets\n"
394                        " - TYPE 2 : %d packets\n"
395                        " - TYPE 3 : %d packets\n"
396                        " - TYPE 4 : %d packets\n"
397                        " - TYPE 5 : %d packets\n"
398                        " - TYPE 6 : %d packets\n"
399                        " - TYPE 7 : %d packets\n"
400                        " - TYPE 8 : %d packets\n"
401                        " - TYPE 9 : %d packets\n"
402                        " - TYPE A : %d packets\n"
403                        " - TYPE B : %d packets\n"
404                        " - TYPE C : %d packets\n"
405                        " - TYPE D : %d packets\n"
406                        " - TYPE E : %d packets\n"
[488]407                        " - TYPE F : %d packets\n"
408                        "    TOTAL = %d packets\n",
409                        counter[0x0], counter[0x1], counter[0x2], counter[0x3],
410                        counter[0x4], counter[0x5], counter[0x6], counter[0x7],
411                        counter[0x8], counter[0x9], counter[0xA], counter[0xB],
412                        counter[0xC], counter[0xD], counter[0xE], counter[0xF],
413                        counter[0x0]+ counter[0x1]+ counter[0x2]+ counter[0x3]+
414                        counter[0x4]+ counter[0x5]+ counter[0x6]+ counter[0x7]+
415                        counter[0x8]+ counter[0x9]+ counter[0xA]+ counter[0xB]+
416                        counter[0xC]+ counter[0xD]+ counter[0xE]+ counter[0xF] );
[457]417
[488]418        giet_nic_tx_stats( nic_tx_channel );
[457]419    }
420
[488]421    // all "store" task exit
[457]422    giet_exit("Task completed");
423
[488]424} // end store()
425
426
[457]427////////////////////////////////////////////
428__attribute__ ((constructor)) void analyse()
429////////////////////////////////////////////
430{
[502]431    // each "load" task get platform parameters
432    unsigned int    x_size;                                             // number of clusters in row
433    unsigned int    y_size;                     // number of clusters in a column
434    unsigned int    nprocs;                     // number of processors per cluster
435    giet_procs_number( &x_size, &y_size, &nprocs );
436
[457]437    // get processor identifiers
438    unsigned int    x;
439    unsigned int    y;
440    unsigned int    l;
441    giet_proc_xyp( &x, &y, &l );
442
[488]443    if ( (x==0) && (y==0) )
444    {
[669]445        // allocate a private TTY
446        giet_tty_alloc(0);
[549]447
448        giet_tty_printf("\n*** Task analyse on P[%d][%d][%d] starts at cycle %d\n"
[502]449                        "  x_size = %d / y_size = %d / nprocs = %d\n",
450                        x , y , l , giet_proctime() , x_size, y_size, nprocs );
[488]451    }
[542]452
453    // all "analyse" tasks wait heaps and mwmr channels initialisation
[473]454    while ( local_sync[x][y] == 0 ) asm volatile ("nop");
455
[488]456    // all "analyse" tasks register pointers on working containers in local stack
457    unsigned int   n;
[502]458    unsigned int   analysis_tasks = nprocs-2;
459    unsigned int*  cont[NPROCS_MAX-2]; 
460    for ( n = 0 ; n < analysis_tasks ; n++ )
[488]461    {
462        cont[n] = container[x][y][n];
463    }
[457]464
[488]465    // all "analyse" tasks register pointers on mwmr fifos in local stack
466    mwmr_channel_t* fifo_l2a = mwmr_l2a[x][y];
467    mwmr_channel_t* fifo_a2s = mwmr_a2s[x][y];
468
469    // "analyse" task[0][0] display status
470    if ( (x==0) && (y==0) )
[549]471    giet_tty_printf("\n*** Task analyse on P[%d,%d,%d] enters main loop at cycle %d\n"
[488]472                    "       &mwmr_l2a = %x\n"
473                    "       &mwmr_a2s = %x\n"
474                    "       &cont[0]  = %x\n",
[457]475                    x, y, l, giet_proctime(), 
[488]476                    (unsigned int)fifo_l2a,
477                    (unsigned int)fifo_a2s,
478                    (unsigned int)cont[0] );
479     
480    /////////////////////////////////////////////////////////////
481    // all "analyse" tasks enter the main loop (on containers)
482    unsigned int  index;           // available container index
483    unsigned int* temp;            // pointer on available container
484    unsigned int  nwords;          // number of words in container
485    unsigned int  npackets;        // number of packets in container
486    unsigned int  length;          // number of bytes in current packet
487    unsigned int  first;           // current packet first word in container
488    unsigned int  type;            // current packet type
489    unsigned int  p;               // current packet index
490
491#if VERBOSE_ANALYSE
492    unsigned int       verbose_len[10]; // save length for all packets in one container
493    unsigned long long verbose_dst[10]; // save length for all packets in one container
494    unsigned long long verbose_src[10]; // save length for all packets in one container
495#endif
496
[457]497    while ( 1 )
498    { 
499
[488]500#if VERBOSE_ANALYSE
501            for( p = 0 ; p < 10 ; p++ )
502            {
503                verbose_len[p] = 0;
504                verbose_dst[p] = 0;
505                verbose_src[p] = 0;
506            }
507#endif
508        // get one working container index from fifo_l2a
509        mwmr_read( fifo_l2a , &index , 1 );
510        temp = cont[index];
511
512        // get packets number and words number
[457]513        npackets = temp[0] & 0x0000FFFF;
514        nwords   = temp[0] >> 16;
515
[488]516        if ( (x==0) && (y==0) )
[549]517        giet_tty_printf("\n*** Task analyse on P[%d,%d,%d] get container at cycle %d"
[457]518                        " : %d packets / %d words\n",
519                                                x, y, l, giet_proctime(), npackets, nwords );
520
521        // initialize word index in container
[488]522        first = 34;
[457]523
524        // loop on packets
525        for( p = 0 ; p < npackets ; p++ )
526        {
527            // get packet length from container header
528            if ( (p & 0x1) == 0 )  length = temp[1+(p>>1)] >> 16;
529            else                   length = temp[1+(p>>1)] & 0x0000FFFF;
530
[488]531            // compute packet DST and SRC MAC addresses
532            unsigned int word0 = temp[first];
533            unsigned int word1 = temp[first + 1];
534            unsigned int word2 = temp[first + 2];
[457]535
[502]536#if VERBOSE_ANALYSE
[488]537            unsigned long long dst = ((unsigned long long)(word1 & 0xFFFF0000)>>16) |
538                                     (((unsigned long long)word0)<<16);
539            unsigned long long src = ((unsigned long long)(word1 & 0x0000FFFF)<<32) |
540                                     ((unsigned long long)word2);
541            if ( p < 10 )
542            {
543                verbose_len[p] = length;
544                verbose_dst[p] = dst;
545                verbose_src[p] = src;
546            }
547#endif
548            // compute type from SRC MAC address and increment counter
549            type = word1 & 0x0000000F;
550            atomic_increment( &counter[type], 1 );
[457]551
[488]552            // exchange SRC & DST MAC addresses for TX
553            temp[first]     = ((word1 & 0x0000FFFF)<<16) | ((word2 & 0xFFFF0000)>>16);
554            temp[first + 1] = ((word2 & 0x0000FFFF)<<16) | ((word0 & 0xFFFF0000)>>16);
555            temp[first + 2] = ((word0 & 0x0000FFFF)<<16) | ((word1 & 0xFFFF0000)>>16);
556
557            // update first word index
558            if ( length & 0x3 ) first += (length>>2)+1;
559            else                first += (length>>2);
[457]560        }
[488]561       
562#if VERBOSE_ANALYSE
563        if ( (x==0) && (y==0) )
[549]564        giet_tty_printf("\n*** Task analyse on P[%d,%d,%d] completes at cycle %d\n"
[488]565                        "   - Packet 0 : plen = %d / dst_mac = %l / src_mac = %l\n"
566                        "   - Packet 1 : plen = %d / dst_mac = %l / src_mac = %l\n"
567                        "   - Packet 2 : plen = %d / dst_mac = %l / src_mac = %l\n"
568                        "   - Packet 3 : plen = %d / dst_mac = %l / src_mac = %l\n"
569                        "   - Packet 4 : plen = %d / dst_mac = %l / src_mac = %l\n"
570                        "   - Packet 5 : plen = %d / dst_mac = %l / src_mac = %l\n"
571                        "   - Packet 6 : plen = %d / dst_mac = %l / src_mac = %l\n"
572                        "   - Packet 7 : plen = %d / dst_mac = %l / src_mac = %l\n"
573                        "   - Packet 8 : plen = %d / dst_mac = %l / src_mac = %l\n"
574                        "   - Packet 9 : plen = %d / dst_mac = %l / src_mac = %l\n",
575                        x , y , l , giet_proctime() , 
576                        verbose_len[0] , verbose_dst[0] , verbose_src[0] ,
577                        verbose_len[1] , verbose_dst[1] , verbose_src[1] ,
578                        verbose_len[2] , verbose_dst[2] , verbose_src[2] ,
579                        verbose_len[3] , verbose_dst[3] , verbose_src[3] ,
580                        verbose_len[4] , verbose_dst[4] , verbose_src[4] ,
581                        verbose_len[5] , verbose_dst[5] , verbose_src[5] ,
582                        verbose_len[6] , verbose_dst[6] , verbose_src[6] ,
583                        verbose_len[7] , verbose_dst[7] , verbose_src[7] ,
584                        verbose_len[8] , verbose_dst[8] , verbose_src[8] ,
585                        verbose_len[9] , verbose_dst[9] , verbose_src[9] );
586#endif
587           
588        // pseudo-random delay
[549]589        unsigned int delay = giet_rand()>>3;
590        for( p = 0 ; p < delay ; p++ ) asm volatile ("nop");
[488]591
592        // put the working container index to fifo_a2s
593        mwmr_write( fifo_a2s , &index , 1 );
[457]594    }
595} // end analyse()
596
Note: See TracBrowser for help on using the repository browser.