source: branches/v5/platforms/tsarv5_dspin_array/top.cpp @ 1059

Last change on this file since 1059 was 350, checked in by alain, 12 years ago

Introducing Platform tsarv5_dspin_array,
that can be used for TSAR communication
infrastructure characterization.

File size: 21.5 KB
Line 
1/////////////////////////////////////////////////////////////////////////
2// File: top.cpp
3// Author: Alain Greiner
4// Copyright: UPMC/LIP6
5// Date : august 2012
6// This program is released under the GNU public license
7/////////////////////////////////////////////////////////////////////////
8// This file define a generic, clusterized communication architecture,
9// as used in the TSAR project, using only synthetic VCI initiators
10// and targets on the direct network, and synthetic packet generators
11// on the coherence network.
12// It can be used to caracterize the communication infrastructure.
13// The number of clusters cannot be larger than 1024.
14//
15// The communication infrastructure contains 3 "independent" networks:
16// - direct network (VCI command/response)
17// - cc40   coherence network (one-way DSPIN network)
18// - cc33   coherence network (one-way DSPIN network)
19//
20// It is build with one single component. The SyntheticCluster contains:
21// - four dspin_local_crossbar per cluster as local interconnect
22// - two virtual_dspin routers per cluster as global interconnect
23// - one VCI initiator per cluster on direct network.
24// - one VCI target per cluster on direct network.
25// - one source per cluster on cc40 coherence network
26// - one source per cluster on cc33 coherence network
27//
28// The packet length and offered load can be independantly defined
29// on the three networks, and broadcast packets can be generated
30// with a fixed period on the cc40 and cc33 DSPIN networks.
31//
32// The main parameters are
33// - x_size        : number of clusters in a row (power of 2)
34// - y_size        : number of clusters in a column (power of 2)
35// - load_d        : offered load per initiator on direct network (*1000)
36// - load_c40      : offered load per initiator on cc40 network (*1000)
37// - load_c33      : offered load per initiator on cc33 network (*1000)
38// - plen_d        : packet length (in flits) on direct network
39// - plen_c40      : packet length (in flits) on cc40 network
40// - plen_c33      : packet length (in flits) on cc33 network
41// - bcp_c40       : broadcast period (in cycles) on cc40 network
42// - bcp_c33       : broadcast period (in cycles) on cc33 network
43//
44// The dspin_local crossbar does not use any routing table, and
45// directly decode the MSB bits of or VCI address or DSPIN first flit:
46// The (x_width + y_width) MSB bits (left aligned) define
47// the cluster index, and the l_width LSB bits are not used here.
48//      | X_ID  | Y_ID  | L_ID  |     OFFSET          |
49//      |x_width|y_width|l_width|---------------------|
50/////////////////////////////////////////////////////////////////////////
51
52#include <systemc>
53#include <sys/time.h>
54#include <iostream>
55#include <sstream>
56#include <cstdlib>
57#include <cstdarg>
58#include <stdint.h>
59
60#include "simple_cluster.h"
61#include "alloc_elems.h"
62
63///////////////////////////////////////////////////
64//               Parallelisation
65///////////////////////////////////////////////////
66#define USE_OPENMP            0
67
68#if USE_OPENMP
69#include <omp.h>
70#endif
71
72///////////////////////////////////////////////////////////
73//          DSPIN networks parameters           
74///////////////////////////////////////////////////////////
75
76#define cmd_width            40
77#define rsp_width            33
78
79///////////////////////////////////////////////////////////
80//          VCI parameters           
81///////////////////////////////////////////////////////////
82
83#define cell_width            4
84#define address_width         32
85#define plen_width            8
86#define error_width           2
87#define clen_width            1
88#define rflag_width           1
89#define srcid_width           14
90#define pktid_width           4
91#define trdid_width           4
92#define wrplen_width          1
93
94/////////////////////////////////
95int _main(int argc, char *argv[])
96{
97   using namespace sc_core;
98   using namespace soclib::caba;
99   using namespace soclib::common;
100
101   size_t   ncycles          = 1000000000;         // simulated cycles
102   size_t   threads          = 1;                  // simulator's threads number
103   size_t   x_size           = 2;                  // number of columns in 2D mesh
104   size_t   y_size           = 2;                  // number of rows in 2D mesh
105   size_t   load_d           = 50;                 // load (*1000) on direct network.
106   size_t   load_c40         = 0;                  // load (*1000) on cc40 network.
107   size_t   load_c33         = 0;                  // load (*1000) on cc33 network.
108   size_t   plen_d           = 4;                  // packet length on direct network.
109   size_t   plen_c40         = 2;                  // packet length on cc40 network.
110   size_t   plen_c33         = 2;                  // packet length on cc33 network.
111   size_t   bcp_c40          = 0;                  // broadcast period on cc40 network
112   size_t   bcp_c33          = 0;                  // broadcast period on cc33 network
113
114   bool     debug_ok         = false;              // trace activated
115   uint32_t debug_from       = 0;                  // trace start cycle
116   bool     stats_ok         = false;              // stats activated
117   uint32_t stats_period     = 0;                  // period
118
119   ////////////// command line arguments //////////////////////
120   if (argc > 1)
121   {
122      for (int n = 1; n < argc; n = n + 2)
123      {
124         if ((strcmp(argv[n],"-NCYCLES") == 0) && (n+1<argc))
125         {
126            ncycles = atoi(argv[n+1]);
127         }
128         else if ((strcmp(argv[n],"-XSIZE") == 0) && (n+1<argc))
129         {
130            x_size  = atoi(argv[n+1]);
131            assert( ( (x_size == 1) or (x_size == 2) or (x_size == 4) or
132                      (x_size == 8) or (x_size == 16) or (x_size == 32) ) and
133                      "The x_size parameter must be 1, 2, 4, 8, 16 or 32" );
134         }
135         else if ((strcmp(argv[n],"-YSIZE") == 0) && (n+1<argc))
136         {
137            y_size  = atoi(argv[n+1]);
138            assert( ( (y_size == 1) or (y_size == 2) or (y_size == 4) or
139                      (y_size == 8) or (y_size == 16) or (y_size == 32) ) and
140                      "The y_size parameter must be 1, 2, 4, 8, 16 or 32" );
141         }
142         else if ((strcmp(argv[n],"-BCP40") == 0) && (n+1<argc))
143         {
144            bcp_c40 = atoi(argv[n+1]);
145         }
146         else if ((strcmp(argv[n],"-BCP33") == 0) && (n+1<argc))
147         {
148            bcp_c33 = atoi(argv[n+1]);
149         }
150         else if ((strcmp(argv[n],"-LOAD") == 0) && (n+1<argc))
151         {
152            load_d = atoi(argv[n+1]);
153         }
154         else if ((strcmp(argv[n],"-LOAD40") == 0) && (n+1<argc))
155         {
156            load_c40 = atoi(argv[n+1]);
157         }
158         else if ((strcmp(argv[n],"-LOAD33") == 0) && (n+1<argc))
159         {
160            load_c33 = atoi(argv[n+1]);
161         }
162         else if ((strcmp(argv[n],"-TRACE") == 0) && (n+1<argc) )
163         {
164            debug_ok = true;
165            debug_from = atoi(argv[n+1]);
166         }
167         else if ((strcmp(argv[n],"-STATS") == 0) && (n+1<argc) )
168         {
169            stats_ok = true;
170            stats_period = atoi(argv[n+1]);
171         }
172         else if ((strcmp(argv[n], "-THREADS") == 0) && ((n+1) < argc))
173         {
174            threads = atoi(argv[n+1]);
175            threads = (threads < 1) ? 1 : threads;
176         }
177         else
178         {
179            std::cout << "   Arguments are (key,value) couples." << std::endl;
180            std::cout << "   The order is not important." << std::endl;
181            std::cout << "     -NCYCLES number_of_simulated_cycles" << std::endl;
182            std::cout << "     -XSIZE   number_of_columns" << std::endl;
183            std::cout << "     -YSIZE   number_of_rows" << std::endl;
184            std::cout << "     -BCP40   broadcast_period_on_CC40_network" << std::endl;
185            std::cout << "     -BCP33   broadcast_period_on_CC33_network" << std::endl;
186            std::cout << "     -LOAD    load*1000_on_direct_network" << std::endl;
187            std::cout << "     -LOAD40  load*1000_on_cc40_network" << std::endl;
188            std::cout << "     -LOAD33  load*1000_on_cc33_network" << std::endl;
189            std::cout << "     -TRACE   debug_start_cycle" << std::endl;
190            std::cout << "     -STATS   period" << std::endl;
191            std::cout << "     -THREADS simulator_threads_number" << std::endl;
192            exit(0);
193         }
194      }
195   }
196
197   std::cout << std::endl;
198   std::cout << "- x_size     = " << x_size << std::endl;
199   std::cout << "- y_size     = " << y_size << std::endl;
200   std::cout << "- load_d     = " << load_d <<  std::endl;
201   std::cout << "- load_c40   = " << load_c40 <<  std::endl;
202   std::cout << "- load_c33   = " << load_c33 <<  std::endl;
203   std::cout << "- bcp_c40    = " << bcp_c40 <<  std::endl;
204   std::cout << "- bcp_c33    = " << bcp_c33 <<  std::endl;
205
206   std::cout << std::endl;
207
208#if USE_OPENMP
209   omp_set_dynamic(false);
210   omp_set_num_threads(threads_nr);
211   std::cerr << "Built with openmp version " << _OPENMP << std::endl;
212#endif
213
214   // Define VCI parameters
215   typedef soclib::caba::VciParams<cell_width,
216           plen_width,
217           address_width,
218           error_width,                                   
219           clen_width,
220           rflag_width,
221           srcid_width,
222           pktid_width,
223           trdid_width,
224           wrplen_width> vci_param;
225
226   // Define parameters depending on mesh size
227   size_t   x_width;
228   size_t   y_width;
229
230   if      (x_size == 1)  x_width = 0;
231   else if (x_size == 2)  x_width = 1;
232   else if (x_size <= 4)  x_width = 2;
233   else if (x_size <= 8)  x_width = 3;
234   else if (x_size <= 16) x_width = 4;
235   else                   x_width = 5;
236
237   if      (y_size == 1)  y_width = 0;
238   else if (y_size == 2)  y_width = 1;
239   else if (y_size <= 4)  y_width = 2;
240   else if (y_size <= 8)  y_width = 3;
241   else if (y_size <= 16) y_width = 4;
242   else                   y_width = 5;
243
244   ////////////////////
245   // Signals
246   ///////////////////
247
248   sc_clock      signal_clk("clk");
249   sc_signal<bool>    signal_resetn("resetn");
250
251   // Horizontal inter-clusters DSPIN signals
252   DspinSignals<cmd_width>*** signal_dspin_h_cmd_inc =
253      alloc_elems<DspinSignals<cmd_width> >("signal_dspin_h_cmd_inc", x_size-1, y_size, 2);
254   DspinSignals<cmd_width>*** signal_dspin_h_cmd_dec =
255      alloc_elems<DspinSignals<cmd_width> >("signal_dspin_h_cmd_dec", x_size-1, y_size, 2);
256   DspinSignals<rsp_width>*** signal_dspin_h_rsp_inc =
257      alloc_elems<DspinSignals<rsp_width> >("signal_dspin_h_rsp_inc", x_size-1, y_size, 2);
258   DspinSignals<rsp_width>*** signal_dspin_h_rsp_dec =
259      alloc_elems<DspinSignals<rsp_width> >("signal_dspin_h_rsp_dec", x_size-1, y_size, 2);
260
261   // Vertical inter-clusters DSPIN signals
262   DspinSignals<cmd_width>*** signal_dspin_v_cmd_inc =
263      alloc_elems<DspinSignals<cmd_width> >("signal_dspin_v_cmd_inc", x_size, y_size-1, 2);
264   DspinSignals<cmd_width>*** signal_dspin_v_cmd_dec =
265      alloc_elems<DspinSignals<cmd_width> >("signal_dspin_v_cmd_dec", x_size, y_size-1, 2);
266   DspinSignals<rsp_width>*** signal_dspin_v_rsp_inc =
267      alloc_elems<DspinSignals<rsp_width> >("signal_dspin_v_rsp_inc", x_size, y_size-1, 2);
268   DspinSignals<rsp_width>*** signal_dspin_v_rsp_dec =
269      alloc_elems<DspinSignals<rsp_width> >("signal_dspin_v_rsp_dec", x_size, y_size-1, 2);
270
271   // Mesh boundaries DSPIN signals
272   DspinSignals<cmd_width>**** signal_dspin_false_cmd_in =
273      alloc_elems<DspinSignals<cmd_width> >("signal_dspin_false_cmd_in", x_size, y_size, 2, 4);
274   DspinSignals<cmd_width>**** signal_dspin_false_cmd_out =
275      alloc_elems<DspinSignals<cmd_width> >("signal_dspin_false_cmd_out", x_size, y_size, 2, 4);
276   DspinSignals<rsp_width>**** signal_dspin_false_rsp_in =
277      alloc_elems<DspinSignals<rsp_width> >("signal_dspin_false_rsp_in", x_size, y_size, 2, 4);
278   DspinSignals<rsp_width>**** signal_dspin_false_rsp_out =
279      alloc_elems<DspinSignals<rsp_width> >("signal_dspin_false_rsp_out", x_size, y_size, 2, 4);
280
281    ////////////////////////////
282    // Clusters construction
283    ////////////////////////////
284
285    SimpleCluster<vci_param, cmd_width, rsp_width>* cluster[32][32];
286
287#if USE_OPENMP
288#pragma omp parallel
289    {
290#pragma omp for
291#endif
292        for(size_t i = 0; i  < (x_size * y_size); i++)
293        {
294            size_t x = i / y_size;
295            size_t y = i % y_size;
296
297#if USE_OPENMP
298#pragma omp critical
299            {
300#endif
301                std::ostringstream sc;
302                sc << "cluster_" << x << "_" << y;
303                std::cout << "****************** " << sc.str().c_str() 
304                          << " ******************" << std::endl;
305
306                cluster[x][y] = new SimpleCluster<vci_param, cmd_width, rsp_width>
307                                    ( sc.str().c_str(),
308                                      x,
309                                      y,
310                                      x_width,
311                                      y_width,
312                                      load_d,
313                                      plen_d,
314                                      load_c40,
315                                      plen_c40,
316                                      load_c33,
317                                      plen_c33,
318                                      bcp_c40,
319                                      bcp_c33 );
320
321#if USE_OPENMP
322            } // end critical
323#endif
324        } // end for
325#if USE_OPENMP
326    }
327#endif
328
329    ///////////////////////////////////////////////////////////////
330    //     Net-list
331    ///////////////////////////////////////////////////////////////
332
333    // Clock & RESET
334    for (size_t x = 0; x < (x_size); x++)
335    {
336        for (size_t y = 0; y < y_size; y++)
337        {
338            cluster[x][y]->p_clk     (signal_clk);
339            cluster[x][y]->p_resetn  (signal_resetn);
340        }
341    }
342
343    // Inter Clusters horizontal connections
344    for (size_t x = 0; x < (x_size-1); x++)
345    {
346        for (size_t y = 0; y < y_size; y++)
347        {
348            for (size_t k = 0; k < 2; k++)
349            {
350                cluster[x][y]->p_cmd_out[k][EAST]     (signal_dspin_h_cmd_inc[x][y][k]);
351                cluster[x+1][y]->p_cmd_in[k][WEST]    (signal_dspin_h_cmd_inc[x][y][k]);
352                cluster[x][y]->p_cmd_in[k][EAST]      (signal_dspin_h_cmd_dec[x][y][k]);
353                cluster[x+1][y]->p_cmd_out[k][WEST]   (signal_dspin_h_cmd_dec[x][y][k]);
354                cluster[x][y]->p_rsp_out[k][EAST]     (signal_dspin_h_rsp_inc[x][y][k]);
355                cluster[x+1][y]->p_rsp_in[k][WEST]    (signal_dspin_h_rsp_inc[x][y][k]);
356                cluster[x][y]->p_rsp_in[k][EAST]      (signal_dspin_h_rsp_dec[x][y][k]);
357                cluster[x+1][y]->p_rsp_out[k][WEST]   (signal_dspin_h_rsp_dec[x][y][k]);
358            }
359        }
360    }
361    std::cout << std::endl << "Horizontal connections established" << std::endl;   
362
363    // Inter Clusters vertical connections
364    for (size_t y = 0; y < (y_size-1); y++)
365    {
366        for (size_t x = 0; x < x_size; x++)
367        {
368            for (size_t k = 0; k < 2; k++)
369            {
370                cluster[x][y]->p_cmd_out[k][NORTH]    (signal_dspin_v_cmd_inc[x][y][k]);
371                cluster[x][y+1]->p_cmd_in[k][SOUTH]   (signal_dspin_v_cmd_inc[x][y][k]);
372                cluster[x][y]->p_cmd_in[k][NORTH]     (signal_dspin_v_cmd_dec[x][y][k]);
373                cluster[x][y+1]->p_cmd_out[k][SOUTH]  (signal_dspin_v_cmd_dec[x][y][k]);
374                cluster[x][y]->p_rsp_out[k][NORTH]    (signal_dspin_v_rsp_inc[x][y][k]);
375                cluster[x][y+1]->p_rsp_in[k][SOUTH]   (signal_dspin_v_rsp_inc[x][y][k]);
376                cluster[x][y]->p_rsp_in[k][NORTH]     (signal_dspin_v_rsp_dec[x][y][k]);
377                cluster[x][y+1]->p_rsp_out[k][SOUTH]  (signal_dspin_v_rsp_dec[x][y][k]);
378            }
379        }
380    }
381    std::cout << "Vertical connections established" << std::endl;
382
383    // East & West boundary cluster connections
384    for (size_t y = 0; y < y_size; y++)
385    {
386        for (size_t k = 0; k < 2; k++)
387        {
388            cluster[0][y]->p_cmd_in[k][WEST]         (signal_dspin_false_cmd_in[0][y][k][WEST]);
389            cluster[0][y]->p_cmd_out[k][WEST]        (signal_dspin_false_cmd_out[0][y][k][WEST]);
390            cluster[0][y]->p_rsp_in[k][WEST]         (signal_dspin_false_rsp_in[0][y][k][WEST]);
391            cluster[0][y]->p_rsp_out[k][WEST]        (signal_dspin_false_rsp_out[0][y][k][WEST]);
392
393            cluster[x_size-1][y]->p_cmd_in[k][EAST]  (signal_dspin_false_cmd_in[x_size-1][y][k][EAST]);
394            cluster[x_size-1][y]->p_cmd_out[k][EAST] (signal_dspin_false_cmd_out[x_size-1][y][k][EAST]);
395            cluster[x_size-1][y]->p_rsp_in[k][EAST]  (signal_dspin_false_rsp_in[x_size-1][y][k][EAST]);
396            cluster[x_size-1][y]->p_rsp_out[k][EAST] (signal_dspin_false_rsp_out[x_size-1][y][k][EAST]);
397        }
398    }
399
400    // North & South boundary cluster connections
401    for (size_t x = 0; x < x_size; x++)
402    {
403        for (size_t k = 0; k < 2; k++)
404        {
405            cluster[x][0]->p_cmd_in[k][SOUTH]         (signal_dspin_false_cmd_in[x][0][k][SOUTH]);
406            cluster[x][0]->p_cmd_out[k][SOUTH]        (signal_dspin_false_cmd_out[x][0][k][SOUTH]);
407            cluster[x][0]->p_rsp_in[k][SOUTH]         (signal_dspin_false_rsp_in[x][0][k][SOUTH]);
408            cluster[x][0]->p_rsp_out[k][SOUTH]        (signal_dspin_false_rsp_out[x][0][k][SOUTH]);
409
410            cluster[x][y_size-1]->p_cmd_in[k][NORTH]  (signal_dspin_false_cmd_in[x][y_size-1][k][NORTH]);
411            cluster[x][y_size-1]->p_cmd_out[k][NORTH] (signal_dspin_false_cmd_out[x][y_size-1][k][NORTH]);
412            cluster[x][y_size-1]->p_rsp_in[k][NORTH]  (signal_dspin_false_rsp_in[x][y_size-1][k][NORTH]);
413            cluster[x][y_size-1]->p_rsp_out[k][NORTH] (signal_dspin_false_rsp_out[x][y_size-1][k][NORTH]);
414        }
415    }
416
417    std::cout << std::endl;
418
419    ////////////////////////////////////////////////////////
420    //   Simulation
421    ///////////////////////////////////////////////////////
422
423    sc_start(sc_core::sc_time(0, SC_NS));
424    signal_resetn = false;
425
426    // network boundaries signals
427    for (size_t x = 0; x < x_size ; x++)
428    {
429        for (size_t y = 0; y < y_size ; y++)
430        {
431            for (size_t k = 0; k < 2; k++)
432            {
433                for (size_t a = 0; a < 4; a++)
434                {
435                    signal_dspin_false_cmd_in[x][y][k][a].write = false;
436                    signal_dspin_false_cmd_in[x][y][k][a].read = true;
437                    signal_dspin_false_cmd_out[x][y][k][a].write = false;
438                    signal_dspin_false_cmd_out[x][y][k][a].read = true;
439
440                    signal_dspin_false_rsp_in[x][y][k][a].write = false;
441                    signal_dspin_false_rsp_in[x][y][k][a].read = true;
442                    signal_dspin_false_rsp_out[x][y][k][a].write = false;
443                    signal_dspin_false_rsp_out[x][y][k][a].read = true;
444                }
445            }
446        }
447    }
448
449    sc_start(sc_core::sc_time(1, SC_NS));
450    signal_resetn = true;
451
452    for (size_t n = 1; n < ncycles; n++)
453    {
454        if ( debug_ok and (n > debug_from) )
455        {
456            std::cout << "****************** cycle " << std::dec << n ;
457            std::cout << " ************************************************" << std::endl;
458
459            cluster[0][0]->ini_d->print_trace();
460            cluster[0][0]->w_ini_d->print_trace();
461            cluster[0][0]->tgt_d->print_trace();
462            cluster[0][0]->w_tgt_d->print_trace();
463
464            cluster[0][0]->ini_c->print_trace();
465            cluster[0][0]->tgt_c->print_trace();
466
467            cluster[0][0]->xbar_cmd_d->print_trace();
468            cluster[0][0]->xbar_rsp_d->print_trace();
469            cluster[0][0]->xbar_cmd_c->print_trace();
470            cluster[0][0]->xbar_rsp_c->print_trace();
471
472            cluster[0][0]->router_cmd->print_trace();
473            cluster[0][0]->router_rsp->print_trace();
474
475            std::cout << "---" << std::endl;
476
477            cluster[0][0]->signal_vci_ini.print_trace("0_0/sig_vci_ini");
478            cluster[0][0]->signal_dspin_ini_cmd_d.print_trace("0_0/sig_dspin_ini_cmd_d");
479            cluster[0][0]->signal_dspin_ini_rsp_d.print_trace("0_0/sig_dspin_ini_rsp_d");
480            cluster[0][0]->signal_dspin_ini_cmd_c.print_trace("0_0/sig_dspin_ini_cmd_c");
481            cluster[0][0]->signal_dspin_ini_rsp_c.print_trace("0_0/sig_dspin_ini_rsp_c");
482            cluster[0][0]->signal_dspin_tgt_cmd_d.print_trace("0_0/sig_dspin_tgt_cmd_d");
483            cluster[0][0]->signal_dspin_tgt_rsp_d.print_trace("0_0/sig_dspin_tgt_rsp_d");
484            cluster[0][0]->signal_dspin_tgt_cmd_c.print_trace("0_0/sig_dspin_tgt_cmd_c");
485            cluster[0][0]->signal_dspin_tgt_rsp_c.print_trace("0_0/sig_dspin_tgt_rsp_c");
486        }
487
488        if( stats_ok and (n % stats_period == 0) ) 
489        {
490            for( size_t i = 0 ; i < x_size ; i++ )
491            {
492                for( size_t j = 0 ; j < y_size ; j++ )
493                {
494                    cluster[i][j]->ini_d->print_stats();
495                    cluster[i][j]->ini_c->print_stats();
496                    cluster[i][j]->tgt_c->print_stats();
497                }
498            }
499        }
500
501        sc_start(sc_core::sc_time(1, SC_NS));
502    }
503
504    for( size_t i = 0 ; i < x_size ; i++ )
505    {
506        for( size_t j = 0 ; j < y_size ; j++ )
507        {
508            cluster[i][j]->ini_d->print_stats();
509            cluster[i][j]->ini_c->print_stats();
510            cluster[i][j]->tgt_c->print_stats();
511        }
512    }
513
514    return EXIT_SUCCESS;
515}
516
517int sc_main (int argc, char *argv[])
518{
519   try {
520      return _main(argc, argv);
521   } catch (std::exception &e) {
522      std::cout << e.what() << std::endl;
523   } catch (...) {
524      std::cout << "Unknown exception occured" << std::endl;
525      throw;
526   }
527   return 1;
528}
529
530
531// Local Variables:
532// tab-width: 3
533// c-basic-offset: 3
534// c-file-offsets:((innamespace . 0)(inline-open . 0))
535// indent-tabs-mode: nil
536// End:
537
538// vim: filetype=cpp:expandtab:shiftwidth=3:tabstop=3:softtabstop=3
539
540
541
542
Note: See TracBrowser for help on using the repository browser.