1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
/* -*- linux-c -*-
* Stat Runtime Functions
* Copyright (C) 2012 Red Hat Inc.
*
* This file is part of systemtap, and is free software. You can
* redistribute it and/or modify it under the terms of the GNU General
* Public License (GPL); either version 2, or (at your option) any
* later version.
*/
#ifndef _STAPDYN_STAT_RUNTIME_H_
#define _STAPDYN_STAT_RUNTIME_H_
#include <pthread.h>
#include <unistd.h>
#include <sched.h>
#include "offptr.h"
#ifdef NEED_STAT_LOCKS
#define STAT_LOCK(sd) pthread_mutex_lock(&(sd)->lock)
#define STAT_UNLOCK(sd) pthread_mutex_unlock(&(sd)->lock)
#else
#define STAT_LOCK(sd) do {} while (0)
#define STAT_UNLOCK(sd) do {} while (0)
#endif
static int STAT_GET_CPU(void)
{
return _stp_runtime_get_data_index();
}
#define STAT_PUT_CPU() do {} while (0)
/** Stat struct. Maps do not need this */
typedef struct _Stat {
struct _Hist hist;
/* aggregated data */
offptr_t oagg;
/* The stat data is a "per-cpu" array. */
offptr_t osd[];
} *Stat;
static Stat _stp_stat_alloc(size_t stat_data_size)
{
int i;
void *mem;
Stat st;
size_t stat_size = sizeof(struct _Stat)
+ sizeof(offptr_t) * _stp_runtime_num_contexts;
size_t total_size = stat_size +
stat_data_size * (_stp_runtime_num_contexts + 1);
if (stat_data_size < sizeof(stat_data))
return NULL;
/* NB: This is done as one big allocation, then assigning offptrs to
* each sub-piece. (See _stp_pmap_new for more explanation) */
st = mem = _stp_shm_zalloc(total_size);
if (st == NULL)
return NULL;
mem += stat_size;
offptr_set(&st->oagg, mem);
for_each_possible_cpu(i) {
mem += stat_data_size;
offptr_set(&st->osd[i], mem);
}
return st;
}
static void _stp_stat_free(Stat st)
{
_stp_shm_free(st);
}
static inline stat_data* _stp_stat_get_agg(Stat st)
{
return offptr_get(&st->oagg);
}
static inline stat_data* _stp_stat_per_cpu_ptr(Stat st, int cpu)
{
return offptr_get(&st->osd[cpu]);
}
static int _stp_stat_initialize_locks(Stat st)
{
#ifdef NEED_STAT_LOCKS
int i, rc;
stat_data *sdp;
for_each_possible_cpu(i) {
sdp = _stp_stat_per_cpu_ptr (st, i);
if ((rc = stp_pthread_mutex_init_shared(&sdp->lock))
!= 0) {
return rc;
}
}
sdp = _stp_stat_get_agg (st);
if ((rc = stp_pthread_mutex_init_shared(&sdp->lock)) != 0) {
_stp_error("Couldn't initialize stat mutex: %d\n", rc);
}
return rc;
#else
return 0;
#endif
}
static void _stp_stat_destroy_locks(Stat st)
{
#ifdef NEED_STAT_LOCKS
int i;
stat_data *sdp;
for_each_possible_cpu(i) {
sdp = _stp_stat_per_cpu_ptr(st, i);
(void)pthread_mutex_destroy(&sdp->lock);
}
sdp = _stp_stat_get_agg (st);
(void)pthread_mutex_destroy(&sdp->lock);
#endif
}
#endif /* _STAPDYN_STAT_RUNTIME_H_ */
|