diff options
-rw-r--r-- | desktop/source/lib/init.cxx | 1 | ||||
-rw-r--r-- | include/rtl/alloc.h | 18 | ||||
-rw-r--r-- | sal/inc/rtllifecycle.h | 4 | ||||
-rw-r--r-- | sal/rtl/alloc_cache.cxx | 953 | ||||
-rw-r--r-- | sal/rtl/alloc_cache.hxx | 116 | ||||
-rw-r--r-- | sal/rtl/strimp.cxx | 10 |
6 files changed, 43 insertions, 1059 deletions
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 0b3582f8c07c..04f586ce4eb3 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -3971,7 +3971,6 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char if (eStage == PRE_INIT) { comphelper::ThreadPool::getSharedOptimalPool().shutdown(); - rtl_alloc_preInit(rtlAllocPostInit); } return bInitialized; diff --git a/include/rtl/alloc.h b/include/rtl/alloc.h index a55df0aaaf4c..cc3cec6ef292 100644 --- a/include/rtl/alloc.h +++ b/include/rtl/alloc.h @@ -220,7 +220,7 @@ typedef struct rtl_cache_st rtl_cache_type; #define RTL_CACHE_NAME_LENGTH 31 -#define RTL_CACHE_FLAG_BULKDESTROY 1 +#define RTL_CACHE_FLAG_BULKDESTROY 1 /* obsolete */ /** * @param[in] pName descriptive name; for debugging purposes. @@ -230,8 +230,8 @@ typedef struct rtl_cache_st rtl_cache_type; * @param[in] destructor object destructor callback function. * @param[in] reclaim reclaim callback function. * @param[in] pUserArg opaque argument passed to callback functions. - * @param[in] pSource opaque argument passed to callback functions. - * @param[in] nFlags flags. + * @param[in] pSource unused argument (should be null). + * @param[in] nFlags flags (unused). * * @return pointer to rtl_cache_type, or NULL upon failure. * @@ -299,16 +299,6 @@ SAL_DLLPUBLIC void SAL_CALL rtl_cache_free ( * spawning per-document instances. This is done * by calling rtl_alloc_preInit with rtlAllocPreInitStart. * - * However before forking we need to wind down - * all threads, which is required by design. - * This is done by calling rtl_alloc_preInit - * with rtlAllocPreInitEnd. - * - * And of course the stopped threads need restarting - * after forking to ensure correct cleanup of the - * caches and other memory allocations. This is done - * by calling rtl_alloc_preInit with rtlAllocPostInit. - * * @since LibreOffice 6.1 */ typedef enum @@ -317,7 +307,7 @@ typedef enum rtlAllocPreInitStart, // Finish phase I of pre-init (before forking). rtlAllocPreInitEnd, - // Post pre-init and after forking. + // Post pre-init and after forking; no longer used. rtlAllocPostInit } rtl_alloc_preInit_phase_t; diff --git a/sal/inc/rtllifecycle.h b/sal/inc/rtllifecycle.h index 4574ae821905..44af09e58cc2 100644 --- a/sal/inc/rtllifecycle.h +++ b/sal/inc/rtllifecycle.h @@ -26,10 +26,6 @@ void rtl_cache_fini(void); void ensureCacheSingleton(void); -void rtl_cache_stop_threads(void); - -void rtl_cache_start_threads(void); - void rtl_locale_init(void); void rtl_locale_fini(void); diff --git a/sal/rtl/alloc_cache.cxx b/sal/rtl/alloc_cache.cxx index 28add71c7860..b4d7a0060d39 100644 --- a/sal/rtl/alloc_cache.cxx +++ b/sal/rtl/alloc_cache.cxx @@ -21,38 +21,11 @@ #include "alloc_impl.hxx" #include "alloc_arena.hxx" #include <rtllifecycle.h> -#include <sal/macros.h> -#include <osl/thread.hxx> #include <cassert> #include <string.h> #include <stdio.h> -#if defined(SAL_UNX) -#include <sys/time.h> -#endif -#include <algorithm> - -/** - * @internal - */ -struct rtl_cache_list_st -{ - rtl_memory_lock_type m_lock; - rtl_cache_type m_cache_head; - -#if defined(SAL_UNX) - pthread_t m_update_thread; - pthread_cond_t m_update_cond; -#elif defined(_WIN32) - HANDLE m_update_thread; - HANDLE m_update_cond; -#endif /* SAL_UNX || _WIN32 */ - int m_update_done; -}; - -static rtl_cache_list_st g_cache_list; - /** provided for cache_type allocations, and hash_table resizing. @@ -60,379 +33,9 @@ static rtl_cache_list_st g_cache_list; */ static rtl_arena_type * gp_cache_arena = nullptr; -/** - @internal -*/ -static rtl_cache_type * gp_cache_magazine_cache = nullptr; - -/** - @internal -*/ -static rtl_cache_type * gp_cache_slab_cache = nullptr; - -/** - @internal -*/ -static rtl_cache_type * gp_cache_bufctl_cache = nullptr; - -#define RTL_CACHE_HASH_INDEX_IMPL(a, s, q, m) \ - ((((a) + ((a) >> (s)) + ((a) >> ((s) << 1))) >> (q)) & (m)) - -#define RTL_CACHE_HASH_INDEX(cache, addr) \ - RTL_CACHE_HASH_INDEX_IMPL((addr), (cache)->m_hash_shift, (cache)->m_type_shift, ((cache)->m_hash_size - 1)) - namespace { -void rtl_cache_hash_rescale( - rtl_cache_type * cache, - sal_Size new_size -) -{ - rtl_cache_bufctl_type ** new_table; - sal_Size new_bytes; - - new_bytes = new_size * sizeof(rtl_cache_bufctl_type*); - new_table = static_cast<rtl_cache_bufctl_type**>(rtl_arena_alloc(gp_cache_arena, &new_bytes)); - - if (new_table) - { - rtl_cache_bufctl_type ** old_table; - sal_Size old_size, i; - - memset (new_table, 0, new_bytes); - - RTL_MEMORY_LOCK_ACQUIRE(&(cache->m_slab_lock)); - - old_table = cache->m_hash_table; - old_size = cache->m_hash_size; - - cache->m_hash_table = new_table; - cache->m_hash_size = new_size; - const auto bit = highbit(cache->m_hash_size); - assert(bit > 0); - cache->m_hash_shift = bit - 1; - - for (i = 0; i < old_size; i++) - { - rtl_cache_bufctl_type * curr = old_table[i]; - while (curr) - { - rtl_cache_bufctl_type * next = curr->m_next; - rtl_cache_bufctl_type ** head; - - head = &(cache->m_hash_table[RTL_CACHE_HASH_INDEX(cache, curr->m_addr)]); - curr->m_next = (*head); - (*head) = curr; - - curr = next; - } - old_table[i] = nullptr; - } - - RTL_MEMORY_LOCK_RELEASE(&(cache->m_slab_lock)); - - if (old_table != cache->m_hash_table_0) - { - sal_Size old_bytes = old_size * sizeof(rtl_cache_bufctl_type*); - rtl_arena_free (gp_cache_arena, old_table, old_bytes); - } - } -} - -rtl_cache_bufctl_type * rtl_cache_hash_remove( - rtl_cache_type * cache, - sal_uIntPtr addr -) -{ - rtl_cache_bufctl_type ** ppHead; - rtl_cache_bufctl_type * bufctl; - sal_Size lookups = 0; - - ppHead = &(cache->m_hash_table[RTL_CACHE_HASH_INDEX(cache, addr)]); - while ((bufctl = *ppHead)) - { - if (bufctl->m_addr == addr) - { - *ppHead = bufctl->m_next; - bufctl->m_next = nullptr; - break; - } - - lookups += 1; - ppHead = &(bufctl->m_next); - } - - assert(bufctl); // bad free - - if (lookups > 1) - { - sal_Size nbuf = static_cast<sal_Size>(cache->m_slab_stats.m_alloc - cache->m_slab_stats.m_free); - if (nbuf > 4 * cache->m_hash_size) - { - if (!(cache->m_features & RTL_CACHE_FEATURE_RESCALE)) - { - sal_Size ave = nbuf >> cache->m_hash_shift; - const auto bit = highbit(ave); - assert(bit > 0); - sal_Size new_size = cache->m_hash_size << (bit - 1); - - cache->m_features |= RTL_CACHE_FEATURE_RESCALE; - RTL_MEMORY_LOCK_RELEASE(&(cache->m_slab_lock)); - rtl_cache_hash_rescale (cache, new_size); - RTL_MEMORY_LOCK_ACQUIRE(&(cache->m_slab_lock)); - cache->m_features &= ~RTL_CACHE_FEATURE_RESCALE; - } - } - } - - return bufctl; -} - -#define RTL_CACHE_SLAB(addr, size) \ - ((reinterpret_cast<rtl_cache_slab_type*>(RTL_MEMORY_P2END(reinterpret_cast<sal_uIntPtr>(addr), (size)))) - 1) - -int rtl_cache_slab_constructor(void * obj, SAL_UNUSED_PARAMETER void *) -{ - rtl_cache_slab_type * slab = static_cast<rtl_cache_slab_type*>(obj); - - QUEUE_START_NAMED(slab, slab_); - slab->m_ntypes = 0; - - return 1; -} - -void rtl_cache_slab_destructor(void * obj, SAL_UNUSED_PARAMETER void *) -{ - rtl_cache_slab_type * slab = static_cast< rtl_cache_slab_type * >(obj); - assert(QUEUE_STARTED_NAMED(slab, slab_)); // assure removed from queue(s) - assert(slab->m_ntypes == 0); // assure no longer referenced - (void) slab; // avoid warnings -} - -/** - @precond cache->m_slab_lock released. -*/ -void rtl_cache_slab_destroy( - rtl_cache_type * cache, - rtl_cache_slab_type * slab -) -{ - void * addr = reinterpret_cast<void*>(slab->m_data); - sal_Size refcnt = slab->m_ntypes; slab->m_ntypes = 0; - - if (cache->m_features & RTL_CACHE_FEATURE_HASH) - { - /* cleanup bufctl(s) for free buffer(s) */ - sal_Size ntypes = (slab->m_bp - slab->m_data) / cache->m_type_size; - for (ntypes -= refcnt; slab->m_sp; ntypes--) - { - rtl_cache_bufctl_type * bufctl = slab->m_sp; - - /* pop from freelist */ - slab->m_sp = bufctl->m_next; - bufctl->m_next = nullptr; - - /* return bufctl struct to bufctl cache */ - rtl_cache_free (gp_cache_bufctl_cache, bufctl); - } - assert(ntypes == 0); - - /* return slab struct to slab cache */ - rtl_cache_free (gp_cache_slab_cache, slab); - } - else - { - /* destruct embedded slab struct */ - rtl_cache_slab_destructor (slab, nullptr); - } - - if (refcnt == 0 || cache->m_features & RTL_CACHE_FEATURE_BULKDESTROY) - { - /* free memory */ - rtl_arena_free (cache->m_source, addr, cache->m_slab_size); - } -} - -/** - Return a buffer to slab layer; used by magazine layer. -*/ -void rtl_cache_slab_free( - rtl_cache_type * cache, - void * addr -) -{ - rtl_cache_bufctl_type * bufctl; - rtl_cache_slab_type * slab; - - RTL_MEMORY_LOCK_ACQUIRE(&(cache->m_slab_lock)); - - /* determine slab from addr */ - if (cache->m_features & RTL_CACHE_FEATURE_HASH) - { - bufctl = rtl_cache_hash_remove (cache, reinterpret_cast<sal_uIntPtr>(addr)); - slab = (bufctl != nullptr) ? reinterpret_cast<rtl_cache_slab_type*>(bufctl->m_slab) : nullptr; - } - else - { - /* embedded slab struct */ - bufctl = static_cast<rtl_cache_bufctl_type*>(addr); - slab = RTL_CACHE_SLAB(addr, cache->m_slab_size); - } - - if (slab) - { - /* check for full slab */ - if (slab->m_ntypes == cache->m_ntypes) - { - /* remove from 'used' queue */ - QUEUE_REMOVE_NAMED(slab, slab_); - - /* insert onto 'free' queue (head) */ - QUEUE_INSERT_HEAD_NAMED(&(cache->m_free_head), slab, slab_); - } - - /* push front */ - bufctl->m_next = slab->m_sp; - slab->m_sp = bufctl; - - /* update stats */ - cache->m_slab_stats.m_free += 1; - cache->m_slab_stats.m_mem_alloc -= cache->m_type_size; - - /* decrement usage, check for empty slab */ - if ((slab->m_ntypes -= 1) == 0) - { - /* remove from 'free' queue */ - QUEUE_REMOVE_NAMED(slab, slab_); - - /* update stats */ - cache->m_slab_stats.m_mem_total -= cache->m_slab_size; - - /* free 'empty' slab */ - RTL_MEMORY_LOCK_RELEASE(&(cache->m_slab_lock)); - rtl_cache_slab_destroy (cache, slab); - return; - } - } - - RTL_MEMORY_LOCK_RELEASE(&(cache->m_slab_lock)); -} - -int rtl_cache_magazine_constructor(void * obj, SAL_UNUSED_PARAMETER void *) -{ - rtl_cache_magazine_type * mag = static_cast<rtl_cache_magazine_type*>(obj); - /* @@@ sal_Size size = (sal_Size)(arg); @@@ */ - - mag->m_mag_next = nullptr; - mag->m_mag_size = RTL_CACHE_MAGAZINE_SIZE; - mag->m_mag_used = 0; - - return 1; -} - -void rtl_cache_magazine_destructor(void * obj, SAL_UNUSED_PARAMETER void *) -{ - rtl_cache_magazine_type * mag = static_cast< rtl_cache_magazine_type * >( - obj); - assert(!mag->m_mag_next); // assure removed from queue(s) - assert(mag->m_mag_used == 0); // assure no longer referenced - (void) mag; // avoid warnings -} - -void rtl_cache_magazine_clear( - rtl_cache_type * cache, - rtl_cache_magazine_type * mag -) -{ - for (; mag->m_mag_used > 0; --mag->m_mag_used) - { - void * obj = mag->m_objects[mag->m_mag_used-1]; - mag->m_objects[mag->m_mag_used-1] = nullptr; - - if (cache->m_destructor) - { - /* destruct object */ - (cache->m_destructor)(obj, cache->m_userarg); - } - - /* return buffer to slab layer */ - rtl_cache_slab_free (cache, obj); - } -} - -/** - @precond cache->m_depot_lock acquired. -*/ -inline rtl_cache_magazine_type * rtl_cache_depot_dequeue( - rtl_cache_depot_type * depot -) -{ - rtl_cache_magazine_type * mag = nullptr; - if (depot->m_mag_count > 0) - { - /* dequeue magazine */ - assert(depot->m_mag_next); - - mag = depot->m_mag_next; - depot->m_mag_next = mag->m_mag_next; - mag->m_mag_next = nullptr; - - /* update depot stats */ - depot->m_mag_count--; - if(depot->m_curr_min > depot->m_mag_count) - { - depot->m_curr_min = depot->m_mag_count; - } - } - return mag; -} - - -void rtl_cache_constructor(void * obj) -{ - rtl_cache_type * cache = static_cast<rtl_cache_type*>(obj); - - memset (cache, 0, sizeof(rtl_cache_type)); - - /* linkage */ - QUEUE_START_NAMED(cache, cache_); - - /* slab layer */ - RTL_MEMORY_LOCK_INIT(&(cache->m_slab_lock)); - - QUEUE_START_NAMED(&(cache->m_free_head), slab_); - QUEUE_START_NAMED(&(cache->m_used_head), slab_); - - cache->m_hash_table = cache->m_hash_table_0; - cache->m_hash_size = RTL_CACHE_HASH_SIZE; - cache->m_hash_shift = highbit(cache->m_hash_size) - 1; - - /* depot layer */ - RTL_MEMORY_LOCK_INIT(&(cache->m_depot_lock)); -} - -void rtl_cache_destructor(void * obj) -{ - rtl_cache_type * cache = static_cast<rtl_cache_type*>(obj); - - /* linkage */ - assert(QUEUE_STARTED_NAMED(cache, cache_)); - - /* slab layer */ - RTL_MEMORY_LOCK_DESTROY(&(cache->m_slab_lock)); - - assert(QUEUE_STARTED_NAMED(&(cache->m_free_head), slab_)); - assert(QUEUE_STARTED_NAMED(&(cache->m_used_head), slab_)); - - assert(cache->m_hash_table == cache->m_hash_table_0); - assert(cache->m_hash_size == RTL_CACHE_HASH_SIZE); - assert(cache->m_hash_shift == highbit(cache->m_hash_size) - 1); - - /* depot layer */ - RTL_MEMORY_LOCK_DESTROY(&(cache->m_depot_lock)); -} - rtl_cache_type * rtl_cache_activate( rtl_cache_type * cache, const char * name, @@ -440,221 +43,38 @@ rtl_cache_type * rtl_cache_activate( size_t objalign, int (SAL_CALL * constructor)(void * obj, void * userarg), void (SAL_CALL * destructor) (void * obj, void * userarg), - void * userarg, - rtl_arena_type * source, - int flags + void * userarg ) { assert(cache); - if (cache) - { - sal_Size slabsize; - - snprintf (cache->m_name, sizeof(cache->m_name), "%s", name); - - /* ensure minimum size (embedded bufctl linkage) */ - if(objsize < sizeof(rtl_cache_bufctl_type*)) - { - objsize = sizeof(rtl_cache_bufctl_type*); - } - - if (objalign == 0) - { - /* determine default alignment */ - if (objsize >= RTL_MEMORY_ALIGNMENT_8) - objalign = RTL_MEMORY_ALIGNMENT_8; - else - objalign = RTL_MEMORY_ALIGNMENT_4; - } - else - { - /* ensure minimum alignment */ - if(objalign < RTL_MEMORY_ALIGNMENT_4) - { - objalign = RTL_MEMORY_ALIGNMENT_4; - } - } - assert(RTL_MEMORY_ISP2(objalign)); - - cache->m_type_size = objsize = RTL_MEMORY_P2ROUNDUP(objsize, objalign); - cache->m_type_align = objalign; - cache->m_type_shift = highbit(cache->m_type_size) - 1; - cache->m_constructor = constructor; - cache->m_destructor = destructor; - cache->m_userarg = userarg; + snprintf (cache->m_name, sizeof(cache->m_name), "%s", name); - /* slab layer */ - cache->m_source = source; - - slabsize = source->m_quantum; /* minimum slab size */ - /* waste at most 1/8 of slab */ - if(slabsize < cache->m_type_size * 8) - { - slabsize = cache->m_type_size * 8; - } - - slabsize = RTL_MEMORY_P2ROUNDUP(slabsize, source->m_quantum); - if (!RTL_MEMORY_ISP2(slabsize)) - slabsize = ((sal_Size(1)) << highbit(slabsize)); - cache->m_slab_size = slabsize; - - if (cache->m_slab_size > source->m_quantum) - { - assert(gp_cache_slab_cache); - assert(gp_cache_bufctl_cache); - - cache->m_features |= RTL_CACHE_FEATURE_HASH; - cache->m_ntypes = cache->m_slab_size / cache->m_type_size; - cache->m_ncolor_max = cache->m_slab_size % cache->m_type_size; - } + if (objalign == 0) + { + /* determine default alignment */ + if (objsize >= RTL_MEMORY_ALIGNMENT_8) + objalign = RTL_MEMORY_ALIGNMENT_8; else - { - /* embedded slab struct */ - cache->m_ntypes = (cache->m_slab_size - sizeof(rtl_cache_slab_type)) / cache->m_type_size; - cache->m_ncolor_max = (cache->m_slab_size - sizeof(rtl_cache_slab_type)) % cache->m_type_size; - } - - assert(cache->m_ntypes > 0); - cache->m_ncolor = 0; - - if (flags & RTL_CACHE_FLAG_BULKDESTROY) - { - /* allow bulk slab delete upon cache deactivation */ - cache->m_features |= RTL_CACHE_FEATURE_BULKDESTROY; - } - - /* magazine layer */ - if (!(flags & RTL_CACHE_FLAG_NOMAGAZINE)) - { - assert(gp_cache_magazine_cache); - cache->m_magazine_cache = gp_cache_magazine_cache; - } - - /* insert into cache list */ - RTL_MEMORY_LOCK_ACQUIRE(&(g_cache_list.m_lock)); - QUEUE_INSERT_TAIL_NAMED(&(g_cache_list.m_cache_head), cache, cache_); - RTL_MEMORY_LOCK_RELEASE(&(g_cache_list.m_lock)); + objalign = RTL_MEMORY_ALIGNMENT_4; } - return cache; -} - -void rtl_cache_deactivate(rtl_cache_type * cache) -{ - /* remove from cache list */ - RTL_MEMORY_LOCK_ACQUIRE(&(g_cache_list.m_lock)); - bool active = !QUEUE_STARTED_NAMED(cache, cache_); - QUEUE_REMOVE_NAMED(cache, cache_); - RTL_MEMORY_LOCK_RELEASE(&(g_cache_list.m_lock)); - - assert(active); // orphaned cache - (void)active; - - /* cleanup magazine layer */ - if (cache->m_magazine_cache) + else { - rtl_cache_type * mag_cache; - rtl_cache_magazine_type * mag; - - /* prevent recursion */ - mag_cache = cache->m_magazine_cache; - cache->m_magazine_cache = nullptr; - - /* cleanup cpu layer */ - if ((mag = cache->m_cpu_curr)) - { - // coverity[missing_lock] - locking is fine - cache->m_cpu_curr = nullptr; - rtl_cache_magazine_clear (cache, mag); - rtl_cache_free (mag_cache, mag); - } - - if ((mag = cache->m_cpu_prev)) - { - // coverity[missing_lock] - locking is fine - cache->m_cpu_prev = nullptr; - rtl_cache_magazine_clear (cache, mag); - rtl_cache_free (mag_cache, mag); - } - - /* cleanup depot layer */ - while ((mag = rtl_cache_depot_dequeue(&(cache->m_depot_full)))) - { - rtl_cache_magazine_clear (cache, mag); - rtl_cache_free (mag_cache, mag); - } - - while ((mag = rtl_cache_depot_dequeue(&(cache->m_depot_empty)))) + /* ensure minimum alignment */ + if(objalign < RTL_MEMORY_ALIGNMENT_4) { - rtl_cache_magazine_clear (cache, mag); - rtl_cache_free (mag_cache, mag); + objalign = RTL_MEMORY_ALIGNMENT_4; } } + assert(RTL_MEMORY_ISP2(objalign)); - /* cleanup slab layer */ - if (cache->m_slab_stats.m_alloc > cache->m_slab_stats.m_free) - { - if (cache->m_features & RTL_CACHE_FEATURE_HASH) - { - /* cleanup bufctl(s) for leaking buffer(s) */ - sal_Size i, n = cache->m_hash_size; - for (i = 0; i < n; i++) - { - rtl_cache_bufctl_type * bufctl; - while ((bufctl = cache->m_hash_table[i])) - { - /* pop from hash table */ - cache->m_hash_table[i] = bufctl->m_next; - bufctl->m_next = nullptr; - - /* return to bufctl cache */ - rtl_cache_free (gp_cache_bufctl_cache, bufctl); - } - } - } - { - /* force cleanup of remaining slabs */ - rtl_cache_slab_type *head, *slab; - - head = &(cache->m_used_head); - for (slab = head->m_slab_next; slab != head; slab = head->m_slab_next) - { - /* remove from 'used' queue */ - QUEUE_REMOVE_NAMED(slab, slab_); - - /* update stats */ - cache->m_slab_stats.m_mem_total -= cache->m_slab_size; - - /* free slab */ - rtl_cache_slab_destroy (cache, slab); - } + cache->m_type_size = objsize = RTL_MEMORY_P2ROUNDUP(objsize, objalign); - head = &(cache->m_free_head); - for (slab = head->m_slab_next; slab != head; slab = head->m_slab_next) - { - /* remove from 'free' queue */ - QUEUE_REMOVE_NAMED(slab, slab_); + cache->m_constructor = constructor; + cache->m_destructor = destructor; + cache->m_userarg = userarg; - /* update stats */ - cache->m_slab_stats.m_mem_total -= cache->m_slab_size; - - /* free slab */ - rtl_cache_slab_destroy (cache, slab); - } - } - } - - if (cache->m_hash_table != cache->m_hash_table_0) - { - rtl_arena_free ( - gp_cache_arena, - cache->m_hash_table, - cache->m_hash_size * sizeof(rtl_cache_bufctl_type*)); - - cache->m_hash_table = cache->m_hash_table_0; - cache->m_hash_size = RTL_CACHE_HASH_SIZE; - cache->m_hash_shift = highbit(cache->m_hash_size) - 1; - } + return cache; } } //namespace @@ -667,8 +87,8 @@ rtl_cache_type * SAL_CALL rtl_cache_create( void (SAL_CALL * destructor) (void * obj, void * userarg), void (SAL_CALL * /*reclaim*/) (void * userarg), void * userarg, - rtl_arena_type * source, - int flags + rtl_arena_type *, + int ) SAL_THROW_EXTERN_C() { rtl_cache_type * result = nullptr; @@ -679,14 +99,7 @@ try_alloc: if (result) { rtl_cache_type * cache = result; - rtl_cache_constructor (cache); - - if (!source) - { - /* use default arena */ - assert(gp_default_arena); - source = gp_default_arena; - } + memset (cache, 0, sizeof(rtl_cache_type)); result = rtl_cache_activate ( cache, @@ -695,16 +108,12 @@ try_alloc: objalign, constructor, destructor, - userarg, - source, - flags + userarg ); if (!result) { /* activation failed */ - rtl_cache_deactivate (cache); - rtl_cache_destructor (cache); rtl_arena_free (gp_cache_arena, cache, size); } } @@ -724,8 +133,6 @@ void SAL_CALL rtl_cache_destroy(rtl_cache_type * cache) SAL_THROW_EXTERN_C() { if (cache) { - rtl_cache_deactivate (cache); - rtl_cache_destructor (cache); rtl_arena_free (gp_cache_arena, cache, sizeof(rtl_cache_type)); } } @@ -776,51 +183,6 @@ void SAL_CALL rtl_secureZeroMemory(void *Ptr, sal_Size Bytes) SAL_THROW_EXTERN_C *p++ = 0; } -static void * rtl_cache_wsupdate_all(void * arg); - -static void rtl_cache_wsupdate_init() -{ - RTL_MEMORY_LOCK_ACQUIRE(&(g_cache_list.m_lock)); - g_cache_list.m_update_done = 0; - (void) pthread_cond_init (&(g_cache_list.m_update_cond), nullptr); - if (pthread_create ( - &(g_cache_list.m_update_thread), nullptr, rtl_cache_wsupdate_all, reinterpret_cast<void*>(10)) != 0) - { - /* failure */ - g_cache_list.m_update_thread = pthread_t(); - } - RTL_MEMORY_LOCK_RELEASE(&(g_cache_list.m_lock)); -} - -static void rtl_cache_wsupdate_wait(unsigned int seconds) -{ - if (seconds > 0) - { - timeval now; - timespec wakeup; - - gettimeofday(&now, nullptr); - wakeup.tv_sec = now.tv_sec + seconds; - wakeup.tv_nsec = now.tv_usec * 1000; - - (void) pthread_cond_timedwait ( - &(g_cache_list.m_update_cond), - &(g_cache_list.m_lock), - &wakeup); - } -} - -static void rtl_cache_wsupdate_fini() -{ - RTL_MEMORY_LOCK_ACQUIRE(&(g_cache_list.m_lock)); - g_cache_list.m_update_done = 1; - pthread_cond_signal (&(g_cache_list.m_update_cond)); - RTL_MEMORY_LOCK_RELEASE(&(g_cache_list.m_lock)); - - if (g_cache_list.m_update_thread != pthread_t()) - pthread_join (g_cache_list.m_update_thread, nullptr); -} - #elif defined(_WIN32) void SAL_CALL rtl_secureZeroMemory(void *Ptr, sal_Size Bytes) SAL_THROW_EXTERN_C() @@ -828,273 +190,34 @@ void SAL_CALL rtl_secureZeroMemory(void *Ptr, sal_Size Bytes) SAL_THROW_EXTERN_C RtlSecureZeroMemory(Ptr, Bytes); } -static DWORD WINAPI rtl_cache_wsupdate_all(void * arg); - -static void rtl_cache_wsupdate_init() -{ - DWORD dwThreadId; - - RTL_MEMORY_LOCK_ACQUIRE(&(g_cache_list.m_lock)); - g_cache_list.m_update_done = 0; - g_cache_list.m_update_cond = CreateEventW (nullptr, TRUE, FALSE, nullptr); - - g_cache_list.m_update_thread = - CreateThread (nullptr, 0, rtl_cache_wsupdate_all, reinterpret_cast<LPVOID>(10), 0, &dwThreadId); - RTL_MEMORY_LOCK_RELEASE(&(g_cache_list.m_lock)); -} - -static void rtl_cache_wsupdate_wait(unsigned int seconds) -{ - if (seconds > 0) - { - RTL_MEMORY_LOCK_RELEASE(&(g_cache_list.m_lock)); - WaitForSingleObject (g_cache_list.m_update_cond, static_cast<DWORD>(seconds * 1000)); - RTL_MEMORY_LOCK_ACQUIRE(&(g_cache_list.m_lock)); - } -} - -static void rtl_cache_wsupdate_fini() -{ - RTL_MEMORY_LOCK_ACQUIRE(&(g_cache_list.m_lock)); - g_cache_list.m_update_done = 1; - SetEvent (g_cache_list.m_update_cond); - RTL_MEMORY_LOCK_RELEASE(&(g_cache_list.m_lock)); - - WaitForSingleObject (g_cache_list.m_update_thread, INFINITE); -} - #endif /* SAL_UNX || _WIN32 */ -/** - update depot stats and purge excess magazines. - - @precond cache->m_depot_lock acquired -*/ -static void rtl_cache_depot_wsupdate( - rtl_cache_type * cache, - rtl_cache_depot_type * depot -) -{ - sal_Size npurge; - - depot->m_prev_min = depot->m_curr_min; - depot->m_curr_min = depot->m_mag_count; - - npurge = std::min(depot->m_curr_min, depot->m_prev_min); - for (; npurge > 0; npurge--) - { - rtl_cache_magazine_type * mag = rtl_cache_depot_dequeue (depot); - if (mag) - { - RTL_MEMORY_LOCK_RELEASE(&(cache->m_depot_lock)); - rtl_cache_magazine_clear (cache, mag); - rtl_cache_free (cache->m_magazine_cache, mag); - RTL_MEMORY_LOCK_ACQUIRE(&(cache->m_depot_lock)); - } - } - // coverity[missing_unlock] - locking is fine -} - -/** - @precond cache->m_depot_lock released -*/ -static void rtl_cache_wsupdate(rtl_cache_type * cache) -{ - if (cache->m_magazine_cache) - { - RTL_MEMORY_LOCK_ACQUIRE(&(cache->m_depot_lock)); - - rtl_cache_depot_wsupdate (cache, &(cache->m_depot_full)); - rtl_cache_depot_wsupdate (cache, &(cache->m_depot_empty)); - - RTL_MEMORY_LOCK_RELEASE(&(cache->m_depot_lock)); - } -} - -#if defined(SAL_UNX) -static void * -#elif defined(_WIN32) -static DWORD WINAPI -#endif /* SAL_UNX || _WIN32 */ -rtl_cache_wsupdate_all(void * arg) -{ - osl::Thread::setName("rtl_cache_wsupdate_all"); - unsigned int seconds = sal::static_int_cast< unsigned int >( - reinterpret_cast< sal_uIntPtr >(arg)); - - RTL_MEMORY_LOCK_ACQUIRE(&(g_cache_list.m_lock)); - while (!g_cache_list.m_update_done) - { - rtl_cache_wsupdate_wait (seconds); - if (!g_cache_list.m_update_done) - { - rtl_cache_type * head, * cache; - - head = &(g_cache_list.m_cache_head); - for (cache = head->m_cache_next; - cache != head; - cache = cache->m_cache_next) - { - rtl_cache_wsupdate (cache); - } - } - } - RTL_MEMORY_LOCK_RELEASE(&(g_cache_list.m_lock)); - -#if defined(SAL_UNX) - return nullptr; -#elif defined(_WIN32) - return 0; -#endif -} - -void rtl_cache_stop_threads(void) -{ - rtl_cache_wsupdate_fini(); -} - -void rtl_cache_start_threads(void) -{ - rtl_cache_wsupdate_init(); -} - void rtl_cache_init() { - { - /* list of caches */ - RTL_MEMORY_LOCK_INIT(&(g_cache_list.m_lock)); - rtl_cache_constructor (&(g_cache_list.m_cache_head)); - } - { - /* cache: internal arena */ - assert(!gp_cache_arena); - - gp_cache_arena = rtl_arena_create ( - "rtl_cache_internal_arena", - 64, /* quantum */ - 0, /* no quantum caching */ - nullptr, /* default source */ - rtl_arena_alloc, - rtl_arena_free, - 0 /* flags */ - ); - assert(gp_cache_arena); - - /* check 'gp_default_arena' initialization */ - assert(gp_default_arena); - } - { - /* cache: magazine cache */ - static rtl_cache_type g_cache_magazine_cache; - - assert(!gp_cache_magazine_cache); - rtl_cache_constructor (&g_cache_magazine_cache); - - gp_cache_magazine_cache = rtl_cache_activate ( - &g_cache_magazine_cache, - "rtl_cache_magazine_cache", - sizeof(rtl_cache_magazine_type), /* objsize */ - 0, /* objalign */ - rtl_cache_magazine_constructor, - rtl_cache_magazine_destructor, - nullptr, /* userarg: NYI */ - gp_default_arena, /* source */ - RTL_CACHE_FLAG_NOMAGAZINE /* during bootstrap; activated below */ - ); - assert(gp_cache_magazine_cache); - - /* activate magazine layer */ - g_cache_magazine_cache.m_magazine_cache = gp_cache_magazine_cache; - } - { - /* cache: slab (struct) cache */ - static rtl_cache_type g_cache_slab_cache; - - assert(!gp_cache_slab_cache); - rtl_cache_constructor (&g_cache_slab_cache); - - gp_cache_slab_cache = rtl_cache_activate ( - &g_cache_slab_cache, - "rtl_cache_slab_cache", - sizeof(rtl_cache_slab_type), /* objsize */ - 0, /* objalign */ - rtl_cache_slab_constructor, - rtl_cache_slab_destructor, - nullptr, /* userarg: none */ - gp_default_arena, /* source */ - 0 /* flags: none */ - ); - assert(gp_cache_slab_cache); - } - { - /* cache: bufctl cache */ - static rtl_cache_type g_cache_bufctl_cache; - - assert(!gp_cache_bufctl_cache); - rtl_cache_constructor (&g_cache_bufctl_cache); + /* cache: internal arena */ + assert(!gp_cache_arena); - gp_cache_bufctl_cache = rtl_cache_activate ( - &g_cache_bufctl_cache, - "rtl_cache_bufctl_cache", - sizeof(rtl_cache_bufctl_type), /* objsize */ - 0, /* objalign */ - nullptr, /* constructor */ - nullptr, /* destructor */ - nullptr, /* userarg */ - gp_default_arena, /* source */ - 0 /* flags: none */ - ); - assert(gp_cache_bufctl_cache); - } + gp_cache_arena = rtl_arena_create ( + "rtl_cache_internal_arena", + 64, /* quantum */ + 0, /* no quantum caching */ + nullptr, /* default source */ + rtl_arena_alloc, + rtl_arena_free, + 0 /* flags */ + ); + assert(gp_cache_arena); - rtl_cache_wsupdate_init(); + /* check 'gp_default_arena' initialization */ + assert(gp_default_arena); } void rtl_cache_fini() { if (gp_cache_arena) { - rtl_cache_type * cache, * head; - - rtl_cache_wsupdate_fini(); - - if (gp_cache_bufctl_cache) - { - cache = gp_cache_bufctl_cache; - gp_cache_bufctl_cache = nullptr; - rtl_cache_deactivate (cache); - rtl_cache_destructor (cache); - } - - if (gp_cache_slab_cache) - { - cache = gp_cache_slab_cache; - gp_cache_slab_cache = nullptr; - rtl_cache_deactivate (cache); - rtl_cache_destructor (cache); - } - - if (gp_cache_magazine_cache) - { - cache = gp_cache_magazine_cache; - gp_cache_magazine_cache = nullptr; - rtl_cache_deactivate (cache); - rtl_cache_destructor (cache); - } - - if (gp_cache_arena) - { - rtl_arena_destroy (gp_cache_arena); - gp_cache_arena = nullptr; - } - - RTL_MEMORY_LOCK_ACQUIRE(&(g_cache_list.m_lock)); - head = &(g_cache_list.m_cache_head); - for (cache = head->m_cache_next; cache != head; cache = cache->m_cache_next) - { - // noop - } - RTL_MEMORY_LOCK_RELEASE(&(g_cache_list.m_lock)); + rtl_arena_destroy (gp_cache_arena); + gp_cache_arena = nullptr; } } diff --git a/sal/rtl/alloc_cache.hxx b/sal/rtl/alloc_cache.hxx index 3e467ade3cd2..501d5770b3c6 100644 --- a/sal/rtl/alloc_cache.hxx +++ b/sal/rtl/alloc_cache.hxx @@ -22,133 +22,17 @@ #include <sal/types.h> #include <rtl/alloc.h> -#include "alloc_impl.hxx" - -/** - @internal -*/ -struct rtl_cache_stat_type -{ - sal_uInt64 m_alloc; - sal_uInt64 m_free; - - sal_Size m_mem_total; - sal_Size m_mem_alloc; -}; - -/** - @internal -*/ -struct rtl_cache_bufctl_type -{ - rtl_cache_bufctl_type * m_next; /* linkage */ - - sal_uIntPtr m_addr; /* buffer address */ - sal_uIntPtr m_slab; /* parent slab address */ -}; - -/** - @internal -*/ -struct rtl_cache_slab_type -{ - rtl_cache_slab_type * m_slab_next; /* slab linkage */ - rtl_cache_slab_type * m_slab_prev; /* slab linkage */ - - sal_Size m_ntypes; /* number of buffers used */ - sal_uIntPtr m_data; /* buffer start addr */ - - sal_uIntPtr m_bp; /* free buffer linkage 'base pointer' */ - rtl_cache_bufctl_type * m_sp; /* free buffer linkage 'stack pointer' */ -}; - -/** - @internal -*/ -#define RTL_CACHE_MAGAZINE_SIZE 61 - -struct rtl_cache_magazine_type -{ - rtl_cache_magazine_type * m_mag_next; /* depot linkage */ - - sal_Size m_mag_size; - sal_Size m_mag_used; - - void * m_objects[RTL_CACHE_MAGAZINE_SIZE]; -}; - -/** - @internal -*/ -struct rtl_cache_depot_type -{ - /* magazine list */ - rtl_cache_magazine_type * m_mag_next; /* linkage */ - sal_Size m_mag_count; /* count */ - - /* working set parameters */ - sal_Size m_curr_min; - sal_Size m_prev_min; -}; - -/** - @internal -*/ -#define RTL_CACHE_HASH_SIZE 8 - -#define RTL_CACHE_FEATURE_HASH 1 -#define RTL_CACHE_FEATURE_BULKDESTROY 2 -#define RTL_CACHE_FEATURE_RESCALE 4 /* within hash rescale operation */ struct rtl_cache_st { - /* linkage */ - rtl_cache_type * m_cache_next; - rtl_cache_type * m_cache_prev; - /* properties */ char m_name[RTL_CACHE_NAME_LENGTH + 1]; - long m_features; sal_Size m_type_size; /* const */ - sal_Size m_type_align; /* const */ - sal_Size m_type_shift; /* log2(m_type_size); const */ int (SAL_CALL * m_constructor)(void * obj, void * userarg); /* const */ void (SAL_CALL * m_destructor) (void * obj, void * userarg); /* const */ void * m_userarg; - - /* slab layer */ - rtl_memory_lock_type m_slab_lock; - rtl_cache_stat_type m_slab_stats; - - rtl_arena_type * m_source; /* slab supplier; const */ - sal_Size m_slab_size; /* const */ - sal_Size m_ntypes; /* number of buffers per slab; const */ - sal_Size m_ncolor; /* next slab color */ - sal_Size m_ncolor_max; /* max. slab color */ - - rtl_cache_slab_type m_free_head; - rtl_cache_slab_type m_used_head; - - rtl_cache_bufctl_type ** m_hash_table; - rtl_cache_bufctl_type * m_hash_table_0[RTL_CACHE_HASH_SIZE]; - sal_Size m_hash_size; /* m_hash_mask + 1 */ - sal_Size m_hash_shift; /* log2(m_hash_size) */ - - /* depot layer */ - rtl_memory_lock_type m_depot_lock; - - rtl_cache_depot_type m_depot_empty; - rtl_cache_depot_type m_depot_full; - - rtl_cache_type * m_magazine_cache; /* magazine supplier; const */ - - /* cpu layer */ - rtl_cache_magazine_type * m_cpu_curr; - rtl_cache_magazine_type * m_cpu_prev; - - rtl_cache_stat_type m_cpu_stats; }; #endif // INCLUDED_SAL_RTL_ALLOC_CACHE_HXX diff --git a/sal/rtl/strimp.cxx b/sal/rtl/strimp.cxx index c590fbcc4d52..e356a4e921a6 100644 --- a/sal/rtl/strimp.cxx +++ b/sal/rtl/strimp.cxx @@ -118,19 +118,11 @@ void SAL_CALL rtl_alloc_preInit (rtl_alloc_preInit_phase_t phase) SAL_THROW_EXTE rtl_allocateString = rtl_allocateMemory; rtl_freeString = rtl_freeMemory; - // Stop the rtl cache thread to have no extra threads while forking. - rtl_cache_stop_threads(); - // TODO: also re-initialize main allocator as well. } break; - case rtlAllocPostInit: - { - // We have forked and need to restart threads and anything - // that must start after forking. - rtl_cache_start_threads(); - } + case rtlAllocPostInit: // no longer used break; } } |