source: soft/giet_vm/applications/classif/classif.c @ 825

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

1) introduce a new classif application, using the vci_master_nic network controler.
2) use the HEAP type in the python file for heap vsegs in all applications.

File size: 9.6 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////////
2// File   : classif.c
3// Date   : november 2014
4// author : Alain Greiner
5///////////////////////////////////////////////////////////////////////////////////////
6// This multi-threaded application takes a stream of ETH/IP/UDP packets, and makes
7// packets classification, based on the SRC_IP (IP header) and SRC_PORT (UDP header).
8//
9// It uses the VciMasterNic peripheral, that can have up to 4 channels.
10// Each channel implement a private TX-QUEUE, and a private RX queue.
11//
12// There is one analyse thread per core. All threads behave as one single server
13// (i.e. all threads use the same local port number). After each packet analysis,
14// the SRC and DST IP addresses and port numbers are exchanged and a response
15// packet is sent to the remote client.
16//
17// This application can run on architectures containing up to 16 * 16 clusters,
18// It requires one shared TTY terminal.
19//
20// The main thread exit after launching analyse threads.
21// It does not use the pthread_join() construct.
22///////////////////////////////////////////////////////////////////////////////////////
23
24#include "stdio.h"
25#include "user_lock.h"
26#include "user_barrier.h"
27
28#define X_SIZE_MAX        16
29#define Y_SIZE_MAX        16
30#define NPROCS_MAX        4
31#define NBYTES_MAX        2048
32#define SERVER_IP         0x77777777
33#define SERVER_PORT       0x8888
34#define MAX_PACKETS       25
35#define VERBOSE           1
36
37// macro to use a shared TTY
38#define printf(...);    { lock_acquire( &tty_lock ); \
39                          giet_tty_printf(__VA_ARGS__);  \
40                          lock_release( &tty_lock ); }
41
42
43///////////////////////////////////////////////////////////////////////////////////////
44//    Global variables
45///////////////////////////////////////////////////////////////////////////////////////
46
47// lock protecting shared TTY
48user_lock_t    tty_lock;
49
50// barrier for instrumentation
51giet_sqt_barrier_t  barrier;
52
53// instrumentation counters
54unsigned int   counter[16];
55
56// threads arguments array
57unsigned int thread_arg[16][16][4];
58
59/////////////////////////////////////////////////////////////////
60__attribute__ ((constructor)) void analyse( unsigned int * arg )
61/////////////////////////////////////////////////////////////////
62{
63    unsigned char buffer[NBYTES_MAX];      // buffer for one raw packet
64    sockaddr_t    server_addr;             // local  socket address
65    sockaddr_t    client_addr;             // remote socket address
66    int           length;                  // received packet length
67    int           count;                   // packets counter
68    int           error;
69
70    unsigned int  tid = *arg;
71
72    printf("\n[CLASSIF] analyse thread %x starts at cycle %d\n",
73           tid , giet_proctime() );
74
75    // create socket
76    int socket = giet_nic_socket( AF_INET , SOCK_DGRAM , 0 );
77
78    if( socket == -1 ) 
79    {
80        printf("\n[CLASSIF ERROR] thread %x cannot create socket\n", tid );
81        giet_pthread_exit( NULL );
82    } 
83
84    // bind socket
85    server_addr.sin_family = AF_INET;
86    server_addr.sin_addr   = HTONL( SERVER_IP );
87    server_addr.sin_port   = HTONS( SERVER_PORT );
88   
89    error = giet_nic_bind( socket , &server_addr , sizeof(server_addr) );
90
91    if( error ) 
92    {
93        printf("\n[CLASSIF ERROR] thread %x cannot bind socket\n", tid );
94        giet_pthread_exit( NULL );
95    } 
96   
97    printf("\n[CLASSIF] socket %x created by thread %x\n", socket , tid );
98
99    // reset NIC counters
100    giet_nic_clear_stats();
101
102    ///////// loop to receive, analyse, and send packets  ///////////
103    for( count = 0 ; count < MAX_PACKETS ; count++ )
104    {
105        length = sizeof(sockaddr_t);
106
107        // get one packet from client
108        error = giet_nic_recvfrom( socket, 
109                                   buffer,
110                                   NBYTES_MAX,
111                                   0,
112                                   &client_addr,
113                                   &length );
114        if( error ) 
115        {
116            printf("\n[CLASSIF ERROR] thread %x cannot receive packet\n", tid );
117            giet_pthread_exit( NULL );
118        } 
119
120        // get type & pktid
121        unsigned int    client_ip   = client_addr.sin_addr;
122        unsigned short  client_port = client_addr.sin_port;
123        unsigned int    type        = ((client_ip & 0x3) << 2) + (client_port & 0x3);
124        unsigned int    pktid       = (((unsigned int )buffer[0]) << 24) |
125                                      (((unsigned int )buffer[1]) << 16) |
126                                      (((unsigned int )buffer[2]) <<  8) |
127                                      (((unsigned int )buffer[3])      ) ;
128        if( VERBOSE )
129        {
130            printf("\n[CLASSIF] thread %x receive packet at cycle %d\n"
131                   "   type = %x / length = %d / pktid = %d\n",
132                   tid , giet_proctime() , type , length , pktid );
133        }
134
135        atomic_increment( &counter[type], 1 );
136
137        // send response packet
138        error = giet_nic_sendto( socket,
139                                 buffer,
140                                 length,
141                                 0, 
142                                 &client_addr,
143                                 sizeof(sockaddr_t) );
144        if( error ) 
145        {
146            printf("\n[CLASSIF ERROR] thread %x cannot send packet\n", tid );
147            giet_pthread_exit( NULL );
148        } 
149
150        if( VERBOSE )
151        {
152            printf("\n[CLASSIF] thread %x sent packet at cycle %d\n"
153                   "   type = %x / length = %d / pktid = %d\n",
154                   tid , giet_proctime() , type , length , pktid );
155        }
156
157    } // end for
158
159    // synchro before stats
160    sqt_barrier_wait( &barrier );
161
162    if ( tid == 0 )
163    {
164        // give time to flush the TX pipe-line
165        char byte;
166        printf("\n ###### enter any key to get stats ######\n");
167        giet_tty_getc( &byte );
168
169        // display classification results
170        printf("\nClassification Results\n"
171               " - TYPE 0 : %d packets\n"
172               " - TYPE 1 : %d packets\n"
173               " - TYPE 2 : %d packets\n"
174               " - TYPE 3 : %d packets\n"
175               " - TYPE 4 : %d packets\n"
176               " - TYPE 5 : %d packets\n"
177               " - TYPE 6 : %d packets\n"
178               " - TYPE 7 : %d packets\n"
179               " - TYPE 8 : %d packets\n"
180               " - TYPE 9 : %d packets\n"
181               " - TYPE A : %d packets\n"
182               " - TYPE B : %d packets\n"
183               " - TYPE C : %d packets\n"
184               " - TYPE D : %d packets\n"
185               " - TYPE E : %d packets\n"
186               " - TYPE F : %d packets\n"
187               "   TOTAL  = %d packets\n",
188               counter[0x0], counter[0x1], counter[0x2], counter[0x3],
189               counter[0x4], counter[0x5], counter[0x6], counter[0x7],
190               counter[0x8], counter[0x9], counter[0xA], counter[0xB],
191               counter[0xC], counter[0xD], counter[0xE], counter[0xF],
192               counter[0x0]+ counter[0x1]+ counter[0x2]+ counter[0x3]+
193               counter[0x4]+ counter[0x5]+ counter[0x6]+ counter[0x7]+
194               counter[0x8]+ counter[0x9]+ counter[0xA]+ counter[0xB]+
195               counter[0xC]+ counter[0xD]+ counter[0xE]+ counter[0xF] );
196
197        // display NIC instrumentation counters
198        giet_nic_print_stats();
199    }
200
201    giet_pthread_exit( "completed" );
202
203} // end analyse()
204
205
206
207//////////////////////////////////////////
208__attribute__ ((constructor)) void main()
209//////////////////////////////////////////
210{
211    unsigned int x , y , n;
212    unsigned int error;
213    pthread_t    trdid;      // thread index required by pthread_create()
214
215    // get plat-form parameters
216    unsigned int x_size;                       // number of clusters in a row
217    unsigned int y_size;                       // number of clusters in a column
218    unsigned int nprocs;                       // number of processors per cluster
219    giet_procs_number( &x_size , &y_size , &nprocs );
220
221    // shared TTY allocation
222    giet_tty_alloc( 1 );     
223    lock_init( &tty_lock);
224
225    giet_pthread_assert( ((x_size >= 1) && (x_size <= 16)),
226                         "[CLASSIF ERROR] x_size must be in [1...16]");
227
228    giet_pthread_assert( ((y_size >= 1) && (y_size <= 16)),
229                         "[CLASSIF ERROR] y_size must be in [1...16]");
230
231    printf("\n[CLASSIF] main thread starts at cycle %d\n", giet_proctime() );
232   
233    // distributed heap[x,y] initialisation
234    for ( x = 0 ; x < x_size ; x++ )
235    {
236        for ( y = 0 ; y < y_size ; y++ )
237        {
238            heap_init( x , y );
239        }
240    }
241
242    printf("\n[CLASSIF] heap initialized at cycle %d\n", giet_proctime() );
243
244    // barrier initialisation
245    sqt_barrier_init( &barrier, x_size , y_size , nprocs );
246
247    printf("\n[CLASSIF] barrier initialized at cycle %d\n", giet_proctime() );
248
249    // lauch analyse threads
250    for ( x = 0 ; x < x_size ; x++ )
251    {
252        for ( y = 0 ; y < y_size ; y++ )
253        {
254            for ( n = 0 ; n < nprocs ; n++ )
255            {
256                thread_arg[x][y][n] = (x << 16) | (y << 8) | n;
257
258                error = giet_pthread_create( &trdid,
259                                             NULL,           // no attribute
260                                             &analyse,
261                                             &thread_arg[x][y][n] );       
262                if( error )
263                {
264                    printf("\n[CLASSIF ERROR] cannot create thread on core[%d,%d,%d]\n",
265                           x, y, n );
266                    giet_pthread_exit( NULL );
267                }
268            }
269        }
270    }
271
272    giet_pthread_exit( "completed" );
273   
274} // end main()
275
Note: See TracBrowser for help on using the repository browser.