root/branches/cu-security-branch/src/common/events/pvfs_tau_api.c @ 8397

Revision 8397, 19.4 KB (checked in by nlmills, 3 years ago)

initial merge with Orange-Branch. much will be broken

Line 
1/*****************************************************
2 * File    : pvfs_tau_api.cpp
3 * Version : $Id: pvfs_tau_api.c,v 1.2.30.4 2010-06-19 00:01:41 nlmills Exp $
4 ****************************************************/
5
6/* Author: Aroon Nataraj */
7
8#include <string.h>
9#include <stdlib.h>
10#include <sys/time.h>
11#include <stdio.h>
12#include <unistd.h>
13#include <pthread.h>
14#include <stdarg.h>
15
16#include <map>
17using namespace std;
18
19#include <Profile/Profiler.h>
20#include <Profile/RtsLayer.h>
21#include "TAU_tf.h"
22
23#include <pvfs_tau_api.h>
24
25#include <fmt_fsm.h>
26
27/* Ttf_closed_event_def:
28 * Stuct to hold descriptions about Start/Stop events
29 * , in particular, the format expected of the var-arg
30 * calls.
31 */
32struct Ttf_closed_event_def {
33    char name[TP_MAX_STR];
34    ff_format fmt_start;
35    int start_no;
36    ff_format fmt_end;
37    int end_no;
38    int index;
39    int inited;
40     
41    //cons
42    Ttf_closed_event_def() {
43        start_no = end_no = 0;
44        inited = 0;
45        name[0] = '\0';
46        index = 0;
47    }
48
49    Ttf_closed_event_def& operator=(const Ttf_closed_event_def& thecopy) {
50        strncpy(name, thecopy.name, TP_MAX_STR);
51        fmt_start.init(thecopy.fmt_start);
52        fmt_end.init(thecopy.fmt_end);
53        start_no = thecopy.start_no;
54        end_no = thecopy.end_no;
55        index = thecopy.index;
56
57        inited = 1;
58       
59        return *this;
60    }
61
62    void init(char* _name, char* _fmt_start, char* _fmt_end, int _index, int _start_no, int _end_no) {
63        strncpy(name, _name, TP_MAX_STR);
64        fmt_start.init(_fmt_start);
65        fmt_start.parse();
66        fmt_end.init(_fmt_end);
67        fmt_end.parse();
68        start_no = _start_no;
69        end_no = _end_no;
70        index = _index;
71        inited = 1;
72   }
73
74   Ttf_closed_event_def(char* _name, char* _fmt_start, char* _fmt_end, int _index, int _start_no, int _end_no) {
75        init(_name, _fmt_start, _fmt_end, _index, _start_no, _end_no);
76   }
77
78};
79
80
81/* Ttf_thread_bundle:
82 * Several things are managed on a per-thread basis.
83 * This allows eliminating or minimizing locking.
84 * The thread-bundle, for lack of a better name, is
85 * meant to keep track of the per-thread state.
86 */
87struct Ttf_thread_bundle {
88    Ttf_closed_event_def* events;
89    Ttf_FileHandleT taufile;
90    int tau_no;
91    x_uint32 event_no;
92
93    #define TP_SCRATCH_SZ (8*50)
94    char scratch[TP_SCRATCH_SZ];
95    int scratch_pos;
96
97    //cons
98    Ttf_thread_bundle() {
99        events = NULL;
100        tau_no = 0;
101        taufile = NULL;
102        event_no = 0;
103        scratch_pos = 0;
104    }
105    //des?
106    //TODO
107};
108
109
110/* g_t_bundles:
111 * For now we declare a bunch of these bundle-ptrs
112 * and allocate them as and when required.
113 * TODO: should we do better?
114 ****************************/
115extern Ttf_thread_bundle* g_t_bundles[TP_MAX_THREADS];
116
117
118//Debugging stuff
119//---------------
120//#define TAU_DEBUG 1   //comment out to unset debugging
121#define TAU_NAME "pvfs_tau_api"
122#include "debug.h"
123
124
125//Declarations for some TAU routines (these arent in TauAPI.h now)
126//----------------------------------------------------------------
127extern "C" {
128extern double Tau_get_timestamp(int tid);
129extern int Tau_get_tid(void);
130}
131
132
133//Fwd decl of utils
134//-----------------
135int tau_thread_init(int tid, int max_elements);
136static int init_master_bundle();
137static Ttf_thread_bundle* get_master_bundle();
138static void put_master_bundle(Ttf_thread_bundle* master_bundle);
139static Ttf_thread_bundle* get_t_bundle(int tid);
140static int refresh_bundle(Ttf_thread_bundle *gbl_bundle, Ttf_thread_bundle *lc_bundle);
141
142
143//We need an enclosing dummy main for instances where no such overall enclosing events are present
144static int PINT_dummy_main;
145
146
147//The Global Master bundle and locks
148static Ttf_thread_bundle* g_master_bundle = NULL;
149static pthread_mutex_t ttf_MasterBundleMutex;
150static pthread_mutexattr_t ttf_MasterBundleMutexAttr;
151
152//The per-thread state management bundles
153Ttf_thread_bundle* g_t_bundles[TP_MAX_THREADS];
154
155
156//Process-level vars (safe to be globals - since process-level)
157//these names are far too generic to be externally visible -
158//TODO: give them a prefix
159//-------------------------
160int g_pid = -1;
161char g_traceloc[TP_MAX_STR];
162char g_filepfx[TP_MAX_STR];
163int g_defbufsz = -1;
164
165
166//The API definition follows
167//--------------------------
168
169////////////////////////////////////////////////////////////////////////////////
170extern "C" int Ttf_init(int process_id, char* folder, char* filename_prefix, int buffer_size) {
171
172    info("Ttf_init: pid:%d folder:%s pfx:%s bsize:%d\n", process_id, folder, filename_prefix, buffer_size);   
173
174    g_pid = process_id;
175    strncpy(g_traceloc, folder, TP_MAX_STR);   
176    strncpy(g_filepfx, filename_prefix, TP_MAX_STR);
177    g_defbufsz = buffer_size;
178
179    TAU_INIT(NULL, NULL);
180#ifndef TAU_MPI
181    TAU_PROFILE_SET_NODE(0);
182#endif /* TAU_MPI */
183
184    if(init_master_bundle()) {
185        err("Ttf_init: init_master_bundle() failed.");
186    return -1;
187    }
188
189    int i = 0;
190    for(i=0; i<TP_MAX_THREADS; i++) {
191        g_t_bundles[i] = NULL;
192    }
193
194    Tau_get_tid(); //this is sort of a hack. Internal code assumes this code path is traversed before other thread-related code. To be fixed...
195
196    tau_thread_init(0, buffer_size);
197
198    info("Ttf_init: Exit\n");
199
200    return 0;
201}
202
203
204////////////////////////////////////////////////////////////////////////////////
205extern "C" int Ttf_thread_start(struct tau_thread_group_info* info, int* thread_id, int* pisnew) {
206    int err = 0;
207    int tmp_sz = info->buffer_size;
208
209    info("Ttf_thread_start: *info:%p\t name:%s\t max:%d\n", info, info->name, info->max);
210
211    Tau_get_tid(); //this is sort of a hack. Internal code assumes this code path is traversed before other thread-related code. To be fixed...
212    RtsLayer::RegisterThreadInGroup(info->name, info->max, pisnew);
213    *thread_id = Tau_get_tid();
214    if(tmp_sz <= 0) tmp_sz = g_defbufsz;
215    err = tau_thread_init(*thread_id, tmp_sz);
216
217    Ttf_thread_bundle *bundle = get_t_bundle(*thread_id);
218
219    //copy over master-bundle to local bundle
220    Ttf_thread_bundle *gbl_bundle = get_master_bundle();
221    refresh_bundle(gbl_bundle, bundle);
222    put_master_bundle(gbl_bundle);
223
224    info("Ttf_thread_start: Exit\n");
225
226    return err;
227}
228
229
230////////////////////////////////////////////////////////////////////////////////
231extern "C" int Ttf_thread_stop() {
232    int tid = Tau_get_tid();
233    info("Ttf_thread_stop:%d\n", tid);
234    RtsLayer::ReleaseThreadInGroup();
235    info("Ttf_thread_stop: Exit: %d\n", tid);
236    return 0;
237}
238
239
240////////////////////////////////////////////////////////////////////////////////
241extern "C" int Ttf_finalize(void)
242{
243    int i, no_t = 0;
244
245    info("Ttf_finalize: Enter.\n");
246
247    for(i =0; i<TP_MAX_THREADS; i++) {
248        if((g_t_bundles[i] == NULL) || (g_t_bundles[i]->taufile == NULL)) {
249            continue;
250        }
251    Ttf_LeaveState(g_t_bundles[i]->taufile, (x_uint64) Tau_get_timestamp(i), g_pid, i, PINT_dummy_main);
252    Ttf_CloseOutputFile(g_t_bundles[i]->taufile);
253    no_t++;
254    }
255
256    //TODO - finalize may be called before end of program - MUST not leak mem - clean up here
257   
258    info("Ttf_finalize: Exit (finned %d threads).\n", no_t);
259
260    return 0;
261}
262
263
264////////////////////////////////////////////////////////////////////////////////
265extern "C" int Ttf_event_define(char* name, char* format_start_event_info, char* format_end_event_info, int* event_type) {
266
267    int tid = Tau_get_tid();
268
269    info("Ttf_event_define: tid:%d name:%s fmt_start:%s fmt_end:%s *event_type:%p\n", tid, name, format_start_event_info, format_end_event_info, event_type);
270
271    //1. Register event definition on global master bundle
272    Ttf_thread_bundle *gbl_bundle = get_master_bundle();
273
274    int the_type = TAU_Log_get_event_number(gbl_bundle);
275    *event_type = the_type;
276   
277    int start_type = 0, end_type = 0;
278
279    start_type = TAU_Log_get_event_number(gbl_bundle);
280    end_type = TAU_Log_get_event_number(gbl_bundle);
281
282    gbl_bundle->events[the_type].init(name, format_start_event_info, format_end_event_info, *event_type, start_type, end_type);
283   
284    //2. Bring local bundle up to date with master bundle
285    Ttf_thread_bundle *lc_bundle = get_t_bundle(tid);
286
287    if(lc_bundle->events == NULL) {
288        lc_bundle->events = new Ttf_closed_event_def[TP_MAX_EVENTS];
289        if(!lc_bundle->events) {
290            err("refresh_bundle: new lc_bundle->events returned NULL.\n");
291            return -1;
292        }
293    }
294
295    if(lc_bundle->tau_no < gbl_bundle->tau_no) {
296        refresh_bundle(gbl_bundle, lc_bundle);
297    } else {
298        err("Ttf_event_define: No.Evs in local bundle(%d) >= global bundle(%d).", lc_bundle->tau_no, gbl_bundle->tau_no);
299    }
300
301    //3. Return master bundle
302    put_master_bundle(gbl_bundle);
303
304    info("Ttf_event_define: name:%s event_type:%d\t *bundle:%p *event:%p\n", name, *event_type, lc_bundle, &(lc_bundle->events[the_type]));
305
306    return 0;
307}
308
309
310////////////////////////////////////////////////////////////////////////////////
311extern "C" int Ttf_EnterState_info(int event_type, int process_id, int* thread_id, int* event_id, ...) {
312
313        int ret;
314        va_list ap;
315        va_start(ap, event_id);
316        ret = Ttf_EnterState_info_va(event_type, process_id, thread_id, event_id, ap);
317        va_end(ap);
318        return ret;
319}
320
321////////////////////////////////////////////////////////////////////////////////
322extern "C" int Ttf_EnterState_info_va(int event_type, int process_id, int* thread_id, int* event_id, va_list ap) {
323    int tid = Tau_get_tid();
324
325    x_uint64 tstamp = (x_uint64) Tau_get_timestamp(tid);
326
327    info("Ttf_EnterState_info: tid:%d event_type:%d pid:%d *event_id:%p\n", tid, event_type, process_id, event_id);
328
329    Ttf_thread_bundle *bundle = get_t_bundle(tid);
330   
331    if(bundle->events == NULL) {
332        err("Ttf_EnterState_info: lc_bundle->events is NULL - no events defined yet? (tau_no==%d)", bundle->tau_no);
333        return -1;
334    }
335
336    //check if "lookup" fails - requires bringing local bundle uptodate
337    if(event_type >= bundle->tau_no) {
338        Ttf_thread_bundle *gbl_bundle = get_master_bundle();
339        refresh_bundle(gbl_bundle, bundle);
340        put_master_bundle(gbl_bundle);
341    }
342
343    //if lookup continues to fail...
344    if(event_type >= bundle->tau_no) {
345        err("Ttf_EnterState_info: event_type(%d) not yet defined.", event_type);
346        return -1;
347    }
348
349    Ttf_closed_event_def *event_info = &(bundle->events[event_type]);
350
351    Ttf_EnterState(bundle->taufile, tstamp, g_pid, tid, event_type);
352
353    *event_id = bundle->event_no++;
354
355    x_uint32 eid = *event_id;
356
357    bundle->scratch_pos = 0;
358
359    memcpy(bundle->scratch+bundle->scratch_pos, &(eid), sizeof(eid));//1st encode the event id
360    bundle->scratch_pos += sizeof(eid);
361
362    //suck from var-args
363    if(event_info->fmt_start.v_tot_size > 0) {
364        int tmp_sz = 0;
365        event_info->fmt_start.suck(ap, bundle->scratch + bundle->scratch_pos, &tmp_sz);
366        bundle->scratch_pos += tmp_sz;
367    }
368
369    memset(bundle->scratch + bundle->scratch_pos, 0, 8); //just to zero out any unused fragment (since record is 8bytes long - memsetting 8 bytes is enough)
370    for(x_uint64* ptr = (x_uint64*)bundle->scratch; (unsigned long) ptr < (unsigned long)(bundle->scratch + bundle->scratch_pos); ptr++) {
371      Ttf_EventTrigger(bundle->taufile, tstamp, g_pid, tid, event_info->start_no, *ptr);
372    }
373
374    info("Enter(After): Encoded eid:%d into scratch as:%d\n", eid, (*((x_uint32*)bundle->scratch)));
375
376    info("Ttf_EnterState_info: *bundle:%p\t *event_info:%p\t v_parsed_fmt:%s\t v_tot_size:%d\n", bundle, event_info, event_info->fmt_start.v_parsed_fmt, event_info->fmt_start.v_tot_size);
377
378    info("Ttf_EnterState_info: Exit: tid:%d event_type:%d pid:%d event_id:%d\n", tid, event_type, process_id, *event_id);
379
380    return 0;
381}
382
383
384extern "C" int Ttf_LeaveState_info(int event_type, int process_id, int* thread_id, int event_id, ...) {
385
386        int ret;
387        va_list ap;
388
389        va_start(ap, event_id);
390        ret = Ttf_LeaveState_info_va(event_type, process_id, thread_id, event_id, ap);
391        va_end(ap);
392        return ret;
393}
394
395////////////////////////////////////////////////////////////////////////////////
396extern "C" int Ttf_LeaveState_info_va(int event_type, int process_id, int* thread_id, int event_id, va_list ap) {
397    int tid = Tau_get_tid();
398
399    x_uint64 tstamp = (x_uint64) Tau_get_timestamp(tid);
400
401    info("Ttf_LeaveState_info: tid:%d event_type:%d pid:%d event_id:%d\n", tid, event_type, process_id, event_id);
402
403    Ttf_thread_bundle *bundle = get_t_bundle(tid);
404   
405    if(bundle->events == NULL) {
406        err("Ttf_LeaveState_info: lc_bundle->events is NULL - no events defined yet? (tau_no==%d)", bundle->tau_no);
407        return -1;
408    }
409
410    //check if "lookup" fails - requires bringing local bundle uptodate
411    if(event_type >= bundle->tau_no) {
412        Ttf_thread_bundle *gbl_bundle = get_master_bundle();
413        refresh_bundle(gbl_bundle, bundle);
414        put_master_bundle(gbl_bundle);
415    }
416    //if lookup continues to fail...
417    if(event_type >= bundle->tau_no) {
418        err("Ttf_LeaveState_info: event_type(%d) not yet defined.", event_type);
419        return -1;
420    }
421
422
423    Ttf_closed_event_def *event_info = &(bundle->events[event_type]);
424
425    Ttf_LeaveState(bundle->taufile, tstamp, g_pid, tid, event_type);
426
427    x_uint32 eid = event_id;
428
429    bundle->scratch_pos = 0;
430
431    memcpy(bundle->scratch + bundle->scratch_pos, &(eid), sizeof(eid));
432    bundle->scratch_pos += sizeof(eid);
433
434    if(event_info->fmt_end.v_tot_size > 0) {
435        int tmp_sz = 0;
436        event_info->fmt_end.suck(ap, bundle->scratch + bundle->scratch_pos, &tmp_sz);
437            bundle->scratch_pos += tmp_sz;
438    }
439
440    memset(bundle->scratch + bundle->scratch_pos, 0, 8); //just to zero out any unused fragment (since record is 8bytes long - memsetting 8 bytes is enough)
441    for(x_uint64* ptr = (x_uint64*)bundle->scratch; (unsigned long) ptr < (unsigned long)(bundle->scratch + bundle->scratch_pos); ptr++) {
442      Ttf_EventTrigger(bundle->taufile, tstamp, g_pid, tid, event_info->end_no, *ptr);
443    }
444
445    info("Leave(After): Encoded eid:%d into scratch as:%d\n", eid, (*((x_uint32*)bundle->scratch)));
446
447    //may be the event-no should be uniq?
448    //bundle->event_no--;
449
450    info("Ttf_LeaveState_info: Exit: tid:%d event_type:%d pid:%d event_id:%d\n", tid, event_type, process_id, event_id);
451   
452    return 0;
453}
454
455
456////////////////////////////////////////////////////////////////////////////////
457extern "C" int Ttf_LogEvent_info(int event_type, int process_id, int* thread_id, int* event_id, double start_time, double end_time, ...) {
458    int err = 0;
459
460    if((err = Ttf_EnterState_info(event_type, process_id, thread_id, event_id)) != 0) {
461       //error...!!!
462       err("Ttf_LogEvent_info: Error from Ttf_EnterState_info: %d. Returning.\n", err);
463       return err;
464    }
465
466    if((err = Ttf_LeaveState_info(event_type, process_id, thread_id, *event_id)) != 0) {
467       //error...!!!
468       err("Ttf_LogEvent_info: Error from Ttf_LeaveState_info: %d. Returning.\n", err);
469       return err;
470    }
471
472    return 0;
473}
474
475
476//The Utils/Helpers of the API
477//----------------------------
478
479////////////////////////////////////////////////////////////////////////////////
480static Ttf_thread_bundle* get_t_bundle(int tid) {
481    if(g_t_bundles[tid] == 0) {
482        g_t_bundles[tid] = new Ttf_thread_bundle();
483    }
484    return g_t_bundles[tid];
485}
486
487
488////////////////////////////////////////////////////////////////////////////////
489static int init_master_bundle() {
490    //setup the mutex
491    pthread_mutexattr_init(&ttf_MasterBundleMutexAttr);
492    pthread_mutex_init(&ttf_MasterBundleMutex, &ttf_MasterBundleMutexAttr);
493
494    //allocate and inialize the bundle
495    if(g_master_bundle != NULL) {
496        err("WARN: init_master_bundle: g_master_bundle(%p) != NULL\n", g_master_bundle);
497    }
498    g_master_bundle = new Ttf_thread_bundle();
499    if(!g_master_bundle) {
500        err("init_master_bundle: new g_master_bundle() returned NULL.\n");
501        return -1;
502    }
503    g_master_bundle->events = new Ttf_closed_event_def[TP_MAX_EVENTS];
504    if(!g_master_bundle->events) {
505        err("init_master_bundle: new g_master_bundle->events returned NULL.\n");
506        return -1;
507    }
508
509    PINT_dummy_main = TAU_Log_get_event_number(g_master_bundle);
510    return 0;
511}
512
513
514////////////////////////////////////////////////////////////////////////////////
515static Ttf_thread_bundle* get_master_bundle() {
516    //lock mutex and return master bundle
517    pthread_mutex_lock(&ttf_MasterBundleMutex);
518    return g_master_bundle;
519}
520
521
522////////////////////////////////////////////////////////////////////////////////
523static void put_master_bundle(Ttf_thread_bundle* master_bundle) {
524    //unlock mutex and noop
525    pthread_mutex_unlock(&ttf_MasterBundleMutex);
526}
527
528
529////////////////////////////////////////////////////////////////////////////////
530int tau_thread_init(int tid, int max_elements) {
531   
532    Ttf_thread_bundle *bundle = NULL;
533
534    info("tau_thread_init: tid:%d max_elements:%d\n", tid, max_elements);
535
536    bundle = get_t_bundle(tid);
537
538    char trcname[TP_MAX_STR*3];
539    char edfname[TP_MAX_STR*3];
540
541    if(bundle->taufile != NULL) {
542      info("tau_thread_init: tid:%d Exit: Already inited. returning.\n", tid);
543      return 0;
544    }
545
546    snprintf(trcname, (TP_MAX_STR*3), "%s/%s.%d.%d.0.trc", g_traceloc, g_filepfx, g_pid, tid);
547    snprintf(edfname, (TP_MAX_STR*3), "%s/%s.%d.%d.edf", g_traceloc, g_filepfx, g_pid, tid);
548
549    bundle->taufile = Ttf_OpenFileForOutput_wsize(trcname,edfname, max_elements);
550
551    bundle->tau_no = 0;
552
553    Ttf_DefThread(bundle->taufile, g_pid, tid, "GENTHREAD");
554   
555    PINT_dummy_main = TAU_Log_get_event_number(bundle);
556    Ttf_DefStateGroup(bundle->taufile, "TAU_DEFAULT", 1);
557    Ttf_DefState(bundle->taufile, PINT_dummy_main, "main", 1);
558    Ttf_EnterState(bundle->taufile, (x_uint64) Tau_get_timestamp(tid), g_pid, tid, PINT_dummy_main);
559    Ttf_FlushTrace(bundle->taufile);
560
561    info("tau_thread_init: tid:%d Exit.\n", tid);
562
563    return 0;
564}
565
566
567////////////////////////////////////////////////////////////////////////////////
568//Assumes any required locking has been performed by caller (no locks taken/released here)
569static int refresh_bundle(Ttf_thread_bundle *gbl_bundle, Ttf_thread_bundle *lc_bundle) {
570    int no_copied = 0;
571
572    if(lc_bundle->events == NULL) {
573        lc_bundle->events = new Ttf_closed_event_def[TP_MAX_EVENTS];
574        if(!lc_bundle->events) {
575            err("refresh_bundle: new lc_bundle->events returned NULL.\n");
576            return -1;
577        }
578    }
579
580    while(lc_bundle->tau_no < gbl_bundle->tau_no) {
581        int lc_no = TAU_Log_get_event_number(lc_bundle);
582        TAU_Log_get_event_number(lc_bundle);
583        TAU_Log_get_event_number(lc_bundle);
584
585        lc_bundle->events[lc_no] = gbl_bundle->events[lc_no];
586        Ttf_closed_event_def* this_ev = &(lc_bundle->events[lc_no]);
587   
588        Ttf_DefState(lc_bundle->taufile, this_ev->index, this_ev->name, 1);
589
590        char start_name[256];
591        if(this_ev->fmt_start.no_patns > 0) {
592            snprintf(start_name, 256, "_xxSTART_%s_FMT_%s%s", this_ev->name, "%d", this_ev->fmt_start.v_parsed_fmt);
593        } else {
594            snprintf(start_name, 256, "_xxSTART_%s_FMT_%s", this_ev->name, "%d");
595        }
596        Ttf_DefUserEvent(lc_bundle->taufile, this_ev->start_no, start_name, 0);
597
598        char end_name[256];
599        if(this_ev->fmt_end.no_patns > 0) {
600            snprintf(end_name, 256, "_xxSTOP_%s_FMT_%s%s", this_ev->name, "%d", this_ev->fmt_end.v_parsed_fmt);
601        } else {
602            snprintf(end_name, 256, "_xxSTOP_%s_FMT_%s", this_ev->name, "%d");
603        }
604        Ttf_DefUserEvent(lc_bundle->taufile, this_ev->end_no, end_name, 0);
605
606        no_copied++;
607    }//while
608   
609    return no_copied;
610}
611
612
613//notes
614// we could wrap the thread_func as in here....
615//rc = tau_pthread_group_create(thread_pointer_array[k], &thread_attr, (void *) run_tau_version,
616//            (void*)threaddata[k], "trialgroup", number_of_threads_in_group);
617//
618
Note: See TracBrowser for help on using the browser.