Source
xxxxxxxxxx
zabbix_log(LOG_LEVEL_DEBUG, "In %s() param:'%s' size:" ZBX_FS_SIZE_T, __func__, param, (zbx_fs_size_t)size);
/*
** Copyright (C) 2001-2025 Zabbix SIA
**
** This program is free software: you can redistribute it and/or modify it under the terms of
** the GNU Affero General Public License as published by the Free Software Foundation, version 3.
**
** 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 Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License along with this program.
** If not, see <https://www.gnu.org/licenses/>.
**/
/******************************************************************************
* *
* Some information on memory layout *
* --------------------------------------- *
* *
* (*) chunk: a contiguous piece of memory that is either free or used *
* *
* +-------- size of + --------------+ *
* | (8 bytes) | | *
* | v | *
* | | *
* | +- allocatable memory --+ | *
* | | (user data goes here) | | *
* v v v v *
* *
* |--------|----------------...----|--------| *
* *
* ^ ^ ^ ^ *
* 8-aligned | | 8-aligned *
* *
* 8-aligned 8-aligned *
* *
* when a chunk is used, `size' fields have SHMEM_FLG_USED bit set *
* *
* when a chunk is free, the first 2 * ZBX_PTR_SIZE bytes of allocatable *
* memory contain pointers to the previous and next chunks, in that order *
* *
* notes: *
* *
* - user data is nicely 8-aligned *
* *
* - size is kept on both left and right ends for quick merging *
* (when freeing a chunk, we can quickly see if the previous *
* and next chunks are free, those will not have SHMEM_FLG_USED) *
* *
* (*) free chunks are stored in doubly-linked lists according to their sizes *
* *
* a typical situation is thus as follows (1 used chunk, 2 free chunks) *
* *
* +--------------------------- shared memory ----------------------------+ *
* | (can be misaligned) | *
* | | *
* | | *
* | +------ chunk A ------+------ chunk B -----+------ chunk C ------+ | *
* | | (free) | (used) | (free) | | *
* | | | | | | *
* v v v v v v *
* prevnext user data prevnext *
* #--|----|--------...|----|----|---....---|----|----|--------...|----|--# *
* NULL | | NULL *
* ^ | ^ | ^ *
* | | | | | *
* | +------------------------------+ | | *
* | | | *
* +-------------------------------------------------+ | *
* | | *
* *
* lo_bound `size' fields in chunk B hi_bound *
* (aligned) have SHMEM_FLG_USED bit set (aligned) *
* *
******************************************************************************/
static void *ALIGN4(void *ptr);
static void *ALIGN8(void *ptr);
static void *ALIGNPTR(void *ptr);
static zbx_uint64_t mem_proper_alloc_size(zbx_uint64_t size);
static int mem_bucket_by_size(zbx_uint64_t size);
static void mem_set_chunk_size(void *chunk, zbx_uint64_t size);
static void mem_set_used_chunk_size(void *chunk, zbx_uint64_t size);
static void *mem_get_prev_chunk(void *chunk);