Project

General

Profile

simple_example.cc

Ron Rechenmacher, 11/07/2017 01:08 PM

 
1
#if 0
2
unsetup_all
3
setup messagefacility v2_01_02 -q e14:debug
4
g++ -O2 -g -Wall -I$MESSAGEFACILITY_INC -I$CETLIB_INC -I$CETLIB_EXCEPT_INC -I$FHICLCPP_INC \
5
 -I$BOOST_INC \
6
 -std=c++14 -o simple_example{,.cc} -L$MESSAGEFACILITY_LIB -L$FHICLCPP_LIB -L$CETLIB_LIB\
7
 -lMF_MessageLogger -lfhiclcpp -lcetlib -lpthread
8
./simple_example nocontext
9

10
#endif
11

    
12
#define USAGE "\
13
usage: %s\n\
14
", basename(argv[0])
15

    
16

    
17
#include "messagefacility/MessageLogger/MessageLogger.h"
18
#include "fhiclcpp/ParameterSet.h"
19
#include "fhiclcpp/make_ParameterSet.h"
20
#include <string>
21
#include <stdlib.h>                                // setenv
22
#include <getopt.h>             // getopt_long, {no,required,optional}_argument, extern char *optarg; extern int opt{ind,err,opt}
23

    
24

    
25
const char *mf_basic_config="\
26
debugModules : [\"*\"]\n\
27
destinations : {\n\
28
  xxx: {\n\
29
    type: cout\n\
30
    threshold: DEBUG\n\
31
    #useMilliseconds: true     # this negates any timestamp format\n\
32
    #format: { wantSomeContext:false timestamp: \"%FT%T%z\" }\n\
33
  }\n\
34
}\n\
35
";
36
const char *mf_nocontext_config="\
37
debugModules:[\"*\"]\n\
38
destinations:{\n\
39
  xxx:{\n\
40
    type: cout\n\
41
    threshold: DEBUG\n\
42
    format:{wantSomeContext:false}\n\
43
  }\n\
44
}\n\
45
";
46

    
47
const char *mf_NOCONTEXT_config="\
48
debugModules:[\"*\"]\n\
49
destinations:{\n\
50
  xxx: {\n\
51
    type: cout\n\
52
    threshold: DEBUG\n\
53
    format: { wantSomeContext:false wantFullContext:false }\n\
54
  }\n\
55
}\n\
56
";
57

    
58
const char *mf_limit_config="\
59
debugModules : [\"*\"]\n\
60
destinations : {\n\
61
  xxx: {\n\
62
    type: cout\n\
63
    threshold: DEBUG\n\
64
    format: { wantSomeContext:false  }\n\
65
    categories:{default:{limit:4 timespan:1}}\n\
66
  }\n\
67
}\n\
68
";
69
const char *mf_limit_stats_config="\
70
debugModules : [\"*\"]\n\
71
destinations : {\n\
72
  xxx: {\n\
73
    type:cout\n\
74
    #type:file\n\
75
    #filename:\"messages.out\"\n\
76
    #append:false\n\
77
    format:{wantSomeContext:false}\n\
78
    threshold:DEBUG\n\
79
    categories:{default:{limit:4 timespan:1 reportEvery:2}}\n\
80
    outputStatistics:true  # this will cause exception if use by other than cout, cerr, or file\n\
81
    resetStatistics:false  # this will cause exception if use by other than cout, cerr, or file\n\
82
  }\n\
83
}\n\
84
";
85

    
86
const char *mf_nodebug_config="\
87
# the point of this config is to show how long LOG_INFO's take when they are not enabled\n\
88
debugModules : [\"*\"]\n\
89
suppressInfo : []\n\
90
destinations : {\n\
91
  xxx: {\n\
92
    type: cout\n\
93
    threshold: INFO\n\
94
    format: { wantSomeContext:false  }\n\
95
  }\n\
96
}\n\
97
";
98

    
99
static int   opt_v=0;
100
typedef struct {
101
        pid_t tid;
102
        int   loops;
103
        int   tnum;
104
        int   dly_us;
105
        int   d00_us;
106
} args_t;
107

    
108

    
109
void* compare_func(void *arg)
110
{
111
    args_t     *args=(args_t *)arg;
112
        pid_t       main_tid=args->tid;
113
        std::string xtra(" extra string");
114

    
115

    
116
        if (!main_tid) {
117
                if (args->dly_us)
118
                        usleep( args->dly_us * args->tnum );
119
        }
120

    
121
        // mf defaults - See $MESSAGEFACILITY_DIR/source/messagefacility/MessageLogger/MessageLogger.h
122
#   if 0
123
        mf::LogTrace("mf_test_category") << "hello - this is an mf::LogTrace(\"mf_test_category\")";        printf( "\n" );
124
        mf::LogVerbatim("mf_test_category") << "hello - this is an mf::LogVerbatim(\"mf_test_category\")";        printf( "\n" );
125
        mf::LogPrint("mf_test_category") << "hello - this is an mf::LogPrint(\"mf_test_category\")";        printf( "\n" );
126
        mf::LogProblem("mf_test_category") << "hello - this is an mf::LogProblem(\"mf_test_category\")";        printf( "\n" );
127
        mf::LogAbsolute("mf_test_category") << "hello - this is an mf::LogAbsolute(\"mf_test_category\")";        printf( "\n" );
128

129
        mf::LogSystem("mf_test_category") << "hello - this is an mf::LogSystem(\"mf_test_category\")";        printf( "\n" );
130
        mf::LogError("mf_test_category") << "hello - this is an mf::LogError(\"mf_test_category\")\n"
131
                                                                         << "notice! nothing prevents a user from ending the message with:\n%MSG";
132
        printf( "\n" );
133
#   endif
134

135
        for (int ii=0; ii<args->loops; ++ii)
136
                mf::LogDebug("mf_test_category") << "hello - this is an mf::LogDebug(\"mf_test_category\")";
137
        printf( "\n" );
138

139
        if (main_tid)
140
                return (NULL);                        // not a thread
141
        else
142
                pthread_exit(NULL);
143
}   // compare_func
144

145

146
int main(  int        argc, char *argv[] )
147
{
148
        fhicl::ParameterSet pset;
149
        args_t              args;
150
        int                 opt_loops=1;
151
        int                 opt_threads=0;
152
        int                 opt_dly_us=0;
153
        int                 opt_d00_us=0;
154
        pthread_t         * threads;
155
        args_t            * threadargs;
156

157
        int do_help=0;
158
        while (1) {
159
                int opt;
160
                static struct option long_options[] = {
161
                        // name     has_arg          *flag  val
162
                        { "help",   no_argument,      0,    'h' },
163
                        { "verbose",optional_argument,0,    'v' }, // --verbose can take optional arg (not so for just -v, so -vvv is allowed)
164
                        {     0,    0,                0,    0 }
165
                };
166
                opt = getopt_long( argc, argv, "?hvl:t:d:D:", // optional args use "::".  NOTE: -v has no arg but --verbose can have optional
167
                                                  long_options, NULL );
168
                if (opt == -1) break;
169
                switch (opt) {
170
                case '?': case 'h': do_help=1; break;
171
                case 'v': if(optarg)opt_v=strtoul(optarg,0,0); else ++opt_v;    break; // optional is for when coming from long option
172
                case 'l': opt_loops=strtoul(optarg,0,0);      break;
173
                case 't': opt_threads=strtoul(optarg,NULL,0); break;
174
                case 'd': opt_dly_us=strtoul(optarg,NULL,0);  break;
175
                case 'D': opt_d00_us=strtoul(optarg,NULL,0);  break;
176
                default:
177
                        printf( "?? getopt returned character code 0%o ??\n", opt );
178
                        exit( 1 );
179
                }
180
        }
181
        if (do_help) { printf(USAGE);exit(0); }
182

183

184
        if ((argc-optind)==0 || ((argc-optind)==1 && strcmp(argv[optind],"basic")==0)) {
185
                std::string pstr(mf_basic_config);
186
                fhicl::make_ParameterSet(pstr, pset);
187
        // ref. https://cdcvs.fnal.gov/redmine/projects/messagefacility/wiki/Build_and_start_messagefacility
188
        } else if ((argc-optind) == 1 && strcmp(argv[optind],"nocontext")==0) {
189
                std::string pstr(mf_nocontext_config);
190
                fhicl::make_ParameterSet(pstr, pset);
191
        } else if ((argc-optind) == 1 && strcmp(argv[optind],"NOCONTEXT")==0) {
192
                std::string pstr(mf_NOCONTEXT_config);
193
                fhicl::make_ParameterSet(pstr, pset);
194
        } else if ((argc-optind) == 1 && strcmp(argv[optind],"limit")==0) {
195
                std::string pstr(mf_limit_config);
196
                fhicl::make_ParameterSet(pstr, pset);
197
        } else if ((argc-optind) == 1 && strcmp(argv[optind],"limit_stats")==0) {
198
                std::string pstr(mf_limit_stats_config);
199
                fhicl::make_ParameterSet(pstr, pset);
200
        } else if ((argc-optind) == 1) { // arv[1] is filename
201
                // i.e ./MessageFacility.cfg
202
        setenv( "FHICL_FILE_PATH",".",0 );
203
                cet::filepath_maker fpm;
204
                fhicl::make_ParameterSet(argv[optind],fpm,pset );
205
        }
206

207
# if   defined(__cplusplus)      &&      (__cplusplus == 201300L)
208
        mf::StartMessageFacility( mf::MessageFacilityService::MultiThread, pset );
209
        mf::SetApplicationName(std::string("myAppName"));
210
#else
211
        mf::StartMessageFacility( pset );
212
        mf::SetApplicationName(std::string("BoardReader")); // if SetApplicationName is not called, mf defaults it to the string "Early"
213
        mf::setEnabledState("");                                                        // Currently Needed for DEBUG messages
214
#endif
215

    
216
    threads = (pthread_t*)malloc(opt_threads*sizeof(pthread_t));
217
        threadargs = (args_t*)malloc(opt_threads*sizeof(args_t));
218

    
219
        args.loops  = opt_loops;
220
        args.dly_us = opt_dly_us;
221
        args.d00_us = opt_d00_us;
222
    args.tid    = 0;
223
        args.tnum   = 0;
224

    
225
    for (int ii=0; ii<opt_threads; ii++)
226
    {        threadargs[ii] = args;
227
                threadargs[ii].tnum=ii+1;
228
                int sts=pthread_create(&threads[ii],NULL,compare_func,(void*)&(threadargs[ii]));
229
        if(sts!=0){perror("pthread_create");exit(1);}
230
    }
231

    
232
        args.tid = 1;
233
        compare_func(&args);
234

    
235
    for (int ii=0; ii<opt_threads; ii++)
236
    {   pthread_join(threads[ii], NULL);
237
    }
238

    
239
        if (opt_d00_us)
240
                usleep( opt_d00_us );
241

    
242
        return (0);
243
}   // main