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

Last change on this file since 600 was 549, checked in by alain, 10 years ago

1) Use private TTY terminals for all tasks in cluster[0,0].
2) Increase the average value of the random delay in the analyse task.

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