1 | /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. |
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 as published by |
5 | the Free Software Foundation; version 2 of the License. |
6 | |
7 | This program is distributed in the hope that it will be useful, |
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 | GNU General Public License for more details. |
11 | |
12 | You should have received a copy of the GNU General Public License |
13 | along with this program; if not, write to the Free Software |
14 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
15 | |
16 | /* Not MT-SAFE */ |
17 | |
18 | #include "mysys_priv.h" |
19 | #include "my_static.h" |
20 | #include "mysys_err.h" |
21 | #include <m_string.h> |
22 | |
23 | /* |
24 | Alloc for things we don't nend to free run-time (that only |
25 | should be free'd on exit) |
26 | |
27 | SYNOPSIS |
28 | my_once_alloc() |
29 | Size |
30 | MyFlags |
31 | |
32 | NOTES |
33 | No DBUG_ENTER... here to get smaller dbug-startup |
34 | */ |
35 | |
36 | void* my_once_alloc(size_t Size, myf MyFlags) |
37 | { |
38 | size_t get_size, max_left; |
39 | uchar* point; |
40 | reg1 USED_MEM *next; |
41 | reg2 USED_MEM **prev; |
42 | |
43 | Size= ALIGN_SIZE(Size); |
44 | prev= &my_once_root_block; |
45 | max_left=0; |
46 | for (next=my_once_root_block ; next && next->left < Size ; next= next->next) |
47 | { |
48 | if (next->left > max_left) |
49 | max_left=next->left; |
50 | prev= &next->next; |
51 | } |
52 | if (! next) |
53 | { /* Time to alloc new block */ |
54 | get_size= Size+ALIGN_SIZE(sizeof(USED_MEM)); |
55 | if (max_left*4 < my_once_extra && get_size < my_once_extra) |
56 | get_size=my_once_extra; /* Normal alloc */ |
57 | |
58 | if ((next = (USED_MEM*) malloc(get_size)) == 0) |
59 | { |
60 | my_errno=errno; |
61 | if (MyFlags & (MY_FAE+MY_WME)) |
62 | my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG+ME_FATALERROR), get_size); |
63 | return((uchar*) 0); |
64 | } |
65 | DBUG_PRINT("test" ,("my_once_malloc %lu byte malloced" , (ulong) get_size)); |
66 | next->next= 0; |
67 | next->size= get_size; |
68 | next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM)); |
69 | *prev=next; |
70 | } |
71 | point= (uchar*) ((char*) next+ (next->size-next->left)); |
72 | next->left-= Size; |
73 | |
74 | if (MyFlags & MY_ZEROFILL) |
75 | bzero(point, Size); |
76 | return((void*) point); |
77 | } /* my_once_alloc */ |
78 | |
79 | |
80 | char *my_once_strdup(const char *src,myf myflags) |
81 | { |
82 | size_t len= strlen(src)+1; |
83 | uchar *dst= my_once_alloc(len, myflags); |
84 | if (dst) |
85 | memcpy(dst, src, len); |
86 | return (char*) dst; |
87 | } |
88 | |
89 | |
90 | void *my_once_memdup(const void *src, size_t len, myf myflags) |
91 | { |
92 | uchar *dst= my_once_alloc(len, myflags); |
93 | if (dst) |
94 | memcpy(dst, src, len); |
95 | return dst; |
96 | } |
97 | |
98 | |
99 | /* |
100 | Deallocate everything that was allocated with my_once_alloc |
101 | |
102 | SYNOPSIS |
103 | my_once_free() |
104 | */ |
105 | |
106 | void my_once_free(void) |
107 | { |
108 | reg1 USED_MEM *next,*old; |
109 | DBUG_ENTER("my_once_free" ); |
110 | |
111 | for (next=my_once_root_block ; next ; ) |
112 | { |
113 | old=next; next= next->next ; |
114 | free((uchar*) old); |
115 | } |
116 | my_once_root_block=0; |
117 | |
118 | DBUG_VOID_RETURN; |
119 | } /* my_once_free */ |
120 | |