1 : /*
2 : * Copyright (c) 2011 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 :
8 : /*
9 : * Simple Perf Counter Layer to be used by the rest of the service run time
10 : */
11 :
12 : #include "native_client/src/shared/platform/nacl_log.h"
13 : #include "native_client/src/shared/platform/nacl_time.h"
14 : #include "native_client/src/include/portability.h"
15 : #include "native_client/src/include/portability_string.h"
16 : #include "native_client/src/include/nacl_assert.h"
17 : #include "native_client/src/include/nacl_macros.h"
18 : #include "native_client/src/trusted/perf_counter/nacl_perf_counter.h"
19 :
20 : #define LAST_IDX(X) (NACL_ARRAY_SIZE(X)-1)
21 :
22 : void NaClPerfCounterCtor(struct NaClPerfCounter *sv,
23 1 : const char *app_name) {
24 1 : if (NULL == sv) {
25 0 : NaClLog(LOG_ERROR, "NaClPerfCounterStart received null pointer\n");
26 0 : return;
27 : };
28 :
29 1 : memset(sv, 0, sizeof(struct NaClPerfCounter));
30 :
31 1 : if (NULL == app_name) {
32 0 : app_name = "__unknown_app__";
33 : }
34 :
35 : NACL_ASSERT_IS_ARRAY(sv->app_name);
36 1 : strncpy(sv->app_name, app_name, LAST_IDX(sv->app_name));
37 :
38 : /* Being explicit about string termination */
39 1 : sv->app_name[LAST_IDX(sv->app_name)] = '\0';
40 :
41 1 : strncpy(sv->sample_names[0], "__start__", LAST_IDX(sv->sample_names[0]));
42 :
43 :
44 1 : while (0 != NaClGetTimeOfDay(&sv->sample_list[sv->samples])) {
45 : /* repeat until we get a sample */
46 0 : }
47 :
48 1 : sv->samples++;
49 1 : }
50 :
51 :
52 : /*
53 : * Records the time in sv and returns its index in sv
54 : * Note that the first time this routine is called on a sv that was just
55 : * constructed via NaClPerfCounterCtor(), it will return 1, but that
56 : * is actually the SECOND sample.
57 : */
58 1 : int NaClPerfCounterMark(struct NaClPerfCounter *sv, const char *ev_name) {
59 1 : if ((NULL == sv) || (NULL == ev_name)) {
60 0 : NaClLog(LOG_ERROR, "NaClPerfCounterMark received null args\n");
61 0 : return -1;
62 : }
63 1 : if (sv->samples >= NACL_MAX_PERF_COUNTER_SAMPLES) {
64 1 : NaClLog(LOG_ERROR, "NaClPerfCounterMark going beyond buffer size\n");
65 1 : return -1;
66 : }
67 : /* busy loop until we succeed, damn it */
68 1 : while (0 != NaClGetTimeOfDay(&(sv->sample_list[sv->samples])));
69 :
70 : /*
71 : * This relies upon memset() inside NaClPerfCounterCtor() for
72 : * correctness
73 : */
74 :
75 : NACL_ASSERT_IS_ARRAY(sv->sample_names[sv->samples]);
76 :
77 : strncpy(sv->sample_names[sv->samples], ev_name,
78 1 : LAST_IDX(sv->sample_names[sv->samples]));
79 : /* Being explicit about string termination */
80 : sv->sample_names[sv->samples][LAST_IDX(sv->sample_names[sv->samples])] =
81 1 : '\0';
82 :
83 1 : return (sv->samples)++;
84 1 : }
85 :
86 :
87 : int64_t NaClPerfCounterInterval(struct NaClPerfCounter *sv,
88 1 : uint32_t a, uint32_t b) {
89 : if ((NULL != sv) && (a < ((unsigned)sv->samples)) &&
90 : (b < ((unsigned)sv->samples)) &&
91 1 : (sv->samples <= NACL_MAX_PERF_COUNTER_SAMPLES)) {
92 1 : uint32_t lo = (a < b)? a : b;
93 1 : uint32_t hi = (b < a)? a : b;
94 : int64_t seconds = (sv->sample_list[hi].nacl_abi_tv_sec -
95 1 : sv->sample_list[lo].nacl_abi_tv_sec);
96 : int64_t usec = (sv->sample_list[hi].nacl_abi_tv_usec -
97 1 : sv->sample_list[lo].nacl_abi_tv_usec);
98 1 : int64_t rtn = seconds * NACL_MICROS_PER_UNIT + usec;
99 :
100 : NaClLog(1, "NaClPerfCounterInterval(%s %s:%s): %"NACL_PRId64" microsecs\n",
101 1 : sv->app_name, sv->sample_names[lo], sv->sample_names[hi], rtn);
102 :
103 1 : return rtn;
104 : }
105 0 : return -1;
106 1 : }
107 :
108 0 : int64_t NaClPerfCounterIntervalLast(struct NaClPerfCounter *sv) {
109 0 : if (NULL != sv) {
110 0 : return NaClPerfCounterInterval(sv, sv->samples - 2, sv->samples - 1);
111 : }
112 0 : return -1;
113 0 : }
114 :
115 0 : int64_t NaClPerfCounterIntervalTotal(struct NaClPerfCounter *sv) {
116 0 : if (NULL != sv) {
117 0 : return NaClPerfCounterInterval(sv, 0, sv->samples - 1);
118 : }
119 0 : return -1;
120 0 : }
|