• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: LGPL-2.1
2 /*
3  * Copyright (C) 2023 Google LLC, Steven Rostedt <rostedt@goodmis.org>
4  */
5 #include <stdlib.h>
6 #include <ctype.h>
7 #include "tracefs.h"
8 #include "tracefs-local.h"
9 
convert_ts(char * value)10 static long long convert_ts(char *value)
11 {
12 	long long ts;
13 	char *saveptr;
14 	char *secs;
15 	char *usecs;
16 
17 	secs = strtok_r(value, ".", &saveptr);
18 	if (!secs)
19 		return -1LL;
20 
21 	ts = strtoll(secs, NULL, 0);
22 
23 	usecs = strtok_r(NULL, ".", &saveptr);
24 	if (!usecs)
25 		return ts;
26 
27 	/* Could be in nanoseconds */
28 	if (strlen(usecs) > 6)
29 		ts *= 1000000000LL;
30 	else
31 		ts *= 1000000LL;
32 
33 	ts += strtoull(usecs, NULL, 0);
34 
35 	return ts;
36 }
37 
38 struct tracefs_buffer_stat *
tracefs_instance_get_stat(struct tracefs_instance * instance,int cpu)39 tracefs_instance_get_stat(struct tracefs_instance *instance, int cpu)
40 {
41 	struct tracefs_buffer_stat *tstat;
42 	char *saveptr;
43 	char *value;
44 	char *field;
45 	char *path;
46 	char *line;
47 	char *next;
48 	char *buf;
49 	int len;
50 	int ret;
51 
52 	ret = asprintf(&path, "per_cpu/cpu%d/stats", cpu);
53 	if (ret < 0)
54 		return NULL;
55 
56 	buf = tracefs_instance_file_read(instance, path, &len);
57 	free(path);
58 
59 	if (!buf)
60 		return NULL;
61 
62 	tstat = malloc(sizeof(*tstat));
63 	if (!tstat) {
64 		free(buf);
65 		return NULL;
66 	}
67 
68 	/* Set everything to -1 */
69 	memset(tstat, -1, sizeof(*tstat));
70 
71 	next = buf;
72 	while ((line = strtok_r(next, "\n", &saveptr))) {
73 		char *save2;
74 
75 		next = NULL;
76 
77 		field = strtok_r(line, ":", &save2);
78 		if (!field)
79 			break;
80 
81 		value = strtok_r(NULL, ":", &save2);
82 		if (!value)
83 			break;
84 
85 		while (isspace(*value))
86 			value++;
87 
88 		if (strcmp(field, "entries") == 0) {
89 			tstat->entries = strtoull(value, NULL, 0);
90 
91 		} else if (strcmp(field, "overrun") == 0) {
92 			tstat->overrun = strtoull(value, NULL, 0);
93 
94 		} else if (strcmp(field, "commit overrun") == 0) {
95 			tstat->commit_overrun = strtoull(value, NULL, 0);
96 
97 		} else if (strcmp(field, "bytes") == 0) {
98 			tstat->bytes = strtoull(value, NULL, 0);
99 
100 		} else if (strcmp(field, "oldest event ts") == 0) {
101 			tstat->oldest_ts = convert_ts(value);
102 
103 		} else if (strcmp(field, "now ts") == 0) {
104 			tstat->now_ts = convert_ts(value);
105 
106 		} else if (strcmp(field, "dropped events") == 0) {
107 			tstat->dropped_events = strtoull(value, NULL, 0);
108 
109 		} else if (strcmp(field, "read events") == 0) {
110 			tstat->read_events = strtoull(value, NULL, 0);
111 		}
112 	}
113 	free(buf);
114 
115 	return tstat;
116 }
117 
tracefs_instance_put_stat(struct tracefs_buffer_stat * tstat)118 void tracefs_instance_put_stat(struct tracefs_buffer_stat *tstat)
119 {
120 	free(tstat);
121 }
122 
tracefs_buffer_stat_entries(struct tracefs_buffer_stat * tstat)123 ssize_t tracefs_buffer_stat_entries(struct tracefs_buffer_stat *tstat)
124 {
125 	return tstat->entries;
126 }
127 
tracefs_buffer_stat_overrun(struct tracefs_buffer_stat * tstat)128 ssize_t tracefs_buffer_stat_overrun(struct tracefs_buffer_stat *tstat)
129 {
130 	return tstat->overrun;
131 }
132 
tracefs_buffer_stat_commit_overrun(struct tracefs_buffer_stat * tstat)133 ssize_t tracefs_buffer_stat_commit_overrun(struct tracefs_buffer_stat *tstat)
134 {
135 	return tstat->commit_overrun;
136 }
137 
tracefs_buffer_stat_bytes(struct tracefs_buffer_stat * tstat)138 ssize_t tracefs_buffer_stat_bytes(struct tracefs_buffer_stat *tstat)
139 {
140 	return tstat->bytes;
141 }
142 
tracefs_buffer_stat_event_timestamp(struct tracefs_buffer_stat * tstat)143 long long tracefs_buffer_stat_event_timestamp(struct tracefs_buffer_stat *tstat)
144 {
145 	return tstat->oldest_ts;
146 }
147 
tracefs_buffer_stat_timestamp(struct tracefs_buffer_stat * tstat)148 long long tracefs_buffer_stat_timestamp(struct tracefs_buffer_stat *tstat)
149 {
150 	return tstat->now_ts;
151 }
152 
tracefs_buffer_stat_dropped_events(struct tracefs_buffer_stat * tstat)153 ssize_t tracefs_buffer_stat_dropped_events(struct tracefs_buffer_stat *tstat)
154 {
155 	return tstat->dropped_events;
156 }
157 
tracefs_buffer_stat_read_events(struct tracefs_buffer_stat * tstat)158 ssize_t tracefs_buffer_stat_read_events(struct tracefs_buffer_stat *tstat)
159 {
160 	return tstat->read_events;
161 }
162 
163