root/branches/cu-security-branch/src/common/misc/pint-event.c @ 8397

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

initial merge with Orange-Branch. much will be broken

Line 
1/*
2 * (C) 2001 Clemson University and The University of Chicago
3 *
4 * See COPYING in top-level directory.
5 */
6
7#include <string.h>
8#include <stdlib.h>
9#include <sys/time.h>
10
11#include <stdio.h>
12
13#include <unistd.h>
14
15#include "pint-event.h"
16#include "pvfs2-types.h"
17#include "pvfs2-mgmt.h"
18#include "gossip.h"
19#include "quicklist.h"
20#include "quickhash.h"
21#include "id-generator.h"
22#include "str-utils.h"
23
24#include "pvfs2-config.h"
25
26#ifdef HAVE_TAU
27#include "pvfs_tau_api.h"
28#endif
29
30/* variables that provide runtime control over which events are recorded */
31
32static PINT_event_group default_group;
33
34static struct qhash_table *events_table = NULL;
35static struct qhash_table *groups_table = NULL;
36static uint32_t event_count = 0;
37uint64_t PINT_event_enabled_mask = 0;
38
39#ifdef HAVE_TAU
40static int PINT_event_default_buffer_size = 1024*1024;
41static int PINT_event_default_max_traces = 1024;
42#endif
43
44struct PINT_group
45{
46    char *name;
47    PINT_event_group id;
48    struct qlist_head events;
49    uint64_t mask;
50    struct qhash_head link;
51};
52
53struct PINT_event
54{
55    char *name;
56    PINT_event_type type;
57    PINT_event_group group;
58    uint64_t mask;
59    struct qlist_head group_link;
60    struct qlist_head link;
61};
62
63#if defined(HAVE_TAU)
64
65static void PINT_event_tau_init(void);
66static void PINT_event_tau_fini(void);
67static void PINT_event_tau_thread_init(char* gname);
68static void PINT_event_tau_thread_fini(void);
69static void PINT_event_free( struct PINT_event *p );
70static void PINT_group_free( strcut PINT_group *g );
71
72#endif /* HAVE_TAU */
73
74static void PINT_event_free( struct PINT_event *p )
75{
76    if( p != NULL )
77    {
78        if( p->name != NULL )
79        {
80            free( p->name );
81        }
82        free( p );
83    }
84    return;
85}
86
87static void PINT_group_free( struct PINT_group *g )
88{
89    if( g != NULL )
90    {
91        if( g->name != NULL )
92        {
93            free( g->name );
94        }
95        free( g );
96    }
97    return;
98}
99
100
101static int PINT_group_compare(void *key, struct qhash_head *link)
102{
103    struct PINT_group *eg = qhash_entry(link, struct PINT_group, link);
104
105    if(!strcmp(eg->name, (char *)key))
106    {
107        return 1;
108    }
109    return 0;
110}
111
112static int PINT_events_compare(void *key, struct qhash_head *link)
113{
114    struct PINT_event *e = qhash_entry(link, struct PINT_event, link);
115
116    if(!strcmp(e->name, (char *)key))
117    {
118        return 1;
119    }
120    return 0;
121}
122
123int PINT_event_init(enum PINT_event_method method)
124{
125    int ret;
126
127    events_table = qhash_init(PINT_events_compare, quickhash_string_hash, 1024);
128    if(!events_table)
129    {
130        return -PVFS_ENOMEM;
131    }
132
133    groups_table = qhash_init(PINT_group_compare, quickhash_string_hash, 1024);
134    if(!groups_table)
135    {
136        qhash_destroy_and_finalize( events_table, struct PINT_event, link,
137            PINT_event_free);
138        return -PVFS_ENOMEM;
139    }
140
141    ret = PINT_event_define_group("defaults", &default_group);
142    if(ret < 0)
143    {
144        qhash_destroy_and_finalize( groups_table, struct PINT_group, link,
145            PINT_group_free );
146        qhash_destroy_and_finalize( events_table, struct PINT_event, link,
147            PINT_event_free);
148
149        return ret;
150    }
151
152    switch(method)
153    {
154        case PINT_EVENT_TRACE_TAU:
155#if defined(HAVE_TAU)
156            PINT_event_tau_init();
157            break;
158#else
159            return -PVFS_ENOSYS;
160#endif
161    }
162
163    return(0);
164}
165
166void PINT_event_free_bucket_resources(struct qhash_table *qht, unsigned long distance_from_link)
167{
168  char **name = NULL;
169  char *start_of_structure = NULL;
170  struct qhash_head *bucket_entry = NULL;
171  struct qhash_head *bucket = NULL;
172  struct qhash_head *next = NULL;
173  int i;
174
175  for (i=0; i<qht->table_size; i++)
176  {
177     bucket = &(qht->array[i]);
178     if (bucket==bucket->next && bucket==bucket->prev)
179        continue;  //this bucket is empty
180     
181     /*for each entry, deallocate the name string and the entry structure*/
182     for (bucket_entry=bucket->next; bucket_entry != bucket; bucket_entry = next)
183     {
184         start_of_structure = (char *)((char *)bucket_entry - distance_from_link);
185         name = (char **)start_of_structure;
186         if (*name)
187         {
188            free(*name);
189            *name=NULL;
190         }
191         name=NULL;
192
193         next = bucket_entry->next;
194         free(start_of_structure);
195         start_of_structure=NULL;
196     }/*end for*/
197
198
199  } /*end for*/
200
201  return;
202}
203
204
205void PINT_event_finalize(void)
206{
207#if defined(HAVE_TAU)
208    PINT_event_tau_fini();
209#endif
210
211    /*free the buckets in the tables and the tables themselves*/
212    /* need to free contents as well */
213    qhash_destroy_and_finalize( groups_table, struct PINT_group, link,
214        PINT_group_free );
215    qhash_destroy_and_finalize( events_table, struct PINT_event, link,
216        PINT_event_free);
217    return;
218}
219
220int PINT_event_thread_start(char *name)
221{
222    if(!groups_table)
223    {
224        /* assume that the events interface just hasn't been initialized */
225        return 0;
226    }
227
228#if defined(HAVE_TAU)
229    PINT_event_tau_thread_init(name);
230#endif
231
232    return 0;
233}
234
235int PINT_event_thread_stop(void)
236{
237    if(!groups_table)
238    {
239        /* assume that the events interface just hasn't been initialized */
240        return 0;
241    }
242
243#if defined(HAVE_TAU)
244    PINT_event_tau_thread_fini();
245    return 0;
246#endif
247
248    return 0;
249}
250
251int PINT_event_enable(const char *events)
252{
253    struct qhash_head *entry;
254    struct PINT_event *event;
255    struct PINT_group *group;
256    char **event_strings;
257    int count, i;
258    int ret = 0;
259
260    if(!groups_table)
261    {
262        /* assume that the events interface just hasn't been initialized */
263        return 0;
264    }
265
266    count = PINT_split_string_list(&event_strings, events);
267
268    for(i = 0; i < count; ++i)
269    {
270        entry = qhash_search(events_table, event_strings[i]);
271        if(entry)
272        {
273            event = qhash_entry(entry, struct PINT_event, link);
274            PINT_event_enabled_mask |= event->mask;
275        }
276        else
277        {
278            entry = qhash_search(groups_table, event_strings[i]);
279            if(entry)
280            {
281                group = qhash_entry(entry, struct PINT_group, link);
282                PINT_event_enabled_mask |= group->mask;
283            }
284        }
285
286        if(!strcmp(events, "all"))
287        {
288            PINT_event_enabled_mask = 0xFFFFFFFF;
289            goto done;
290        }
291
292        if(!entry)
293        {
294            gossip_err("Unknown event or event group: %s\n", event_strings[i]);
295            ret = -PVFS_EINVAL;
296            goto done;
297        }
298    }
299
300done:
301    for(i = 0; i < count; ++i)
302    {
303        free(event_strings[i]);
304    }
305    free(event_strings);
306
307    return ret;
308}
309
310int PINT_event_disable(const char *events)
311{
312    struct qhash_head *entry;
313    struct PINT_event *event;
314    struct PINT_group *group;
315    char **event_strings;
316    int count, i;
317    int ret = 0;
318
319    count = PINT_split_string_list(&event_strings, events);
320
321    for(i = 0; i < count; ++i)
322    {
323        entry = qhash_search(events_table, event_strings[i]);
324        if(entry)
325        {
326            event = qhash_entry(entry, struct PINT_event, link);
327            PINT_event_enabled_mask &= ~(event->mask);
328        }
329        else
330        {
331            entry = qhash_search(groups_table, event_strings[i]);
332            if(entry)
333            {
334                group = qhash_entry(entry, struct PINT_group, link);
335                PINT_event_enabled_mask &= ~(group->mask);
336            }
337        }
338
339        if(!entry)
340        {
341            gossip_err("Unknown event or event group: %s\n", event_strings[i]);
342            ret = -PVFS_EINVAL;
343            goto done;
344        }
345    }
346
347    if(!strcmp(events, "none"))
348    {
349        PINT_event_enabled_mask = 0;
350    }
351
352done:
353    for(i = 0; i < count; ++i)
354    {
355        free(event_strings[i]);
356    }
357    free(event_strings);
358
359    return ret;
360}
361
362int PINT_event_define_group(const char *name, PINT_event_group *group)
363{
364    struct PINT_group *g;
365
366    if(!groups_table)
367    {
368        /* assume that the events interface just hasn't been initialized */
369        return 0;
370    }
371
372    g = malloc(sizeof(*g));
373    if(!g)
374    {
375        return -PVFS_ENOMEM;
376    }
377    memset(g, 0, sizeof(*g));
378
379    g->name = strdup(name);
380    if(!g->name)
381    {
382        return -PVFS_ENOMEM;
383    }
384
385    INIT_QLIST_HEAD(&g->events);
386
387    qhash_add(groups_table, g->name, &g->link);
388    id_gen_fast_register(&g->id, g);
389
390    *group = g->id;
391    return 0;
392}
393
394int PINT_event_define_event(PINT_event_group *group,
395                            char *name,
396                            char *format_start,
397                            char *format_end,
398                            PINT_event_type *et)
399{
400    struct PINT_group *g;
401    PINT_event_group ag;
402    struct PINT_event *event;
403
404    if(!groups_table)
405    {
406        /* assume that the events interface just hasn't been initialized */
407        return 0;
408    }
409
410    if(!group)
411    {
412        /* use default group */
413        ag = default_group;
414    }
415    else
416    {
417        ag = *group;
418    }
419
420    event = malloc(sizeof(*event));
421    if(!event)
422    {
423        return -PVFS_ENOMEM;
424    }
425    memset(event, 0, sizeof(*event));
426
427    event->name = strdup(name);
428    if(!event->name)
429    {
430        free(event);
431        return -PVFS_ENOMEM;
432    }
433
434#ifdef HAVE_TAU
435    Ttf_event_define(name, format_start, format_end, (int *)&event->type);
436#endif
437
438    event->group = ag;
439    event->mask = (1 << event_count);
440    ++event_count;
441
442    g = id_gen_fast_lookup(ag);
443    g->mask |= event->mask;
444    qlist_add(&event->group_link, &g->events);
445    qhash_add(events_table, event->name, &event->link);
446
447    id_gen_fast_register(et, event);
448    return 0;
449}
450
451int PINT_event_start_event(
452    PINT_event_type type, int process_id, int *thread_id, PINT_event_id *id, ...)
453{
454    va_list ap;
455    struct PINT_event *event;
456
457    if(!groups_table)
458    {
459        /* assume that the events interface just hasn't been initialized */
460        return 0;
461    }
462
463event = id_gen_fast_lookup(type);
464    if(event && (event->mask & PINT_event_enabled_mask))
465    {
466        va_start(ap, id);
467#ifdef HAVE_TAU
468        Ttf_EnterState_info_va(event->type, process_id, thread_id, (int *)id, ap);
469#endif
470        va_end(ap);
471    }
472    return 0;
473}
474
475int PINT_event_end_event(
476    PINT_event_type type, int process_id, int *thread_id, PINT_event_id id, ...)
477{
478    va_list ap;
479    struct PINT_event *event;
480
481    if(!groups_table)
482    {
483        /* assume that the events interface just hasn't been initialized */
484        return 0;
485    }
486
487    event = id_gen_fast_lookup(type);
488    if(event && (event->mask & PINT_event_enabled_mask))
489    {
490        va_start(ap, id);
491#ifdef HAVE_TAU
492        Ttf_LeaveState_info_va(event->type, process_id, thread_id, id, ap);
493#endif
494        va_end(ap);
495    }
496    return 0;
497}
498
499/******************************************************************************/
500#if defined(HAVE_TAU)
501
502void PINT_event_tau_init(void) {
503    char* foldername = "/tmp/";
504    char* prefix = "pvfs2";
505    int bufsz = 0; //use default
506
507    Ttf_init(getpid(), foldername, prefix, bufsz);
508
509    return;
510}
511
512
513void PINT_event_tau_fini(void) {
514    Ttf_finalize();
515    return;
516}
517
518static void PINT_event_tau_thread_init(char* gname) {
519    int tid = 0;
520    struct tau_thread_group_info tg_info;
521    strncpy(tg_info.name, gname, sizeof(tg_info.name));
522    tg_info.buffer_size = PINT_event_default_buffer_size;
523    tg_info.max = PINT_event_default_max_traces;
524    int isnew = 0;
525    Ttf_thread_start(&tg_info,  &tid, &isnew);
526
527    return;
528}
529
530
531static void PINT_event_tau_thread_fini() {
532    Ttf_thread_stop();
533    return;
534}
535
536#endif /* HAVE_TAU */
537/******************************************************************************/
538
539
540/*
541 * Local variables:
542 *  c-indent-level: 4
543 *  c-basic-offset: 4
544 * End:
545 *
546 * vim: ts=8 sts=4 sw=4 expandtab
547 */
Note: See TracBrowser for help on using the browser.