From 354bb40e75d94466e91fe6960523612c9d17ccfb Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 2 Nov 2017 23:11:29 +0300 Subject: Add implementation --- mysql/mysys/my_once.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 mysql/mysys/my_once.c (limited to 'mysql/mysys/my_once.c') diff --git a/mysql/mysys/my_once.c b/mysql/mysys/my_once.c new file mode 100644 index 0000000..b0938f0 --- /dev/null +++ b/mysql/mysys/my_once.c @@ -0,0 +1,120 @@ +/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + 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. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +/* Not MT-SAFE */ + +#include "mysys_priv.h" +#include "my_static.h" +#include "mysys_err.h" +#include +#include "my_thread_local.h" + +/* + Alloc for things we don't nend to free run-time (that only + should be free'd on exit) + + SYNOPSIS + my_once_alloc() + Size + MyFlags + + NOTES + No DBUG_ENTER... here to get smaller dbug-startup +*/ + +void* my_once_alloc(size_t Size, myf MyFlags) +{ + size_t get_size, max_left; + uchar* point; + USED_MEM *next; + USED_MEM **prev; + + Size= ALIGN_SIZE(Size); + prev= &my_once_root_block; + max_left=0; + for (next=my_once_root_block ; next && next->left < Size ; next= next->next) + { + if (next->left > max_left) + max_left=next->left; + prev= &next->next; + } + if (! next) + { /* Time to alloc new block */ + get_size= Size+ALIGN_SIZE(sizeof(USED_MEM)); + if (max_left*4 < my_once_extra && get_size < my_once_extra) + get_size=my_once_extra; /* Normal alloc */ + + if ((next = (USED_MEM*) malloc(get_size)) == 0) + { + set_my_errno(errno); + if (MyFlags & (MY_FAE+MY_WME)) + my_error(EE_OUTOFMEMORY, MYF(ME_FATALERROR), get_size); + return((uchar*) 0); + } + DBUG_PRINT("test",("my_once_malloc %lu byte malloced", (ulong) get_size)); + next->next= 0; + next->size= (uint)get_size; + next->left= (uint)(get_size-ALIGN_SIZE(sizeof(USED_MEM))); + *prev=next; + } + point= (uchar*) ((char*) next+ (next->size-next->left)); + next->left-= (uint)Size; + + if (MyFlags & MY_ZEROFILL) + memset(point, 0, Size); + return((void*) point); +} /* my_once_alloc */ + + +char *my_once_strdup(const char *src,myf myflags) +{ + size_t len= strlen(src)+1; + uchar *dst= my_once_alloc(len, myflags); + if (dst) + memcpy(dst, src, len); + return (char*) dst; +} + + +void *my_once_memdup(const void *src, size_t len, myf myflags) +{ + uchar *dst= my_once_alloc(len, myflags); + if (dst) + memcpy(dst, src, len); + return dst; +} + + +/* + Deallocate everything that was allocated with my_once_alloc + + SYNOPSIS + my_once_free() +*/ + +void my_once_free(void) +{ + USED_MEM *next,*old; + DBUG_ENTER("my_once_free"); + + for (next=my_once_root_block ; next ; ) + { + old=next; next= next->next ; + free((uchar*) old); + } + my_once_root_block=0; + + DBUG_VOID_RETURN; +} /* my_once_free */ -- cgit v1.1