/src/mysql-server/mysys/my_once.cc
Line | Count | Source |
1 | | /* Copyright (c) 2000, 2025, Oracle and/or its affiliates. |
2 | | |
3 | | This program is free software; you can redistribute it and/or modify |
4 | | it under the terms of the GNU General Public License, version 2.0, |
5 | | as published by the Free Software Foundation. |
6 | | |
7 | | This program is designed to work with certain software (including |
8 | | but not limited to OpenSSL) that is licensed under separate terms, |
9 | | as designated in a particular file or component or in included license |
10 | | documentation. The authors of MySQL hereby grant you an additional |
11 | | permission to link the program and your derivative works with the |
12 | | separately licensed software that they have either included with |
13 | | the program or referenced in the documentation. |
14 | | |
15 | | Without limiting anything contained in the foregoing, this file, |
16 | | which is part of C Driver for MySQL (Connector/C), is also subject to the |
17 | | Universal FOSS Exception, version 1.0, a copy of which can be found at |
18 | | http://oss.oracle.com/licenses/universal-foss-exception. |
19 | | |
20 | | This program is distributed in the hope that it will be useful, |
21 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
23 | | GNU General Public License, version 2.0, for more details. |
24 | | |
25 | | You should have received a copy of the GNU General Public License |
26 | | along with this program; if not, write to the Free Software |
27 | | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
28 | | |
29 | | /** |
30 | | @file mysys/my_once.cc |
31 | | */ |
32 | | |
33 | | /* Not MT-SAFE */ |
34 | | |
35 | | #include <sys/types.h> |
36 | | #include <cerrno> |
37 | | #include <cstdlib> |
38 | | #include <cstring> |
39 | | |
40 | | #include "my_dbug.h" |
41 | | #include "my_inttypes.h" |
42 | | #include "my_pointer_arithmetic.h" |
43 | | #include "my_sys.h" |
44 | | #include "my_thread_local.h" |
45 | | #include "mysys/my_static.h" |
46 | | #include "mysys_err.h" |
47 | | |
48 | | /* |
49 | | Alloc for things we don't nend to free run-time (that only |
50 | | should be free'd on exit) |
51 | | |
52 | | SYNOPSIS |
53 | | my_once_alloc() |
54 | | Size |
55 | | MyFlags |
56 | | |
57 | | NOTES |
58 | | No DBUG_TRACE... here to get smaller dbug-startup |
59 | | */ |
60 | | |
61 | 928 | void *my_once_alloc(size_t Size, myf MyFlags) { |
62 | 928 | size_t get_size, max_left; |
63 | 928 | uchar *point; |
64 | 928 | USED_MEM *next; |
65 | 928 | USED_MEM **prev; |
66 | | |
67 | 928 | Size = ALIGN_SIZE(Size); |
68 | 928 | prev = &my_once_root_block; |
69 | 928 | max_left = 0; |
70 | 18.5k | for (next = my_once_root_block; next && next->left < Size; |
71 | 17.6k | next = next->next) { |
72 | 17.6k | if (next->left > max_left) max_left = next->left; |
73 | 17.6k | prev = &next->next; |
74 | 17.6k | } |
75 | 928 | if (!next) { /* Time to alloc new block */ |
76 | 84 | get_size = Size + ALIGN_SIZE(sizeof(USED_MEM)); |
77 | 84 | if (max_left * 4 < my_once_extra && get_size < my_once_extra) |
78 | 84 | get_size = my_once_extra; /* Normal alloc */ |
79 | | |
80 | 84 | if ((next = (USED_MEM *)malloc(get_size)) == nullptr) { |
81 | 0 | set_my_errno(errno); |
82 | 0 | if (MyFlags & (MY_FAE + MY_WME)) |
83 | 0 | my_error(EE_OUTOFMEMORY, MYF(ME_FATALERROR), get_size); |
84 | 0 | return ((uchar *)nullptr); |
85 | 0 | } |
86 | 84 | DBUG_PRINT("test", ("my_once_malloc %lu byte malloced", (ulong)get_size)); |
87 | 84 | next->next = nullptr; |
88 | 84 | next->size = (uint)get_size; |
89 | 84 | next->left = (uint)(get_size - ALIGN_SIZE(sizeof(USED_MEM))); |
90 | 84 | *prev = next; |
91 | 84 | } |
92 | 928 | point = (uchar *)((char *)next + (next->size - next->left)); |
93 | 928 | next->left -= (uint)Size; |
94 | | |
95 | 928 | if (MyFlags & MY_ZEROFILL) memset(point, 0, Size); |
96 | 928 | return ((void *)point); |
97 | 928 | } /* my_once_alloc */ |
98 | | |
99 | 0 | char *my_once_strdup(const char *src, myf myflags) { |
100 | 0 | const size_t len = strlen(src) + 1; |
101 | 0 | auto *dst = static_cast<uchar *>(my_once_alloc(len, myflags)); |
102 | 0 | if (dst) memcpy(dst, src, len); |
103 | 0 | return (char *)dst; |
104 | 0 | } |
105 | | |
106 | 0 | void *my_once_memdup(const void *src, size_t len, myf myflags) { |
107 | 0 | auto *dst = static_cast<uchar *>(my_once_alloc(len, myflags)); |
108 | 0 | if (dst) memcpy(dst, src, len); |
109 | 0 | return dst; |
110 | 0 | } |
111 | | |
112 | | /* |
113 | | Deallocate everything that was allocated with my_once_alloc |
114 | | |
115 | | SYNOPSIS |
116 | | my_once_free() |
117 | | */ |
118 | | |
119 | 0 | void my_once_free() { |
120 | 0 | USED_MEM *next, *old; |
121 | 0 | DBUG_TRACE; |
122 | |
|
123 | 0 | for (next = my_once_root_block; next;) { |
124 | 0 | old = next; |
125 | 0 | next = next->next; |
126 | 0 | free((uchar *)old); |
127 | 0 | } |
128 | 0 | my_once_root_block = nullptr; |
129 | 0 | } /* my_once_free */ |