Welcome to DSUI Internals Manual’s documentation!

Contents:

Initializing DSUI

  • exactly once: dsui_init_check() does the following:
  • Initialize global pool of buffers
  • Initialize maps (1) filename-to-logging_thread, (2) ipname-to-ip structure
  • Create signal handler thread
  • Optionally: register instrumentation points

Registering Instrumentation Points

  • IPs are created statically or dynamically
  • Static: normal method, put into well-known, global section by compiler
  • Dynamic: exactly what it sounds like. Probably used by PyDSUI?

Static Allocation

  • Found by scanning special global section
  • Locked: dsui_register_ip, unlocked: __dsui_register_ip
  • If duplicate named IP, link to original
  • Assign a unique ID to the IP
  • Register IP in IP hashtable/map
  • Dump namespace event to any active logging threads

Dynamic Allocation

  • Use dsui_create_ip

Create Logging Thread

  • Each datastream sink (specific file/socket) is controlled by exactly one logging thread
  • Open file or socket
  • Create pthread
  • Register filename-to-logging_thread mapping

Datastream Creation

  • dsui_open_datastream: default, file specific
  • Determine the logging thread controlling datastream sink (e.g. /path/to/file)
  • Check if maximum number of datastreams has been reached
  • Assign unique ID to datastream for later reference
  • Register datastream in global ID-indexed map
  • Do generic datastream creation with: global buffer pool, default cache sizes
  • datastream_create: generic datastream creation
  • allocate struct datastream
  • For non-ring buffer mode: initialize buffer management thread for datastream
  • initialize the datastream’s buffer cache

Starting DSUI: Default

  • Generate and open output filename

Instrumentation Points

struct datastream_ip

  • Generic representation of an instrumentation point
  • Stuffed into global data section. Allows all IPs to be easily found
  • Links to struct datastream_ip_data which contains ancillary data
  • The id is assigned at run-time
struct datastream_ip {
    struct datastream_ip_data *ip;
    struct datastream_list **next;
    unsigned int *id;
} __attribute__((aligned(8)));

struct datastream_ip_data

  • Contains Group (family), and IP name
  • Other info (e.g. file) for easy instrospection/documentation
  • edf is the name of the associated extra data function
  • type: event/internval/etc...
  • next: datastreams that receive this IP
  • ds_array: direct access to specific datastream
  • list: TODO: i believe this is unused
struct datastream_ip_data {
    const char *group;
    const char *name;
    const char *edf;
    const char *file;
    const char *func;
    int line;
    unsigned int type;
    struct dstrm_list_head list;
    unsigned int id;
    struct datastream_list *next;
    struct datastream_list *ds_array[MAX_DS];
};

Buffer Management

Buffer

Buffer Pool

Buffer Queue

Timekeeping in DSUI

  • Supports multiple clocks
  • Generic time representation, 64-bit uint, dstrm_time_t
  • Exactly one clock source enabled per DSUI instance

Clock Sources

  • enum: CLOCK_GETTIMEOFDAY
  • enum: CLOCK_TSC
  • Global clock: global_clock_id
  • Available clocks: struct dstrm_clock dsui_clocks[NR_CLOCKS];

A clock

struct dstrm_clock {
    char *name;
    dstrm_time_t (*read)(void);
};

Available clocks

struct dstrm_clock dsui_clocks[NR_CLOCKS] = {
    {"tsc",                 rdclock_tsc},
    {"gtod",                rdclock_gettimeofday},
};

Reading the clock

#define DSTRM_READ_CLOCK(val)                           \
    do {                                                \
        (val) = dsui_clocks[global_clock_id].read();    \
    } while (0)

Indices and tables