blob: fd6770bd49a1ecd3e3fca50303ed7624af0ba2c3 [file] [log] [blame]
Nicolas "Pixel" Noble85a46dd2016-04-12 01:50:51 +02001/*
2 *
3 * Copyright 2016, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34#include <stdint.h>
35#include <string.h>
36
37#include <grpc/support/alloc.h>
38#include <grpc/support/sync.h>
39
40#include "test/core/util/memory_counters.h"
41
Nicolas "Pixel" Noble85a46dd2016-04-12 01:50:51 +020042static struct grpc_memory_counters g_memory_counters;
43static gpr_allocation_functions g_old_allocs;
44
Nicolas "Pixel" Noble7c37a682016-04-12 19:08:00 +020045static void *guard_malloc(size_t size);
46static void *guard_realloc(void *vptr, size_t size);
47static void guard_free(void *vptr);
48
Nicolas "Pixel" Noble85a46dd2016-04-12 01:50:51 +020049static void *guard_malloc(size_t size) {
50 size_t *ptr;
Nicolas "Pixel" Noble7c37a682016-04-12 19:08:00 +020051 if (!size) return NULL;
Craig Tiller44cc8142017-02-09 08:00:31 -080052 gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_absolute,
53 (gpr_atm)size);
54 gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_relative,
55 (gpr_atm)size);
56 gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_allocs_absolute,
57 (gpr_atm)1);
58 gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_allocs_relative,
59 (gpr_atm)1);
Nicolas "Pixel" Noble85a46dd2016-04-12 01:50:51 +020060 ptr = g_old_allocs.malloc_fn(size + sizeof(size));
61 *ptr++ = size;
62 return ptr;
63}
64
65static void *guard_realloc(void *vptr, size_t size) {
66 size_t *ptr = vptr;
Nicolas "Pixel" Noble7c37a682016-04-12 19:08:00 +020067 if (vptr == NULL) {
68 return guard_malloc(size);
69 }
70 if (size == 0) {
71 guard_free(vptr);
72 return NULL;
73 }
Nicolas "Pixel" Noble85a46dd2016-04-12 01:50:51 +020074 --ptr;
Craig Tiller44cc8142017-02-09 08:00:31 -080075 gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_absolute,
76 (gpr_atm)size);
77 gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_relative,
78 -(gpr_atm)*ptr);
79 gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_relative,
80 (gpr_atm)size);
81 gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_allocs_absolute,
82 (gpr_atm)1);
Nicolas "Pixel" Noble85a46dd2016-04-12 01:50:51 +020083 ptr = g_old_allocs.realloc_fn(ptr, size + sizeof(size));
84 *ptr++ = size;
85 return ptr;
86}
87
88static void guard_free(void *vptr) {
89 size_t *ptr = vptr;
Nicolas "Pixel" Noble7c37a682016-04-12 19:08:00 +020090 if (!vptr) return;
Nicolas "Pixel" Noble85a46dd2016-04-12 01:50:51 +020091 --ptr;
Craig Tiller44cc8142017-02-09 08:00:31 -080092 gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_relative,
93 -(gpr_atm)*ptr);
94 gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_allocs_relative,
95 -(gpr_atm)1);
Nicolas "Pixel" Noble85a46dd2016-04-12 01:50:51 +020096 g_old_allocs.free_fn(ptr);
97}
98
99struct gpr_allocation_functions g_guard_allocs = {guard_malloc, guard_realloc,
100 guard_free};
101
102void grpc_memory_counters_init() {
103 memset(&g_memory_counters, 0, sizeof(g_memory_counters));
Nicolas "Pixel" Noble85a46dd2016-04-12 01:50:51 +0200104 g_old_allocs = gpr_get_allocation_functions();
105 gpr_set_allocation_functions(g_guard_allocs);
106}
107
108void grpc_memory_counters_destroy() {
109 gpr_set_allocation_functions(g_old_allocs);
Nicolas "Pixel" Noble85a46dd2016-04-12 01:50:51 +0200110}
111
112struct grpc_memory_counters grpc_memory_counters_snapshot() {
113 struct grpc_memory_counters counters;
Craig Tiller8f1b3152017-02-08 15:06:20 -0800114 counters.total_size_relative =
115 gpr_atm_no_barrier_load(&g_memory_counters.total_size_relative);
116 counters.total_size_absolute =
117 gpr_atm_no_barrier_load(&g_memory_counters.total_size_absolute);
118 counters.total_allocs_relative =
119 gpr_atm_no_barrier_load(&g_memory_counters.total_allocs_relative);
120 counters.total_allocs_absolute =
121 gpr_atm_no_barrier_load(&g_memory_counters.total_allocs_absolute);
Nicolas "Pixel" Noble85a46dd2016-04-12 01:50:51 +0200122 return counters;
123}