From f5fa33611ff8159c6855460a9fd41b3a5faa2d04 Mon Sep 17 00:00:00 2001 From: YuQing <384681@qq.com> Date: Fri, 10 Sep 2021 16:36:14 +0800 Subject: [PATCH] add files: array_allocator.[hc] --- HISTORY | 3 +- src/Makefile.in | 6 ++-- src/array_allocator.c | 73 ++++++++++++++++++++++++++++++++++++++ src/array_allocator.h | 82 +++++++++++++++++++++++++++++++++++++++++++ src/sorted_queue.h | 15 ++++++++ 5 files changed, 175 insertions(+), 4 deletions(-) create mode 100644 src/array_allocator.c create mode 100644 src/array_allocator.h diff --git a/HISTORY b/HISTORY index fd1d280..ccf2fdb 100644 --- a/HISTORY +++ b/HISTORY @@ -1,10 +1,11 @@ -Version 1.54 2021-09-09 +Version 1.54 2021-09-10 * fast_allocator.[hc]: correct reclaim_interval logic * shared_func.[hc]: add functions getFileContentEx1 and getFileContent1 * fc_queue.[hc]: add function fc_queue_timedpeek * pthread_func.[hc]: add function init_pthread_rwlock * add files: sorted_queue.[hc] + * add files: array_allocator.[hc] Version 1.53 2021-06-30 * process_action support action status diff --git a/src/Makefile.in b/src/Makefile.in index b651b44..0565c30 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -17,7 +17,7 @@ FAST_SHARED_OBJS = hash.lo chain.lo shared_func.lo ini_file_reader.lo \ multi_socket_client.lo skiplist_set.lo uniq_skiplist.lo \ json_parser.lo buffered_file_writer.lo server_id_func.lo \ fc_queue.lo sorted_queue.lo fc_memory.lo shared_buffer.lo \ - thread_pool.lo + thread_pool.lo array_allocator.lo FAST_STATIC_OBJS = hash.o chain.o shared_func.o ini_file_reader.o \ logger.o sockopt.o base64.o sched_thread.o \ @@ -31,7 +31,7 @@ FAST_STATIC_OBJS = hash.o chain.o shared_func.o ini_file_reader.o \ multi_socket_client.o skiplist_set.o uniq_skiplist.o \ json_parser.o buffered_file_writer.o server_id_func.o \ fc_queue.o sorted_queue.o fc_memory.o shared_buffer.o \ - thread_pool.o + thread_pool.o array_allocator.o HEADER_FILES = common_define.h hash.h chain.h logger.h base64.h \ shared_func.h pthread_func.h ini_file_reader.h _os_define.h \ @@ -46,7 +46,7 @@ HEADER_FILES = common_define.h hash.h chain.h logger.h base64.h \ multi_socket_client.h skiplist_set.h uniq_skiplist.h \ fc_list.h locked_list.h json_parser.h buffered_file_writer.h \ server_id_func.h fc_queue.h sorted_queue.h fc_memory.h \ - shared_buffer.h thread_pool.h fc_atomic.h + shared_buffer.h thread_pool.h fc_atomic.h array_allocator.h ALL_OBJS = $(FAST_STATIC_OBJS) $(FAST_SHARED_OBJS) diff --git a/src/array_allocator.c b/src/array_allocator.c new file mode 100644 index 0000000..57dc2b7 --- /dev/null +++ b/src/array_allocator.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020 YuQing <384681@qq.com> + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * 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. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "shared_func.h" +#include "array_allocator.h" + +int array_allocator_init(ArrayAllocatorContext *ctx, + const char *name_prefix, const int element_size, + const int min_bits, const int max_bits) +{ + const int reclaim_interval = 0; + char name[32]; + struct fast_region_info regions[32]; + struct fast_region_info *region; + int bit; + int start; + int end; + int alloc_elements_once; + int step; + + ctx->element_size = element_size; + ctx->min_count = (1 << min_bits); + start = 0; + alloc_elements_once = (1 << (max_bits - min_bits + 2)); + for (bit=min_bits, region=regions; + bit<=max_bits; bit++, region++) + { + end = sizeof(VoidArray) + (1 << bit) * ctx->element_size; + step = end - start; + FAST_ALLOCATOR_INIT_REGION(*region, start, + end, step, alloc_elements_once); + alloc_elements_once /= 2; + start = end; + } + + snprintf(name, sizeof(name), "%s-array", name_prefix); + return fast_allocator_init_ex(&ctx->allocator, + name, regions, region - regions, 0, + 0.9999, reclaim_interval, true); +} + +VoidArray *array_allocator_alloc(ArrayAllocatorContext *ctx, + const int target_count) +{ + int alloc; + int bytes; + + if (target_count <= ctx->min_count) { + alloc = ctx->min_count; + } else if (is_power2(target_count)) { + alloc = target_count; + } else { + alloc = ctx->min_count; + while (alloc < target_count) { + alloc *= 2; + } + } + + bytes = sizeof(VoidArray) + alloc * ctx->element_size; + return (VoidArray *)fast_allocator_alloc(&ctx->allocator, bytes); +} diff --git a/src/array_allocator.h b/src/array_allocator.h new file mode 100644 index 0000000..cc4946a --- /dev/null +++ b/src/array_allocator.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2020 YuQing <384681@qq.com> + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * 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. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef ARRAY_ALLOCATOR_H +#define ARRAY_ALLOCATOR_H + +#include "fast_allocator.h" + +typedef struct +{ + int alloc; + int count; + char elts[0]; +} VoidArray; + +typedef struct +{ + int alloc; + int count; + int64_t elts[0]; +} I64Array; + +typedef struct +{ + int alloc; + int count; + int32_t elts[0]; +} I32Array; + +typedef struct +{ + struct fast_allocator_context allocator; + int element_size; + int min_count; +} ArrayAllocatorContext; + +#ifdef __cplusplus +extern "C" { +#endif + + int array_allocator_init(ArrayAllocatorContext *ctx, + const char *name_prefix, const int element_size, + const int min_bits, const int max_bits); + + VoidArray *array_allocator_alloc(ArrayAllocatorContext *ctx, + const int target_count); + + static inline void array_allocator_free(ArrayAllocatorContext *ctx, + VoidArray *array) + { + array->count = 0; + fast_allocator_free(&ctx->allocator, array); + } + + +#define i64_array_allocator_init(ctx, min_bits, max_bits) \ + array_allocator_init(ctx, "i64", sizeof(int64_t), min_bits, max_bits) + +#define i64_array_allocator_alloc(ctx, target_count) \ + (I64Array *)array_allocator_alloc(ctx, target_count) + +#define i64_array_allocator_free(ctx, array) \ + array_allocator_free(ctx, (VoidArray *)array) + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sorted_queue.h b/src/sorted_queue.h index 5f997dc..f9e1e88 100644 --- a/src/sorted_queue.h +++ b/src/sorted_queue.h @@ -89,6 +89,21 @@ static inline bool sorted_queue_empty(struct sorted_queue *sq) return fc_queue_empty(&sq->queue); } +static inline void *sorted_queue_timedpeek(struct sorted_queue *sq, + const int timeout, const int time_unit) +{ + return fc_queue_timedpeek(&sq->queue, timeout, time_unit); +} + +#define sorted_queue_timedpeek_sec(sq, timeout) \ + sorted_queue_timedpeek(sq, timeout, FC_TIME_UNIT_SECOND) + +#define sorted_queue_timedpeek_ms(sq, timeout_ms) \ + sorted_queue_timedpeek(sq, timeout_ms, FC_TIME_UNIT_MSECOND) + +#define sorted_queue_timedpeek_us(sq, timeout_us) \ + sorted_queue_timedpeek(sq, timeout_us, FC_TIME_UNIT_USECOND) + #ifdef __cplusplus } #endif