1 /* Copyright (c) 2019, Oracle and/or its affiliates. All Rights Reserved.
2 
3 This program is free software; you can redistribute it and/or modify it under
4 the terms of the GNU General Public License, version 2.0, as published by the
5 Free Software Foundation.
6 
7 This program is also distributed with certain software (including but not
8 limited to OpenSSL) that is licensed under separate terms, as designated in a
9 particular file or component or in included license documentation. The authors
10 of MySQL hereby grant you an additional permission to link the program and
11 your derivative works with the separately licensed software that they have
12 included with MySQL.
13 
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
17 for more details.
18 
19 You should have received a copy of the GNU General Public License along with
20 this program; if not, write to the Free Software Foundation, Inc.,
21 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 /** @file storage/temptable/src/block.cc */
24 
25 #include "my_dbug.h"
26 #include "my_psi_config.h"
27 #include "mysql/psi/mysql_memory.h"
28 #include "mysql/psi/psi_base.h"
29 #include "mysql/psi/psi_memory.h"
30 
31 #ifdef HAVE_PSI_MEMORY_INTERFACE
32 #define TEMPTABLE_PFS_MEMORY
33 
34 /* Enabling this causes ~ 4% performance drop in sysbench distinct ranges. */
35 //#define TEMPTABLE_PFS_MEMORY_COUNT_LOGICAL
36 #endif /* HAVE_PSI_MEMORY_INTERFACE */
37 
38 namespace temptable {
39 
40 #ifdef TEMPTABLE_PFS_MEMORY
41 #ifdef TEMPTABLE_PFS_MEMORY_COUNT_LOGICAL
42 /** PFS key to account logical memory allocations and deallocations. Logical
43  * is any request for new memory that arrives to the allocator. */
44 PSI_memory_key mem_key_logical;
45 #endif /* TEMPTABLE_PFS_MEMORY_COUNT_LOGICAL */
46 
47 /** PFS key to account physical allocations and deallocations from disk. After
48  * we have allocated more than `temptable_max_ram` we start taking memory from
49  * the OS disk, using mmap()'ed files. */
50 PSI_memory_key mem_key_physical_disk;
51 
52 /** PFS key to account physical allocations and deallocations from RAM. Before
53  * we have allocated more than `temptable_max_ram` we take memory from the OS
54  * RAM, using e.g. malloc(). */
55 PSI_memory_key mem_key_physical_ram;
56 
57 /** Array of PFS keys. */
58 PSI_memory_info pfs_info[] = {
59 #ifdef TEMPTABLE_PFS_MEMORY_COUNT_LOGICAL
60     {&mem_key_logical, "logical", 0, 0, PSI_DOCUMENT_ME},
61 #endif /* TEMPTABLE_PFS_MEMORY_COUNT_LOGICAL */
62     {&mem_key_physical_disk, "physical_disk", 0, 0, PSI_DOCUMENT_ME},
63     {&mem_key_physical_ram, "physical_ram", PSI_FLAG_ONLY_GLOBAL_STAT, 0,
64      PSI_DOCUMENT_ME},
65 };
66 
67 /** Number of elements inside `pfs_info[]`. */
68 const size_t pfs_info_num_elements = sizeof(pfs_info) / sizeof(pfs_info[0]);
69 #endif /* TEMPTABLE_PFS_MEMORY */
70 
Block_PSI_init()71 void Block_PSI_init() {
72 #ifdef TEMPTABLE_PFS_MEMORY
73   PSI_MEMORY_CALL(register_memory)
74   ("temptable", pfs_info, pfs_info_num_elements);
75 #endif /* TEMPTABLE_PFS_MEMORY */
76 }
77 
Block_PSI_track_logical_allocation(size_t size)78 void Block_PSI_track_logical_allocation(size_t size) {
79   (void)size;
80 #ifdef TEMPTABLE_PFS_MEMORY_COUNT_LOGICAL
81   PSI_thread *owner_thread;
82 
83 #ifndef DBUG_OFF
84   PSI_memory_key key =
85 #endif /* DBUG_OFF */
86       PSI_MEMORY_CALL(memory_alloc)(mem_key_logical, size, &owner_thread);
87 
88   DBUG_ASSERT(key == mem_key_logical || key == PSI_NOT_INSTRUMENTED);
89 #endif /* TEMPTABLE_PFS_MEMORY_COUNT_LOGICAL */
90 }
91 
Block_PSI_track_logical_deallocation(size_t size)92 void Block_PSI_track_logical_deallocation(size_t size) {
93   (void)size;
94 #ifdef TEMPTABLE_PFS_MEMORY_COUNT_LOGICAL
95   PSI_MEMORY_CALL(memory_free)
96   (mem_key_logical, size, nullptr);
97 #endif /* TEMPTABLE_PFS_MEMORY_COUNT_LOGICAL */
98 }
99 
Block_PSI_track_physical_ram_allocation(size_t size)100 void Block_PSI_track_physical_ram_allocation(size_t size) {
101   (void)size;
102 #ifdef TEMPTABLE_PFS_MEMORY
103   const PSI_memory_key psi_key = mem_key_physical_ram;
104   PSI_thread *owner_thread;
105 #ifndef DBUG_OFF
106   PSI_memory_key got_key =
107 #endif /* DBUG_OFF */
108       PSI_MEMORY_CALL(memory_alloc)(psi_key, size, &owner_thread);
109   DBUG_ASSERT(got_key == psi_key || got_key == PSI_NOT_INSTRUMENTED);
110 #endif /* TEMPTABLE_PFS_MEMORY */
111 }
112 
Block_PSI_track_physical_ram_deallocation(size_t size)113 void Block_PSI_track_physical_ram_deallocation(size_t size) {
114   (void)size;
115 #ifdef TEMPTABLE_PFS_MEMORY
116   PSI_MEMORY_CALL(memory_free)(mem_key_physical_ram, size, nullptr);
117 #endif /* TEMPTABLE_PFS_MEMORY */
118 }
119 
Block_PSI_track_physical_disk_allocation(size_t size)120 void Block_PSI_track_physical_disk_allocation(size_t size) {
121   (void)size;
122 #ifdef TEMPTABLE_PFS_MEMORY
123   const PSI_memory_key psi_key = mem_key_physical_disk;
124   PSI_thread *owner_thread;
125 #ifndef DBUG_OFF
126   PSI_memory_key got_key =
127 #endif /* DBUG_OFF */
128       PSI_MEMORY_CALL(memory_alloc)(psi_key, size, &owner_thread);
129   DBUG_ASSERT(got_key == psi_key || got_key == PSI_NOT_INSTRUMENTED);
130 #endif /* TEMPTABLE_PFS_MEMORY */
131 }
132 
Block_PSI_track_physical_disk_deallocation(size_t size)133 void Block_PSI_track_physical_disk_deallocation(size_t size) {
134   (void)size;
135 #ifdef TEMPTABLE_PFS_MEMORY
136   PSI_MEMORY_CALL(memory_free)(mem_key_physical_disk, size, nullptr);
137 #endif /* TEMPTABLE_PFS_MEMORY */
138 }
139 
140 } /* namespace temptable */
141