You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

649 lines
17 KiB

17 years ago
17 years ago
17 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
  1. /*****************************************************************************
  2. Copyright (c) 1994, 2010, Oracle and/or its affiliates. All Rights Reserved.
  3. This program is free software; you can redistribute it and/or modify it under
  4. the terms of the GNU General Public License as published by the Free Software
  5. Foundation; version 2 of the License.
  6. This program is distributed in the hope that it will be useful, but WITHOUT
  7. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along with
  10. this program; if not, write to the Free Software Foundation, Inc.,
  11. 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
  12. *****************************************************************************/
  13. /********************************************************************//**
  14. @file include/mem0mem.ic
  15. The memory management
  16. Created 6/8/1994 Heikki Tuuri
  17. *************************************************************************/
  18. #include "mem0dbg.ic"
  19. #ifndef UNIV_HOTBACKUP
  20. # include "mem0pool.h"
  21. #endif /* !UNIV_HOTBACKUP */
  22. #ifdef UNIV_DEBUG
  23. # define mem_heap_create_block(heap, n, type, file_name, line) \
  24. mem_heap_create_block_func(heap, n, file_name, line, type)
  25. # define mem_heap_create_at(N, file_name, line) \
  26. mem_heap_create_func(N, file_name, line, MEM_HEAP_DYNAMIC)
  27. #else /* UNIV_DEBUG */
  28. # define mem_heap_create_block(heap, n, type, file_name, line) \
  29. mem_heap_create_block_func(heap, n, type)
  30. # define mem_heap_create_at(N, file_name, line) \
  31. mem_heap_create_func(N, MEM_HEAP_DYNAMIC)
  32. #endif /* UNIV_DEBUG */
  33. /***************************************************************//**
  34. Creates a memory heap block where data can be allocated.
  35. @return own: memory heap block, NULL if did not succeed (only possible
  36. for MEM_HEAP_BTR_SEARCH type heaps) */
  37. UNIV_INTERN
  38. mem_block_t*
  39. mem_heap_create_block_func(
  40. /*=======================*/
  41. mem_heap_t* heap, /*!< in: memory heap or NULL if first block
  42. should be created */
  43. ulint n, /*!< in: number of bytes needed for user data */
  44. #ifdef UNIV_DEBUG
  45. const char* file_name,/*!< in: file name where created */
  46. ulint line, /*!< in: line where created */
  47. #endif /* UNIV_DEBUG */
  48. ulint type); /*!< in: type of heap: MEM_HEAP_DYNAMIC or
  49. MEM_HEAP_BUFFER */
  50. /******************************************************************//**
  51. Frees a block from a memory heap. */
  52. UNIV_INTERN
  53. void
  54. mem_heap_block_free(
  55. /*================*/
  56. mem_heap_t* heap, /*!< in: heap */
  57. mem_block_t* block); /*!< in: block to free */
  58. #ifndef UNIV_HOTBACKUP
  59. /******************************************************************//**
  60. Frees the free_block field from a memory heap. */
  61. UNIV_INTERN
  62. void
  63. mem_heap_free_block_free(
  64. /*=====================*/
  65. mem_heap_t* heap); /*!< in: heap */
  66. #endif /* !UNIV_HOTBACKUP */
  67. /***************************************************************//**
  68. Adds a new block to a memory heap.
  69. @return created block, NULL if did not succeed (only possible for
  70. MEM_HEAP_BTR_SEARCH type heaps) */
  71. UNIV_INTERN
  72. mem_block_t*
  73. mem_heap_add_block(
  74. /*===============*/
  75. mem_heap_t* heap, /*!< in: memory heap */
  76. ulint n); /*!< in: number of bytes user needs */
  77. UNIV_INLINE
  78. void
  79. mem_block_set_len(mem_block_t* block, ulint len)
  80. {
  81. ut_ad(len > 0);
  82. block->len = len;
  83. }
  84. UNIV_INLINE
  85. ulint
  86. mem_block_get_len(mem_block_t* block)
  87. {
  88. return(block->len);
  89. }
  90. UNIV_INLINE
  91. void
  92. mem_block_set_type(mem_block_t* block, ulint type)
  93. {
  94. ut_ad((type == MEM_HEAP_DYNAMIC) || (type == MEM_HEAP_BUFFER)
  95. || (type == MEM_HEAP_BUFFER + MEM_HEAP_BTR_SEARCH));
  96. block->type = type;
  97. }
  98. UNIV_INLINE
  99. ulint
  100. mem_block_get_type(mem_block_t* block)
  101. {
  102. return(block->type);
  103. }
  104. UNIV_INLINE
  105. void
  106. mem_block_set_free(mem_block_t* block, ulint free)
  107. {
  108. ut_ad(free > 0);
  109. ut_ad(free <= mem_block_get_len(block));
  110. block->free = free;
  111. }
  112. UNIV_INLINE
  113. ulint
  114. mem_block_get_free(mem_block_t* block)
  115. {
  116. return(block->free);
  117. }
  118. UNIV_INLINE
  119. void
  120. mem_block_set_start(mem_block_t* block, ulint start)
  121. {
  122. ut_ad(start > 0);
  123. block->start = start;
  124. }
  125. UNIV_INLINE
  126. ulint
  127. mem_block_get_start(mem_block_t* block)
  128. {
  129. return(block->start);
  130. }
  131. /***************************************************************//**
  132. Allocates and zero-fills n bytes of memory from a memory heap.
  133. @return allocated, zero-filled storage */
  134. UNIV_INLINE
  135. void*
  136. mem_heap_zalloc(
  137. /*============*/
  138. mem_heap_t* heap, /*!< in: memory heap */
  139. ulint n) /*!< in: number of bytes; if the heap is allowed
  140. to grow into the buffer pool, this must be
  141. <= MEM_MAX_ALLOC_IN_BUF */
  142. {
  143. ut_ad(heap);
  144. ut_ad(!(heap->type & MEM_HEAP_BTR_SEARCH));
  145. return(memset(mem_heap_alloc(heap, n), 0, n));
  146. }
  147. /***************************************************************//**
  148. Allocates n bytes of memory from a memory heap.
  149. @return allocated storage, NULL if did not succeed (only possible for
  150. MEM_HEAP_BTR_SEARCH type heaps) */
  151. UNIV_INLINE
  152. void*
  153. mem_heap_alloc(
  154. /*===========*/
  155. mem_heap_t* heap, /*!< in: memory heap */
  156. ulint n) /*!< in: number of bytes; if the heap is allowed
  157. to grow into the buffer pool, this must be
  158. <= MEM_MAX_ALLOC_IN_BUF */
  159. {
  160. mem_block_t* block;
  161. void* buf;
  162. ulint free;
  163. ut_ad(mem_heap_check(heap));
  164. block = UT_LIST_GET_LAST(heap->base);
  165. ut_ad(!(block->type & MEM_HEAP_BUFFER) || (n <= MEM_MAX_ALLOC_IN_BUF));
  166. /* Check if there is enough space in block. If not, create a new
  167. block to the heap */
  168. if (mem_block_get_len(block)
  169. < mem_block_get_free(block) + MEM_SPACE_NEEDED(n)) {
  170. block = mem_heap_add_block(heap, n);
  171. if (block == NULL) {
  172. return(NULL);
  173. }
  174. }
  175. free = mem_block_get_free(block);
  176. buf = (byte*) block + free;
  177. mem_block_set_free(block, free + MEM_SPACE_NEEDED(n));
  178. #ifdef UNIV_MEM_DEBUG
  179. UNIV_MEM_ALLOC(buf,
  180. n + MEM_FIELD_HEADER_SIZE + MEM_FIELD_TRAILER_SIZE);
  181. /* In the debug version write debugging info to the field */
  182. mem_field_init((byte*) buf, n);
  183. /* Advance buf to point at the storage which will be given to the
  184. caller */
  185. buf = (byte*) buf + MEM_FIELD_HEADER_SIZE;
  186. #endif
  187. UNIV_MEM_ALLOC(buf, n);
  188. return(buf);
  189. }
  190. /*****************************************************************//**
  191. Returns a pointer to the heap top.
  192. @return pointer to the heap top */
  193. UNIV_INLINE
  194. byte*
  195. mem_heap_get_heap_top(
  196. /*==================*/
  197. mem_heap_t* heap) /*!< in: memory heap */
  198. {
  199. mem_block_t* block;
  200. byte* buf;
  201. ut_ad(mem_heap_check(heap));
  202. block = UT_LIST_GET_LAST(heap->base);
  203. buf = (byte*) block + mem_block_get_free(block);
  204. return(buf);
  205. }
  206. /*****************************************************************//**
  207. Frees the space in a memory heap exceeding the pointer given. The
  208. pointer must have been acquired from mem_heap_get_heap_top. The first
  209. memory block of the heap is not freed. */
  210. UNIV_INLINE
  211. void
  212. mem_heap_free_heap_top(
  213. /*===================*/
  214. mem_heap_t* heap, /*!< in: heap from which to free */
  215. byte* old_top)/*!< in: pointer to old top of heap */
  216. {
  217. mem_block_t* block;
  218. mem_block_t* prev_block;
  219. #if defined UNIV_MEM_DEBUG || defined UNIV_DEBUG
  220. ibool error;
  221. ulint total_size;
  222. ulint size;
  223. ut_ad(mem_heap_check(heap));
  224. /* Validate the heap and get its total allocated size */
  225. mem_heap_validate_or_print(heap, NULL, FALSE, &error, &total_size,
  226. NULL, NULL);
  227. ut_a(!error);
  228. /* Get the size below top pointer */
  229. mem_heap_validate_or_print(heap, old_top, FALSE, &error, &size, NULL,
  230. NULL);
  231. ut_a(!error);
  232. #endif
  233. block = UT_LIST_GET_LAST(heap->base);
  234. while (block != NULL) {
  235. if (((byte*) block + mem_block_get_free(block) >= old_top)
  236. && ((byte*) block <= old_top)) {
  237. /* Found the right block */
  238. break;
  239. }
  240. /* Store prev_block value before freeing the current block
  241. (the current block will be erased in freeing) */
  242. prev_block = UT_LIST_GET_PREV(list, block);
  243. mem_heap_block_free(heap, block);
  244. block = prev_block;
  245. }
  246. ut_ad(block);
  247. /* Set the free field of block */
  248. mem_block_set_free(block, old_top - (byte*) block);
  249. ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
  250. UNIV_MEM_ASSERT_W(old_top, (byte*) block + block->len - old_top);
  251. #if defined UNIV_MEM_DEBUG
  252. /* In the debug version erase block from top up */
  253. mem_erase_buf(old_top, (byte*) block + block->len - old_top);
  254. /* Update allocated memory count */
  255. mutex_enter(&mem_hash_mutex);
  256. mem_current_allocated_memory -= (total_size - size);
  257. mutex_exit(&mem_hash_mutex);
  258. #endif /* UNIV_MEM_DEBUG */
  259. UNIV_MEM_ALLOC(old_top, (byte*) block + block->len - old_top);
  260. /* If free == start, we may free the block if it is not the first
  261. one */
  262. if ((heap != block) && (mem_block_get_free(block)
  263. == mem_block_get_start(block))) {
  264. mem_heap_block_free(heap, block);
  265. }
  266. }
  267. /*****************************************************************//**
  268. Empties a memory heap. The first memory block of the heap is not freed. */
  269. UNIV_INLINE
  270. void
  271. mem_heap_empty(
  272. /*===========*/
  273. mem_heap_t* heap) /*!< in: heap to empty */
  274. {
  275. mem_heap_free_heap_top(heap, (byte*) heap + mem_block_get_start(heap));
  276. #ifndef UNIV_HOTBACKUP
  277. if (heap->free_block) {
  278. mem_heap_free_block_free(heap);
  279. }
  280. #endif /* !UNIV_HOTBACKUP */
  281. }
  282. /*****************************************************************//**
  283. Returns a pointer to the topmost element in a memory heap. The size of the
  284. element must be given.
  285. @return pointer to the topmost element */
  286. UNIV_INLINE
  287. void*
  288. mem_heap_get_top(
  289. /*=============*/
  290. mem_heap_t* heap, /*!< in: memory heap */
  291. ulint n) /*!< in: size of the topmost element */
  292. {
  293. mem_block_t* block;
  294. byte* buf;
  295. ut_ad(mem_heap_check(heap));
  296. block = UT_LIST_GET_LAST(heap->base);
  297. buf = (byte*) block + mem_block_get_free(block) - MEM_SPACE_NEEDED(n);
  298. #ifdef UNIV_MEM_DEBUG
  299. ut_ad(mem_block_get_start(block) <= (ulint) (buf - (byte*) block));
  300. /* In the debug version, advance buf to point at the storage which
  301. was given to the caller in the allocation*/
  302. buf += MEM_FIELD_HEADER_SIZE;
  303. /* Check that the field lengths agree */
  304. ut_ad(n == mem_field_header_get_len(buf));
  305. #endif
  306. return((void*) buf);
  307. }
  308. /*****************************************************************//**
  309. Frees the topmost element in a memory heap. The size of the element must be
  310. given. */
  311. UNIV_INLINE
  312. void
  313. mem_heap_free_top(
  314. /*==============*/
  315. mem_heap_t* heap, /*!< in: memory heap */
  316. ulint n) /*!< in: size of the topmost element */
  317. {
  318. mem_block_t* block;
  319. ut_ad(mem_heap_check(heap));
  320. block = UT_LIST_GET_LAST(heap->base);
  321. /* Subtract the free field of block */
  322. mem_block_set_free(block, mem_block_get_free(block)
  323. - MEM_SPACE_NEEDED(n));
  324. UNIV_MEM_ASSERT_W((byte*) block + mem_block_get_free(block), n);
  325. #ifdef UNIV_MEM_DEBUG
  326. ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
  327. /* In the debug version check the consistency, and erase field */
  328. mem_field_erase((byte*) block + mem_block_get_free(block), n);
  329. #endif
  330. /* If free == start, we may free the block if it is not the first
  331. one */
  332. if ((heap != block) && (mem_block_get_free(block)
  333. == mem_block_get_start(block))) {
  334. mem_heap_block_free(heap, block);
  335. } else {
  336. /* Avoid a bogus UNIV_MEM_ASSERT_W() warning in a
  337. subsequent invocation of mem_heap_free_top().
  338. Originally, this was UNIV_MEM_FREE(), to catch writes
  339. to freed memory. */
  340. UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n);
  341. }
  342. }
  343. /*****************************************************************//**
  344. NOTE: Use the corresponding macros instead of this function. Creates a
  345. memory heap. For debugging purposes, takes also the file name and line as
  346. argument.
  347. @return own: memory heap, NULL if did not succeed (only possible for
  348. MEM_HEAP_BTR_SEARCH type heaps) */
  349. UNIV_INLINE
  350. mem_heap_t*
  351. mem_heap_create_func(
  352. /*=================*/
  353. ulint n, /*!< in: desired start block size,
  354. this means that a single user buffer
  355. of size n will fit in the block,
  356. 0 creates a default size block */
  357. #ifdef UNIV_DEBUG
  358. const char* file_name, /*!< in: file name where created */
  359. ulint line, /*!< in: line where created */
  360. #endif /* UNIV_DEBUG */
  361. ulint type) /*!< in: heap type */
  362. {
  363. mem_block_t* block;
  364. if (!n) {
  365. n = MEM_BLOCK_START_SIZE;
  366. }
  367. block = mem_heap_create_block(NULL, n, type, file_name, line);
  368. if (block == NULL) {
  369. return(NULL);
  370. }
  371. UT_LIST_INIT(block->base);
  372. /* Add the created block itself as the first block in the list */
  373. UT_LIST_ADD_FIRST(list, block->base, block);
  374. #ifdef UNIV_MEM_DEBUG
  375. mem_hash_insert(block, file_name, line);
  376. #endif
  377. return(block);
  378. }
  379. /*****************************************************************//**
  380. NOTE: Use the corresponding macro instead of this function. Frees the space
  381. occupied by a memory heap. In the debug version erases the heap memory
  382. blocks. */
  383. UNIV_INLINE
  384. void
  385. mem_heap_free_func(
  386. /*===============*/
  387. mem_heap_t* heap, /*!< in, own: heap to be freed */
  388. const char* file_name __attribute__((unused)),
  389. /*!< in: file name where freed */
  390. ulint line __attribute__((unused)))
  391. {
  392. mem_block_t* block;
  393. mem_block_t* prev_block;
  394. ut_ad(mem_heap_check(heap));
  395. block = UT_LIST_GET_LAST(heap->base);
  396. #ifdef UNIV_MEM_DEBUG
  397. /* In the debug version remove the heap from the hash table of heaps
  398. and check its consistency */
  399. mem_hash_remove(heap, file_name, line);
  400. #endif
  401. #ifndef UNIV_HOTBACKUP
  402. if (heap->free_block) {
  403. mem_heap_free_block_free(heap);
  404. }
  405. #endif /* !UNIV_HOTBACKUP */
  406. while (block != NULL) {
  407. /* Store the contents of info before freeing current block
  408. (it is erased in freeing) */
  409. prev_block = UT_LIST_GET_PREV(list, block);
  410. mem_heap_block_free(heap, block);
  411. block = prev_block;
  412. }
  413. }
  414. /***************************************************************//**
  415. NOTE: Use the corresponding macro instead of this function.
  416. Allocates a single buffer of memory from the dynamic memory of
  417. the C compiler. Is like malloc of C. The buffer must be freed
  418. with mem_free.
  419. @return own: free storage */
  420. UNIV_INLINE
  421. void*
  422. mem_alloc_func(
  423. /*===========*/
  424. ulint n, /*!< in: desired number of bytes */
  425. #ifdef UNIV_DEBUG
  426. const char* file_name, /*!< in: file name where created */
  427. ulint line, /*!< in: line where created */
  428. #endif /* UNIV_DEBUG */
  429. ulint* size) /*!< out: allocated size in bytes,
  430. or NULL */
  431. {
  432. mem_heap_t* heap;
  433. void* buf;
  434. heap = mem_heap_create_at(n, file_name, line);
  435. /* Note that as we created the first block in the heap big enough
  436. for the buffer requested by the caller, the buffer will be in the
  437. first block and thus we can calculate the pointer to the heap from
  438. the pointer to the buffer when we free the memory buffer. */
  439. if (size) {
  440. /* Adjust the allocation to the actual size of the
  441. memory block. */
  442. ulint m = mem_block_get_len(heap)
  443. - mem_block_get_free(heap);
  444. #ifdef UNIV_MEM_DEBUG
  445. m -= MEM_FIELD_HEADER_SIZE + MEM_FIELD_TRAILER_SIZE;
  446. #endif /* UNIV_MEM_DEBUG */
  447. ut_ad(m >= n);
  448. n = m;
  449. *size = m;
  450. }
  451. buf = mem_heap_alloc(heap, n);
  452. ut_a((byte*) heap == (byte*) buf - MEM_BLOCK_HEADER_SIZE
  453. - MEM_FIELD_HEADER_SIZE);
  454. return(buf);
  455. }
  456. /***************************************************************//**
  457. NOTE: Use the corresponding macro instead of this function. Frees a single
  458. buffer of storage from the dynamic memory of the C compiler. Similar to the
  459. free of C. */
  460. UNIV_INLINE
  461. void
  462. mem_free_func(
  463. /*==========*/
  464. void* ptr, /*!< in, own: buffer to be freed */
  465. const char* file_name, /*!< in: file name where created */
  466. ulint line) /*!< in: line where created */
  467. {
  468. mem_heap_t* heap;
  469. heap = (mem_heap_t*)((byte*) ptr - MEM_BLOCK_HEADER_SIZE
  470. - MEM_FIELD_HEADER_SIZE);
  471. mem_heap_free_func(heap, file_name, line);
  472. }
  473. /*****************************************************************//**
  474. Returns the space in bytes occupied by a memory heap. */
  475. UNIV_INLINE
  476. ulint
  477. mem_heap_get_size(
  478. /*==============*/
  479. mem_heap_t* heap) /*!< in: heap */
  480. {
  481. ulint size = 0;
  482. ut_ad(mem_heap_check(heap));
  483. size = heap->total_size;
  484. #ifndef UNIV_HOTBACKUP
  485. if (heap->free_block) {
  486. size += UNIV_PAGE_SIZE;
  487. }
  488. #endif /* !UNIV_HOTBACKUP */
  489. return(size);
  490. }
  491. /**********************************************************************//**
  492. Duplicates a NUL-terminated string.
  493. @return own: a copy of the string, must be deallocated with mem_free */
  494. UNIV_INLINE
  495. char*
  496. mem_strdup(
  497. /*=======*/
  498. const char* str) /*!< in: string to be copied */
  499. {
  500. ulint len = strlen(str) + 1;
  501. return((char*) memcpy(mem_alloc(len), str, len));
  502. }
  503. /**********************************************************************//**
  504. Makes a NUL-terminated copy of a nonterminated string.
  505. @return own: a copy of the string, must be deallocated with mem_free */
  506. UNIV_INLINE
  507. char*
  508. mem_strdupl(
  509. /*========*/
  510. const char* str, /*!< in: string to be copied */
  511. ulint len) /*!< in: length of str, in bytes */
  512. {
  513. char* s = (char*) mem_alloc(len + 1);
  514. s[len] = 0;
  515. return((char*) memcpy(s, str, len));
  516. }
  517. /**********************************************************************//**
  518. Makes a NUL-terminated copy of a nonterminated string,
  519. allocated from a memory heap.
  520. @return own: a copy of the string */
  521. UNIV_INLINE
  522. char*
  523. mem_heap_strdupl(
  524. /*=============*/
  525. mem_heap_t* heap, /*!< in: memory heap where string is allocated */
  526. const char* str, /*!< in: string to be copied */
  527. ulint len) /*!< in: length of str, in bytes */
  528. {
  529. char* s = (char*) mem_heap_alloc(heap, len + 1);
  530. s[len] = 0;
  531. return((char*) memcpy(s, str, len));
  532. }