osMemory.c 5.1 KB
Newer Older
wafwerar's avatar
wafwerar 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#define ALLOW_FORBID_FUNC
wafwerar's avatar
wafwerar 已提交
17
#include <malloc.h>
wafwerar's avatar
wafwerar 已提交
18 19
#include "os.h"

wafwerar's avatar
wafwerar 已提交
20 21
#ifdef USE_TD_MEMORY

L
Liu Jicong 已提交
22
#define TD_MEMORY_SYMBOL ('T' << 24 | 'A' << 16 | 'O' << 8 | 'S')
wafwerar's avatar
wafwerar 已提交
23

24
#define TD_MEMORY_STACK_TRACE_DEPTH 10
wafwerar's avatar
wafwerar 已提交
25

26 27
typedef struct TdMemoryInfo *TdMemoryInfoPtr;

H
Haojun Liao 已提交
28
typedef struct TdMemoryInfo {
wafwerar's avatar
wafwerar 已提交
29
  int32_t symbol;
H
Haojun Liao 已提交
30
  int32_t memorySize;
L
Liu Jicong 已提交
31
  void   *stackTrace[TD_MEMORY_STACK_TRACE_DEPTH];  // gdb: disassemble /m 0xXXX
32 33 34
  // TdMemoryInfoPtr pNext;
  // TdMemoryInfoPtr pPrev;
} TdMemoryInfo;
wafwerar's avatar
wafwerar 已提交
35

36
// static TdMemoryInfoPtr GlobalMemoryPtr = NULL;
wafwerar's avatar
wafwerar 已提交
37

wafwerar's avatar
wafwerar 已提交
38
#ifdef WINDOWS
L
Liu Jicong 已提交
39
#define tstrdup(str) _strdup(str)
wafwerar's avatar
wafwerar 已提交
40
#else
L
Liu Jicong 已提交
41
#define tstrdup(str) strdup(str)
wafwerar's avatar
wafwerar 已提交
42

L
Liu Jicong 已提交
43
#include <execinfo.h>
wafwerar's avatar
wafwerar 已提交
44

wafwerar's avatar
wafwerar 已提交
45
#define STACKCALL __attribute__((regparm(1), noinline))
46
void **STACKCALL taosGetEbp(void) {
wafwerar's avatar
wafwerar 已提交
47 48 49 50 51 52 53
  void **ebp = NULL;
  __asm__ __volatile__("mov %%rbp, %0;\n\t"
                       : "=m"(ebp)  /* output */
                       :            /* input */
                       : "memory"); /* not affect register */
  return (void **)(*ebp);
}
wafwerar's avatar
wafwerar 已提交
54

wafwerar's avatar
wafwerar 已提交
55 56
int32_t taosBackTrace(void **buffer, int32_t size) {
  int32_t frame = 0;
L
Liu Jicong 已提交
57 58 59
  void  **ebp;
  void  **ret = NULL;
  size_t  func_frame_distance = 0;
wafwerar's avatar
wafwerar 已提交
60
  if (buffer != NULL && size > 0) {
61
    ebp = taosGetEbp();
wafwerar's avatar
wafwerar 已提交
62
    func_frame_distance = (size_t)*ebp - (size_t)ebp;
wafwerar's avatar
wafwerar 已提交
63 64 65 66 67
    while (ebp && frame < size && (func_frame_distance < (1ULL << 24))  // assume function ebp more than 16M
           && (func_frame_distance > 0)) {
      ret = ebp + 1;
      buffer[frame++] = *ret;
      ebp = (void **)(*ebp);
wafwerar's avatar
wafwerar 已提交
68
      func_frame_distance = (size_t)*ebp - (size_t)ebp;
wafwerar's avatar
wafwerar 已提交
69 70 71 72
    }
  }
  return frame;
}
wafwerar's avatar
wafwerar 已提交
73

wafwerar's avatar
wafwerar 已提交
74 75
#endif

76 77 78 79 80
// char **taosBackTraceSymbols(int32_t *size) {
//   void  *buffer[20] = {NULL};
//   *size = taosBackTrace(buffer, 20);
//   return backtrace_symbols(buffer, *size);
// }
wafwerar's avatar
wafwerar 已提交
81

wafwerar's avatar
wafwerar 已提交
82 83
#endif

wafwerar's avatar
wafwerar 已提交
84
void *taosMemoryMalloc(int32_t size) {
wafwerar's avatar
wafwerar 已提交
85
#ifdef USE_TD_MEMORY
wafwerar's avatar
wafwerar 已提交
86
  void *tmp = malloc(size + sizeof(TdMemoryInfo));
wafwerar's avatar
wafwerar 已提交
87 88 89 90 91
  if (tmp == NULL) return NULL;

  TdMemoryInfoPtr pTdMemoryInfo = (TdMemoryInfoPtr)tmp;
  pTdMemoryInfo->memorySize = size;
  pTdMemoryInfo->symbol = TD_MEMORY_SYMBOL;
L
Liu Jicong 已提交
92
  taosBackTrace(pTdMemoryInfo->stackTrace, TD_MEMORY_STACK_TRACE_DEPTH);
wafwerar's avatar
wafwerar 已提交
93

L
Liu Jicong 已提交
94
  return (char *)tmp + sizeof(TdMemoryInfo);
wafwerar's avatar
wafwerar 已提交
95 96 97
#else
  return malloc(size);
#endif
wafwerar's avatar
wafwerar 已提交
98 99 100
}

void *taosMemoryCalloc(int32_t num, int32_t size) {
wafwerar's avatar
wafwerar 已提交
101
#ifdef USE_TD_MEMORY
wafwerar's avatar
wafwerar 已提交
102
  int32_t memorySize = num * size;
L
Liu Jicong 已提交
103
  char   *tmp = calloc(memorySize + sizeof(TdMemoryInfo), 1);
wafwerar's avatar
wafwerar 已提交
104 105 106 107 108
  if (tmp == NULL) return NULL;

  TdMemoryInfoPtr pTdMemoryInfo = (TdMemoryInfoPtr)tmp;
  pTdMemoryInfo->memorySize = memorySize;
  pTdMemoryInfo->symbol = TD_MEMORY_SYMBOL;
L
Liu Jicong 已提交
109
  taosBackTrace(pTdMemoryInfo->stackTrace, TD_MEMORY_STACK_TRACE_DEPTH);
wafwerar's avatar
wafwerar 已提交
110

L
Liu Jicong 已提交
111
  return (char *)tmp + sizeof(TdMemoryInfo);
wafwerar's avatar
wafwerar 已提交
112 113 114
#else
  return calloc(num, size);
#endif
wafwerar's avatar
wafwerar 已提交
115 116 117
}

void *taosMemoryRealloc(void *ptr, int32_t size) {
wafwerar's avatar
wafwerar 已提交
118
#ifdef USE_TD_MEMORY
wafwerar's avatar
wafwerar 已提交
119
  if (ptr == NULL) return taosMemoryMalloc(size);
L
Liu Jicong 已提交
120 121

  TdMemoryInfoPtr pTdMemoryInfo = (TdMemoryInfoPtr)((char *)ptr - sizeof(TdMemoryInfo));
wafwerar's avatar
wafwerar 已提交
122 123 124 125 126 127 128
  assert(pTdMemoryInfo->symbol == TD_MEMORY_SYMBOL);

  TdMemoryInfo tdMemoryInfo;
  memcpy(&tdMemoryInfo, pTdMemoryInfo, sizeof(TdMemoryInfo));

  void *tmp = realloc(pTdMemoryInfo, size + sizeof(TdMemoryInfo));
  if (tmp == NULL) return NULL;
L
Liu Jicong 已提交
129

wafwerar's avatar
wafwerar 已提交
130 131 132
  memcpy(tmp, &tdMemoryInfo, sizeof(TdMemoryInfo));
  ((TdMemoryInfoPtr)tmp)->memorySize = size;

L
Liu Jicong 已提交
133
  return (char *)tmp + sizeof(TdMemoryInfo);
wafwerar's avatar
wafwerar 已提交
134 135 136
#else
  return realloc(ptr, size);
#endif
wafwerar's avatar
wafwerar 已提交
137 138
}

139 140 141
void *taosMemoryStrDup(void *ptr) {
#ifdef USE_TD_MEMORY
  if (ptr == NULL) return NULL;
L
Liu Jicong 已提交
142 143

  TdMemoryInfoPtr pTdMemoryInfo = (TdMemoryInfoPtr)((char *)ptr - sizeof(TdMemoryInfo));
144 145 146 147
  assert(pTdMemoryInfo->symbol == TD_MEMORY_SYMBOL);

  void *tmp = tstrdup((const char *)pTdMemoryInfo);
  if (tmp == NULL) return NULL;
L
Liu Jicong 已提交
148

149
  memcpy(tmp, pTdMemoryInfo, sizeof(TdMemoryInfo));
L
Liu Jicong 已提交
150
  taosBackTrace(((TdMemoryInfoPtr)tmp)->stackTrace, TD_MEMORY_STACK_TRACE_DEPTH);
151

L
Liu Jicong 已提交
152
  return (char *)tmp + sizeof(TdMemoryInfo);
153 154 155 156 157
#else
  return tstrdup((const char *)ptr);
#endif
}

wafwerar's avatar
wafwerar 已提交
158
void taosMemoryFree(void *ptr) {
wafwerar's avatar
wafwerar 已提交
159
#ifdef USE_TD_MEMORY
L
Liu Jicong 已提交
160 161
  TdMemoryInfoPtr pTdMemoryInfo = (TdMemoryInfoPtr)((char *)ptr - sizeof(TdMemoryInfo));
  if (pTdMemoryInfo->symbol == TD_MEMORY_SYMBOL) {
wafwerar's avatar
wafwerar 已提交
162 163
    pTdMemoryInfo->memorySize = 0;
    // memset(pTdMemoryInfo, 0, sizeof(TdMemoryInfo));
wafwerar's avatar
wafwerar 已提交
164 165
    free(pTdMemoryInfo);
  } else {
wafwerar's avatar
wafwerar 已提交
166
    free(ptr);
wafwerar's avatar
wafwerar 已提交
167
  }
wafwerar's avatar
wafwerar 已提交
168
#else
wafwerar's avatar
wafwerar 已提交
169
  return free(ptr);
wafwerar's avatar
wafwerar 已提交
170
#endif
wafwerar's avatar
wafwerar 已提交
171 172 173 174
}

int32_t taosMemorySize(void *ptr) {
  if (ptr == NULL) return 0;
wafwerar's avatar
wafwerar 已提交
175 176

#ifdef USE_TD_MEMORY
L
Liu Jicong 已提交
177
  TdMemoryInfoPtr pTdMemoryInfo = (TdMemoryInfoPtr)((char *)ptr - sizeof(TdMemoryInfo));
wafwerar's avatar
wafwerar 已提交
178 179 180
  assert(pTdMemoryInfo->symbol == TD_MEMORY_SYMBOL);

  return pTdMemoryInfo->memorySize;
wafwerar's avatar
wafwerar 已提交
181 182 183
#else
#ifdef WINDOWS
  return _msize(ptr);
wafwerar's avatar
wafwerar 已提交
184 185 186
#else
  return malloc_usable_size(ptr);
#endif
wafwerar's avatar
wafwerar 已提交
187
#endif
L
Liu Jicong 已提交
188
}