Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / sal / rtl / alloc_cache.cxx
blob1f165cca161c94dce81e2e75eedf68416158ec11
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "alloc_cache.hxx"
21 #include "alloc_impl.hxx"
22 #include "alloc_arena.hxx"
23 #include <rtllifecycle.h>
25 #include <cassert>
26 #include <cstdlib>
27 #include <string.h>
28 #include <stdio.h>
30 /**
31 provided for cache_type allocations, and hash_table resizing.
33 @internal
35 static rtl_arena_type * gp_cache_arena = nullptr;
37 namespace
40 rtl_cache_type * rtl_cache_activate(
41 rtl_cache_type * cache,
42 const char * name,
43 size_t objsize,
44 size_t objalign,
45 int (SAL_CALL * constructor)(void * obj, void * userarg),
46 void (SAL_CALL * destructor) (void * obj, void * userarg),
47 void * userarg
50 assert(cache);
52 snprintf (cache->m_name, sizeof(cache->m_name), "%s", name);
54 if (objalign == 0)
56 /* determine default alignment */
57 if (objsize >= RTL_MEMORY_ALIGNMENT_8)
58 objalign = RTL_MEMORY_ALIGNMENT_8;
59 else
60 objalign = RTL_MEMORY_ALIGNMENT_4;
62 else
64 /* ensure minimum alignment */
65 if(objalign < RTL_MEMORY_ALIGNMENT_4)
67 objalign = RTL_MEMORY_ALIGNMENT_4;
70 assert(RTL_MEMORY_ISP2(objalign));
72 cache->m_type_size = RTL_MEMORY_P2ROUNDUP(objsize, objalign);
74 cache->m_constructor = constructor;
75 cache->m_destructor = destructor;
76 cache->m_userarg = userarg;
78 return cache;
81 } //namespace
83 rtl_cache_type * SAL_CALL rtl_cache_create(
84 const char * name,
85 sal_Size objsize,
86 sal_Size objalign,
87 int (SAL_CALL * constructor)(void * obj, void * userarg),
88 void (SAL_CALL * destructor) (void * obj, void * userarg),
89 void (SAL_CALL * /*reclaim*/) (void * userarg),
90 void * userarg,
91 rtl_arena_type *,
92 int
93 ) SAL_THROW_EXTERN_C()
95 rtl_cache_type * result = nullptr;
96 sal_Size size = sizeof(rtl_cache_type);
98 try_alloc:
99 result = static_cast<rtl_cache_type*>(rtl_arena_alloc (gp_cache_arena, &size));
100 if (result)
102 rtl_cache_type * cache = result;
103 memset (cache, 0, sizeof(rtl_cache_type));
105 result = rtl_cache_activate (
106 cache,
107 name,
108 objsize,
109 objalign,
110 constructor,
111 destructor,
112 userarg
115 if (!result)
117 /* activation failed */
118 rtl_arena_free (gp_cache_arena, cache, size);
121 else if (!gp_cache_arena)
123 ensureCacheSingleton();
124 if (gp_cache_arena)
126 /* try again */
127 goto try_alloc;
130 return result;
133 void SAL_CALL rtl_cache_destroy(rtl_cache_type * cache) SAL_THROW_EXTERN_C()
135 if (cache)
137 rtl_arena_free (gp_cache_arena, cache, sizeof(rtl_cache_type));
141 void * SAL_CALL rtl_cache_alloc(rtl_cache_type * cache) SAL_THROW_EXTERN_C()
143 void * obj = nullptr;
145 if (!cache)
146 return nullptr;
148 obj = std::malloc(cache->m_type_size);
149 if (obj && cache->m_constructor)
151 if (!(cache->m_constructor)(obj, cache->m_userarg))
153 /* construction failure */
154 std::free(obj);
155 obj = nullptr;
158 return obj;
161 void SAL_CALL rtl_cache_free(
162 rtl_cache_type * cache,
163 void * obj
164 ) SAL_THROW_EXTERN_C()
166 if (obj && cache)
168 if (cache->m_destructor)
170 /* destruct object */
171 (cache->m_destructor)(obj, cache->m_userarg);
173 std::free(obj);
177 #if defined(SAL_UNX)
179 void SAL_CALL rtl_secureZeroMemory(void *Ptr, sal_Size Bytes) SAL_THROW_EXTERN_C()
181 //currently glibc doesn't implement memset_s
182 volatile char *p = static_cast<volatile char*>(Ptr);
183 while (Bytes--)
184 *p++ = 0;
187 #elif defined(_WIN32)
189 void SAL_CALL rtl_secureZeroMemory(void *Ptr, sal_Size Bytes) SAL_THROW_EXTERN_C()
191 RtlSecureZeroMemory(Ptr, Bytes);
194 #endif /* SAL_UNX || _WIN32 */
196 void rtl_cache_init()
198 /* cache: internal arena */
199 assert(!gp_cache_arena);
201 gp_cache_arena = rtl_arena_create (
202 "rtl_cache_internal_arena",
203 64, /* quantum */
204 0, /* no quantum caching */
205 nullptr, /* default source */
206 rtl_arena_alloc,
207 rtl_arena_free,
208 0 /* flags */
210 assert(gp_cache_arena);
212 /* check 'gp_default_arena' initialization */
213 assert(gp_default_arena);
216 void rtl_cache_fini()
218 if (gp_cache_arena)
220 rtl_arena_destroy (gp_cache_arena);
221 gp_cache_arena = nullptr;
225 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */