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

RevLine 
[2281]1/*
2 * (C) 2001 Clemson University and The University of Chicago
3 *
4 * See COPYING in top-level directory.
5 */
6
[2301]7#include <string.h>
[2281]8#include <stdlib.h>
9#include <sys/time.h>
10
[2877]11#include <stdio.h>
12
[7941]13#include <unistd.h>
14
[2281]15#include "pint-event.h"
16#include "pvfs2-types.h"
[2294]17#include "pvfs2-mgmt.h"
[2281]18#include "gossip.h"
[7941]19#include "quicklist.h"
20#include "quickhash.h"
21#include "id-generator.h"
22#include "str-utils.h"
[2281]23
[7941]24#include "pvfs2-config.h"
25
26#ifdef HAVE_TAU
27#include "pvfs_tau_api.h"
28#endif
29
[2281]30/* variables that provide runtime control over which events are recorded */
31
[7941]32static PINT_event_group default_group;
[2281]33
[7941]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;
[2877]42#endif
43
[7941]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};
[2877]52
[7941]53struct PINT_event
[2281]54{
[7941]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};
[2298]62
[7941]63#if defined(HAVE_TAU)
[2877]64
[7941]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);
[8397]69static void PINT_event_free( struct PINT_event *p );
70static void PINT_group_free( strcut PINT_group *g );
[2877]71
[7941]72#endif /* HAVE_TAU */
[2877]73
[8397]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
[7941]101static int PINT_group_compare(void *key, struct qhash_head *link)
[2877]102{
[7941]103    struct PINT_group *eg = qhash_entry(link, struct PINT_group, link);
[2915]104
[7941]105    if(!strcmp(eg->name, (char *)key))
106    {
107        return 1;
108    }
[2877]109    return 0;
110}
111
[7941]112static int PINT_events_compare(void *key, struct qhash_head *link)
[2877]113{
[7941]114    struct PINT_event *e = qhash_entry(link, struct PINT_event, link);
[2877]115
[7941]116    if(!strcmp(e->name, (char *)key))
117    {
118        return 1;
119    }
[2877]120    return 0;
121}
122
[7941]123int PINT_event_init(enum PINT_event_method method)
[2877]124{
[7941]125    int ret;
[2877]126
[7941]127    events_table = qhash_init(PINT_events_compare, quickhash_string_hash, 1024);
128    if(!events_table)
[2298]129    {
[7941]130        return -PVFS_ENOMEM;
[2298]131    }
[2281]132
[7941]133    groups_table = qhash_init(PINT_group_compare, quickhash_string_hash, 1024);
134    if(!groups_table)
[2298]135    {
[8397]136        qhash_destroy_and_finalize( events_table, struct PINT_event, link,
137            PINT_event_free);
[7941]138        return -PVFS_ENOMEM;
[2298]139    }
[2281]140
[7941]141    ret = PINT_event_define_group("defaults", &default_group);
142    if(ret < 0)
[2298]143    {
[8397]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
[7941]149        return ret;
[2298]150    }
[2281]151
[7941]152    switch(method)
[2298]153    {
[7941]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
[2298]161    }
[2281]162
[7941]163    return(0);
[2877]164}
[2281]165
[8397]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
[2877]205void PINT_event_finalize(void)
206{
[7941]207#if defined(HAVE_TAU)
208    PINT_event_tau_fini();
[2877]209#endif
210
[8397]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);
[2281]217    return;
218}
219
[7941]220int PINT_event_thread_start(char *name)
[2281]221{
[7941]222    if(!groups_table)
223    {
224        /* assume that the events interface just hasn't been initialized */
225        return 0;
226    }
[2298]227
[7941]228#if defined(HAVE_TAU)
229    PINT_event_tau_thread_init(name);
230#endif
[2281]231
[7941]232    return 0;
[2281]233}
234
[7941]235int PINT_event_thread_stop(void)
[2290]236{
[7941]237    if(!groups_table)
238    {
239        /* assume that the events interface just hasn't been initialized */
240        return 0;
241    }
[2298]242
[7941]243#if defined(HAVE_TAU)
244    PINT_event_tau_thread_fini();
245    return 0;
246#endif
[2290]247
[7941]248    return 0;
[2290]249}
250
[7941]251int PINT_event_enable(const char *events)
[2281]252{
[7941]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;
[2877]259
[7941]260    if(!groups_table)
261    {
262        /* assume that the events interface just hasn't been initialized */
263        return 0;
264    }
[2877]265
[7941]266    count = PINT_split_string_list(&event_strings, events);
[2877]267
[7941]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        }
[2877]285
[7941]286        if(!strcmp(events, "all"))
287        {
288            PINT_event_enabled_mask = 0xFFFFFFFF;
289            goto done;
290        }
[2877]291
[7941]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;
[2877]308}
309
[7941]310int PINT_event_disable(const char *events)
[2877]311{
[7941]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;
[2281]318
[7941]319    count = PINT_split_string_list(&event_strings, events);
[2281]320
[7941]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        }
[2281]338
[7941]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"))
[2281]348    {
[7941]349        PINT_event_enabled_mask = 0;
[2281]350    }
[7941]351
352done:
353    for(i = 0; i < count; ++i)
354    {
355        free(event_strings[i]);
356    }
357    free(event_strings);
358
359    return ret;
[2877]360}
[2281]361
[7941]362int PINT_event_define_group(const char *name, PINT_event_group *group)
[2877]363{
[7941]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;
[2877]370    }
[2298]371
[7941]372    g = malloc(sizeof(*g));
373    if(!g)
374    {
375        return -PVFS_ENOMEM;
[2877]376    }
[7941]377    memset(g, 0, sizeof(*g));
[2877]378
[7941]379    g->name = strdup(name);
380    if(!g->name)
381    {
382        return -PVFS_ENOMEM;
383    }
[2877]384
[7941]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;
[2281]392}
393
[7941]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)
[2877]399{
[7941]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;
[2877]408    }
409
[7941]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);
[2877]436#endif
437
[7941]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, ...)
[2298]453{
[7941]454    va_list ap;
455    struct PINT_event *event;
[2298]456
[7941]457    if(!groups_table)
458    {
459        /* assume that the events interface just hasn't been initialized */
460        return 0;
461    }
[2298]462
[7941]463event = id_gen_fast_lookup(type);
464    if(event && (event->mask & PINT_event_enabled_mask))
[2298]465    {
[7941]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);
[2298]471    }
[7941]472    return 0;
473}
[2298]474
[7941]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;
[2298]480
[7941]481    if(!groups_table)
[2298]482    {
[7941]483        /* assume that the events interface just hasn't been initialized */
484        return 0;
[2298]485    }
486
[7941]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
[2298]509    return;
510}
511
[7941]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
[2281]540/*
541 * Local variables:
542 *  c-indent-level: 4
543 *  c-basic-offset: 4
544 * End:
545 *
[3784]546 * vim: ts=8 sts=4 sw=4 expandtab
[2281]547 */
Note: See TracBrowser for help on using the browser.