GCC Code Coverage Report
Directory: ../src/ Exec Total Coverage
File: /home/joels/Current/lispbm/src/lbm_prof.c Lines: 0 57 0.0 %
Date: 2024-12-05 14:36:58 Branches: 0 40 0.0 %

Line Branch Exec Source
1
/*
2
    Copyright 2023 Joel Svensson  svenssonjoel@yahoo.se
3
4
    This program is free software: you can redistribute it and/or modify
5
    it under the terms of the GNU General Public License as published by
6
    the Free Software Foundation, either version 3 of the License, or
7
    (at your option) any later version.
8
9
    This program is distributed in the hope that it will be useful,
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
    GNU General Public License for more details.
13
14
    You should have received a copy of the GNU General Public License
15
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
*/
17
18
#include "lbm_prof.h"
19
#include "platform_mutex.h"
20
21
static lbm_uint num_samples = 0;
22
static lbm_uint num_system_samples = 0;
23
static lbm_uint num_sleep_samples = 0;
24
extern eval_context_t *ctx_running;
25
extern mutex_t qmutex;
26
extern bool    qmutex_initialized;
27
extern volatile bool lbm_system_sleeping;
28
29
static lbm_prof_t *prof_data;
30
static lbm_uint    prof_data_num;
31
32
#define TRUNC_SIZE(N) (((N) > LBM_PROF_MAX_NAME_SIZE -1) ? LBM_PROF_MAX_NAME_SIZE-1 : N)
33
34
bool lbm_prof_init(lbm_prof_t *prof_data_buf,
35
                   lbm_uint    prof_data_buf_num) {
36
  if (qmutex_initialized && prof_data_buf && prof_data_buf_num > 0) {
37
    num_samples = 0;
38
    num_system_samples = 0;
39
    num_sleep_samples = 0;
40
    prof_data_num = prof_data_buf_num;
41
    prof_data = prof_data_buf;
42
    for (lbm_uint i = 0; i < prof_data_num; i ++) {
43
      prof_data_buf[i].cid  = -1;
44
      prof_data[i].has_name = false;
45
      memset(&prof_data_buf[i].name, 0, LBM_PROF_MAX_NAME_SIZE);
46
      prof_data_buf[i].count = 0;
47
    }
48
  }
49
  return false;
50
}
51
52
lbm_uint lbm_prof_get_num_samples(void) {
53
  return num_samples;
54
}
55
56
lbm_uint lbm_prof_get_num_system_samples(void) {
57
  return num_system_samples;
58
}
59
60
lbm_uint lbm_prof_get_num_sleep_samples(void) {
61
  return num_sleep_samples;
62
}
63
64
void lbm_prof_sample(void) {
65
  num_samples ++;
66
67
  // Lock mutex so context cannot be destroyed until
68
  // we are done storing a sample.
69
  mutex_lock(&qmutex);
70
  eval_context_t *curr = ctx_running;
71
  if (curr != NULL) {
72
    lbm_cid id = curr->id;
73
    char *name = curr->name;
74
    lbm_uint name_len = 0;
75
    bool doing_gc = false;
76
    if (curr->state & LBM_THREAD_STATE_GC_BIT) {
77
      doing_gc = true;
78
    }
79
    if (name) name_len = strlen(name) + 1;
80
    for (lbm_uint i = 0; i < prof_data_num; i ++) {
81
      if (prof_data[i].cid == -1) {
82
        // add new sample:
83
        prof_data[i].cid = id;
84
        prof_data[i].count = 1;
85
        prof_data[i].gc_count = doing_gc ? 1 : 0;
86
        if (name) {
87
          memcpy(&prof_data[i].name, name, TRUNC_SIZE(name_len));
88
          prof_data[i].name[LBM_PROF_MAX_NAME_SIZE - 1] = 0;
89
          prof_data[i].has_name = true;
90
        }
91
        break;
92
      }
93
      if (prof_data[i].cid == id &&
94
          prof_data[i].has_name &&
95
          name != NULL &&
96
          strncmp(prof_data[i].name, name, TRUNC_SIZE(name_len)) == 0) {
97
        // found a named existing measurement.
98
        prof_data[i].count ++;
99
        prof_data[i].gc_count += doing_gc ? 1 : 0;
100
        break;
101
      }
102
      if (prof_data[i].cid == id &&
103
          !prof_data[i].has_name &&
104
          name == NULL) {
105
        prof_data[i].count ++;
106
        prof_data[i].gc_count += doing_gc ? 1 : 0;
107
        break;
108
      }
109
    }
110
  } else {
111
    if (lbm_system_sleeping) {
112
      num_sleep_samples ++;
113
    } else {
114
      num_system_samples ++;
115
    }
116
  }
117
  mutex_unlock(&qmutex);
118
}