From 88b9dc3632ba5bed39d70494321d76720c6db82d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?shuxin=20=E3=80=80=E3=80=80zheng?= Date: Thu, 12 Sep 2024 11:48:12 +0800 Subject: [PATCH] Add align bytes set when creating dbuf; 16 bytes align for redis module. --- lib_acl/include/stdlib/acl_dbuf_pool.h | 8 ++ lib_acl/samples/coder/main.c | 4 + lib_acl/src/stdlib/memory/acl_dbuf_pool.c | 10 +- .../include/acl_cpp/stdlib/dbuf_pool.hpp | 127 +++++++----------- lib_acl_cpp/src/http/http_mime.cpp | 10 +- lib_acl_cpp/src/redis/redis_client.cpp | 10 +- lib_acl_cpp/src/redis/redis_command.cpp | 4 +- lib_acl_cpp/src/stdlib/dbuf_pool.cpp | 25 ++-- 8 files changed, 91 insertions(+), 107 deletions(-) diff --git a/lib_acl/include/stdlib/acl_dbuf_pool.h b/lib_acl/include/stdlib/acl_dbuf_pool.h index aafcaeeac..6633c3405 100644 --- a/lib_acl/include/stdlib/acl_dbuf_pool.h +++ b/lib_acl/include/stdlib/acl_dbuf_pool.h @@ -14,6 +14,14 @@ typedef struct ACL_DBUF_POOL ACL_DBUF_POOL; */ ACL_API ACL_DBUF_POOL *acl_dbuf_pool_create(size_t block_size); +/** + * 创建内存池对象 + * @param block_size {size_t} 内存池中每个连续内存块的大小(字节) + * @param align {size_t} 分配内存时的字节对齐个数 + * @return {ACL_DBUF_POOL*} 返回非 NULL 对象 + */ +ACL_API ACL_DBUF_POOL *acl_dbuf_pool_create2(size_t block_size, size_t align); + /** * 重置内存池状态,会将多余的内存数据块释放 * @param pool {ACL_DBUF_POOL*} 内存池对象 diff --git a/lib_acl/samples/coder/main.c b/lib_acl/samples/coder/main.c index e806bb0e6..8b7981fc8 100644 --- a/lib_acl/samples/coder/main.c +++ b/lib_acl/samples/coder/main.c @@ -75,6 +75,8 @@ static void crc32_encode(const char *ptr, size_t len) static char *load_from(const char *filename) { char *data = acl_vstream_loadfile(filename); + return data; + /* char *ptr = strchr(data, '\r'); if (ptr == NULL) { ptr = strchr(data, '\n'); @@ -83,6 +85,7 @@ static char *load_from(const char *filename) *ptr = 0; } return data; + */ } static void usage(const char *prog) @@ -117,6 +120,7 @@ int main(int argc, char *argv[]) break; case 'f': buf = load_from(optarg); + printf("buf=%s\n", buf); break; case 'a': if (strcasecmp(optarg, "decode") == 0) { diff --git a/lib_acl/src/stdlib/memory/acl_dbuf_pool.c b/lib_acl/src/stdlib/memory/acl_dbuf_pool.c index 48df444ee..d1e3a0597 100644 --- a/lib_acl/src/stdlib/memory/acl_dbuf_pool.c +++ b/lib_acl/src/stdlib/memory/acl_dbuf_pool.c @@ -26,6 +26,7 @@ typedef struct ACL_DBUF { struct ACL_DBUF_POOL { size_t block_size; + size_t align; size_t off; size_t huge; size_t count; @@ -34,6 +35,11 @@ struct ACL_DBUF_POOL { }; ACL_DBUF_POOL *acl_dbuf_pool_create(size_t block_size) +{ + return acl_dbuf_pool_create2(block_size, sizeof(void*)); +} + +ACL_DBUF_POOL *acl_dbuf_pool_create2(size_t block_size, size_t align) { ACL_DBUF_POOL *pool; size_t size; @@ -75,6 +81,7 @@ ACL_DBUF_POOL *acl_dbuf_pool_create(size_t block_size) #endif pool->block_size = size; + pool->align = align + align % 2; /* 需保证对齐字节为偶数 */ pool->off = 0; pool->huge = 0; pool->head = (ACL_DBUF*) pool->buf; @@ -258,7 +265,8 @@ void *acl_dbuf_pool_alloc(ACL_DBUF_POOL *pool, size_t length) void *ptr; ACL_DBUF *dbuf; - length += sizeof(size_t) - length % sizeof(size_t); + /* 保证长度是按指定字节对齐的 */ + length += pool->align - length % pool->align; if (length > pool->block_size) { dbuf = acl_dbuf_alloc(pool, length); diff --git a/lib_acl_cpp/include/acl_cpp/stdlib/dbuf_pool.hpp b/lib_acl_cpp/include/acl_cpp/stdlib/dbuf_pool.hpp index ba079545e..3d5f85770 100644 --- a/lib_acl_cpp/include/acl_cpp/stdlib/dbuf_pool.hpp +++ b/lib_acl_cpp/include/acl_cpp/stdlib/dbuf_pool.hpp @@ -23,8 +23,10 @@ class ACL_CPP_API dbuf_pool { // : public noncopyable public: /** * 该类对象必须动态创建 + * @param nblock {size_t} 4096字节的个数 + * @param align {size_t} 分配内存时的字节对齐数 */ - dbuf_pool(size_t nblock = 2); + dbuf_pool(size_t nblock = 2, size_t align = 8); /** * 该类对象必须要动态创建,所以隐藏了析构函数,使用者需要调用 destroy @@ -119,8 +121,7 @@ public: * 获得内部 ACL_DBUF_POOL 对象,以便于操作 C 接口的内存池对象 * @return {ACL_DBUF_POOL*} */ - ACL_DBUF_POOL *get_dbuf() - { + ACL_DBUF_POOL *get_dbuf() const { return pool_; } @@ -134,11 +135,9 @@ public: /** * sample: - * void test() - * { + * void test() { * acl::dbuf_pool* dbuf = new acl::dbuf_pool; - * for (int i = 0; i < 1000; i++) - * { + * for (int i = 0; i < 1000; i++) { * char* ptr = dbuf->dbuf_strdup("hello world!"); * printf("%s\r\n", p); * } @@ -146,8 +145,7 @@ public: * * // 创建 dbuf 对象时,指定了内部分配内存块的位数 * dbuf = new(8) acl::dbuf_pool; - * for (int i = 0; i < 1000; i++) - * { + * for (int i = 0; i < 1000; i++) { * ptr = dbuf->dbuf_strdup("hello world!"); * printf("%s\r\n", p); * } @@ -181,8 +179,7 @@ public: * @return {int} 返回该对象在 dbuf_guard 中的数组中的下标位置,当该 * 对象没有被 dbuf_guard 保存时,则返回 -1,此时有可能会造成内存泄露 */ - int pos() const - { + int pos() const { return pos_; } @@ -190,8 +187,7 @@ public: * 返回构造函数中 dbuf_guard 对象 * @return {dbuf_guard*} */ - dbuf_guard* get_guard() const - { + dbuf_guard* get_guard() const { return guard_; } @@ -227,8 +223,9 @@ public: * @param nblock {size_t} 本类对象内部创建 dbuf_pool 对象时,本参数 * 指定了内存块(4096)的倍数 * @param capacity {size_t} 内部创建的 objs_ 数组的初始长度 + * @param align {size_t} 分配内存时地址对齐字节个数 */ - dbuf_guard(size_t nblock = 2, size_t capacity = 500); + dbuf_guard(size_t nblock = 2, size_t capacity = 500, size_t align = 8); /** * 析构函数,在析构函数内部将会自动销毁由构造函数传入的 dbuf_pool 对象 @@ -247,8 +244,7 @@ public: * @param len {size_t} * @return {void*} */ - void* dbuf_alloc(size_t len) - { + void* dbuf_alloc(size_t len) { return dbuf_->dbuf_alloc(len); } @@ -257,8 +253,7 @@ public: * @param len {size_t} * @return {void*} */ - void* dbuf_calloc(size_t len) - { + void* dbuf_calloc(size_t len) { return dbuf_->dbuf_calloc(len); } @@ -267,8 +262,7 @@ public: * @param s {const char*} * @return {char*} */ - char* dbuf_strdup(const char* s) - { + char* dbuf_strdup(const char* s) { return dbuf_->dbuf_strdup(s); } @@ -278,8 +272,7 @@ public: * @param len {size_t} * @return {char*} */ - char* dbuf_strndup(const char* s, size_t len) - { + char* dbuf_strndup(const char* s, size_t len) { return dbuf_->dbuf_strndup(s, len); } @@ -289,8 +282,7 @@ public: * @param len {size_t} * @return {void*} */ - void* dbuf_memdup(const void* addr, size_t len) - { + void* dbuf_memdup(const void* addr, size_t len) { return dbuf_->dbuf_memdup(addr, len); } @@ -299,8 +291,7 @@ public: * @param addr {const void*} * @return {bool} */ - bool dbuf_free(const void* addr) - { + bool dbuf_free(const void* addr) { return dbuf_->dbuf_free(addr); } @@ -309,8 +300,7 @@ public: * @param addr {const void*} * @return {bool} */ - bool dbuf_keep(const void* addr) - { + bool dbuf_keep(const void* addr) { return dbuf_->dbuf_keep(addr); } @@ -319,8 +309,7 @@ public: * @param addr {const void*} * @return {bool} */ - bool dbuf_unkeep(const void* addr) - { + bool dbuf_unkeep(const void* addr) { return dbuf_->dbuf_unkeep(addr); } @@ -328,8 +317,7 @@ public: * 获得 dbuf_pool 对象 * @return {acl::dbuf_pool&} */ - acl::dbuf_pool& get_dbuf() const - { + acl::dbuf_pool& get_dbuf() const { return *dbuf_; } @@ -348,8 +336,7 @@ public: * 获得当前内存池中管理的对象数量 * @return {size_t} */ - size_t size() const - { + size_t size() const { return size_; } @@ -375,32 +362,28 @@ public: public: template - T* create() - { + T* create() { T* t = new (dbuf_alloc(sizeof(T))) T(); (void) push_back(t); return t; } template - T* create(P1 p) - { + T* create(P1 p) { T* t = new (dbuf_alloc(sizeof(T))) T(p); (void) push_back(t); return t; } template - T* create(P1 p1, P2 p2) - { + T* create(P1 p1, P2 p2) { T* t = new (dbuf_alloc(sizeof(T))) T(p1, p2); (void) push_back(t); return t; } template - T* create(P1 p1, P2 p2, P3 p3) - { + T* create(P1 p1, P2 p2, P3 p3) { T* t = new (dbuf_alloc(sizeof(T))) T(p1, p2, p3); (void) push_back(t); return t; @@ -408,8 +391,7 @@ public: template - T* create(P1 p1, P2 p2, P3 p3, P4 p4) - { + T* create(P1 p1, P2 p2, P3 p3, P4 p4) { T* t = new (dbuf_alloc(sizeof(T))) T(p1, p2, p3, p4); (void) push_back(t); return t; @@ -417,8 +399,7 @@ public: template - T* create(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) - { + T* create(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) { T* t = new (dbuf_alloc(sizeof(T))) T(p1, p2, p3, p4, p5); (void) push_back(t); return t; @@ -426,8 +407,7 @@ public: template - T* create(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) - { + T* create(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) { T* t = new (dbuf_alloc(sizeof(T))) T(p1, p2, p3, p4, p5, p6); (void) push_back(t); return t; @@ -435,8 +415,7 @@ public: template - T* create(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) - { + T* create(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) { T* t = new (dbuf_alloc(sizeof(T))) T(p1, p2, p3, p4, p5, p6, p7); (void) push_back(t); @@ -446,8 +425,7 @@ public: template - T* create(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) - { + T* create(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) { T* t = new (dbuf_alloc(sizeof(T))) T(p1, p2, p3, p4, p5, p6, p7, p8); (void) push_back(t); @@ -458,8 +436,7 @@ public: typename P4, typename P5, typename P6, typename P7, typename P8,typename P9> T* create(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, - P8 p8, P9 p9) - { + P8 p8, P9 p9) { T* t = new (dbuf_alloc(sizeof(T))) T(p1, p2, p3, p4, p5, p6, p7, p8, p9); (void) push_back(t); @@ -470,8 +447,7 @@ public: typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10> T* create(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, - P8 p8, P9 p9, P10 p10) - { + P8 p8, P9 p9, P10 p10) { T* t = new (dbuf_alloc(sizeof(T))) T(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); (void) push_back(t); @@ -489,8 +465,7 @@ private: // 一方面使数组对象也在 dbuf_pool 内存池上创建,另一方面可以避免 // std::vector 内部在扩容时的内存不可控性 - struct dbuf_objs_link - { + struct dbuf_objs_link { dbuf_obj** objs; // 存储 dbuf_obj 对象的数组对象 size_t size; // 存储于 objs 中的对象个数 size_t capacity; // objs 数组的大小 @@ -511,14 +486,12 @@ private: /** * sample1: * // 继承 acl::dbuf_obj 的子类 - * class myobj1 : public acl::dbuf_obj - * { + * class myobj1 : public acl::dbuf_obj { * public: * // 将 guard 对象传递给基类对象,基类将本对象加入 guard 的对象集合中 * myobj1(acl::dbuf_guard* guard) : dbuf_obj(guard) {} * - * void doit() - * { + * void doit() { * printf("hello world!\r\n"); * } * @@ -526,13 +499,11 @@ private: * ~myobj1() {} * }; * - * void test() - * { + * void test() { * acl::dbuf_guard dbuf; * * // 在 dbuf_guard 对象上创建动态 100 个 myobj 对象 - * for (int i = 0; i < 100; i++) - * { + * for (int i = 0; i < 100; i++) { * // 在 guard 对象上创建动态 myobj 对象,且将 guard 作为构造参数 * myobj* obj = new (dbuf.dbuf_alloc(sizeof(myobj))) myobj(&dbuf); * obj->doit(); @@ -542,13 +513,11 @@ private: * } * * // sample2 - * class myobj2 : public acl::dbuf_obj - * { + * class myobj2 : public acl::dbuf_obj { * public: * myobj2() {} * - * void doit() - * { + * void doit() { * printf("hello world\r\n"); * } * @@ -556,25 +525,21 @@ private: * ~myobj2() {} * }; * - * void test2() - * { + * void test2() { * acl::dbuf_guard dbuf; * - * for (int i = 0; i < 100; i++) - * { + * for (int i = 0; i < 100; i++) { * myobj2* obj = dbuf.create(); * obj->doit(); * } * } * * // sample3 - * class myobj2 : public acl::dbuf_obj - * { + * class myobj2 : public acl::dbuf_obj { * public: * myobj2(int i) : i_(i) {} * - * void doit() - * { + * void doit() { * printf("hello world, i: %d\r\n", i_); * } * @@ -585,12 +550,10 @@ private: * int i_; * }; * - * void test2() - * { + * void test2() { * acl::dbuf_guard dbuf; * - * for (int i = 0; i < 100; i++) - * { + * for (int i = 0; i < 100; i++) { * myobj2* obj = dbuf.create(i); * obj->doit(); * } diff --git a/lib_acl_cpp/src/http/http_mime.cpp b/lib_acl_cpp/src/http/http_mime.cpp index 6eb3a30b1..15c1e387e 100644 --- a/lib_acl_cpp/src/http/http_mime.cpp +++ b/lib_acl_cpp/src/http/http_mime.cpp @@ -13,8 +13,7 @@ #if !defined(ACL_MIME_DISABLE) -namespace acl -{ +namespace acl { ////////////////////////////////////////////////////////////////////////// @@ -108,7 +107,7 @@ void http_mime_node::load_param(const char* path) const char* fromCharset = get_charset(); const char* toCharset = get_toCharset(); if (fromCharset && *fromCharset && toCharset && *toCharset - && strcasecmp(fromCharset, toCharset)) { + && strcasecmp(fromCharset, toCharset) != 0) { charset_conv conv; string tmp; @@ -201,11 +200,10 @@ void http_mime::set_saved_path(const char* path) bool http_mime::update(const char* data, size_t len) { - return mime_state_update(mime_state_, data, (int) len) == 1 - ? true : false; + return mime_state_update(mime_state_, data, (int) len) == 1; } -const std::list& http_mime::get_nodes(void) const +const std::list& http_mime::get_nodes() const { if (parsed_) { return mime_nodes_; diff --git a/lib_acl_cpp/src/redis/redis_client.cpp b/lib_acl_cpp/src/redis/redis_client.cpp index 8bf3afae3..faea72a76 100644 --- a/lib_acl_cpp/src/redis/redis_client.cpp +++ b/lib_acl_cpp/src/redis/redis_client.cpp @@ -473,12 +473,13 @@ const redis_result* redis_client::run(dbuf_pool* dbuf, const redis_request& req, size_t size = req.get_size(); while (true) { - if (! open()) { + if (!open()) { return NULL; } - if (rw_timeout != NULL) + if (rw_timeout != NULL) { conn_.set_rw_timeout(*rw_timeout); + } if (check_addr_ && !check_connection(conn_)) { logger_error("CHECK_CONNECTION FAILED!"); @@ -499,10 +500,11 @@ const redis_result* redis_client::run(dbuf_pool* dbuf, const redis_request& req, return NULL; } - if (nchildren >= 1) + if (nchildren >= 1) { result = get_objects(conn_, dbuf, nchildren); - else + } else { result = get_object(conn_, dbuf); + } if (result != NULL) { if (rw_timeout != NULL) { diff --git a/lib_acl_cpp/src/redis/redis_command.cpp b/lib_acl_cpp/src/redis/redis_command.cpp index f37b0d0b9..605aa712c 100644 --- a/lib_acl_cpp/src/redis/redis_command.cpp +++ b/lib_acl_cpp/src/redis/redis_command.cpp @@ -44,7 +44,9 @@ void redis_command::init() #ifdef ACL_DBUF_HOOK_NEW dbuf_ = new (REDIS_DBUF_NBLOCK) dbuf_pool(); #else - dbuf_ = new dbuf_pool(REDIS_DBUF_NBLOCK); + // 因为 gcc 编译器在启用 O3 优化时,有可能在地址赋值时会因使用 MOVDQA, + // 而该指令是按 16 字节对齐的 + dbuf_ = new dbuf_pool(REDIS_DBUF_NBLOCK, 16); #endif } diff --git a/lib_acl_cpp/src/stdlib/dbuf_pool.cpp b/lib_acl_cpp/src/stdlib/dbuf_pool.cpp index dd925fcd2..388e47fb3 100644 --- a/lib_acl_cpp/src/stdlib/dbuf_pool.cpp +++ b/lib_acl_cpp/src/stdlib/dbuf_pool.cpp @@ -4,27 +4,26 @@ #include "acl_cpp/stdlib/dbuf_pool.hpp" #endif -namespace acl -{ +namespace acl { -dbuf_pool::dbuf_pool(size_t nblock /* = 2 */) +dbuf_pool::dbuf_pool(size_t nblock /* = 2 */, size_t align /* = 8 */) { #ifdef ACL_DBUF_HOOK_NEW (void) nblock; #else - pool_ = acl_dbuf_pool_create(4096 * nblock); + pool_ = acl_dbuf_pool_create2(4096 * nblock, align); mysize_ = sizeof(dbuf_pool); #endif } -dbuf_pool::~dbuf_pool(void) +dbuf_pool::~dbuf_pool() { #ifndef ACL_DBUF_HOOK_NEW acl_dbuf_pool_destroy(pool_); #endif } -void dbuf_pool::destroy(void) +void dbuf_pool::destroy() { delete this; } @@ -97,17 +96,17 @@ void* dbuf_pool::dbuf_memdup(const void* addr, size_t len) bool dbuf_pool::dbuf_free(const void* addr) { - return acl_dbuf_pool_free(pool_, addr) == 0 ? true : false; + return acl_dbuf_pool_free(pool_, addr) == 0; } bool dbuf_pool::dbuf_keep(const void* addr) { - return acl_dbuf_pool_keep(pool_, addr) == 0 ? true : false; + return acl_dbuf_pool_keep(pool_, addr) == 0; } bool dbuf_pool::dbuf_unkeep(const void* addr) { - return acl_dbuf_pool_unkeep(pool_, addr) == 0 ? true : false; + return acl_dbuf_pool_unkeep(pool_, addr) == 0; } ////////////////////////////////////////////////////////////////////////////// @@ -155,7 +154,7 @@ dbuf_guard::dbuf_guard(acl::dbuf_pool* dbuf, size_t capacity /* = 500 */) init(capacity); } -dbuf_guard::dbuf_guard(size_t nblock /* = 2 */, size_t capacity /* = 500 */) +dbuf_guard::dbuf_guard(size_t nblock, size_t capacity, size_t align) : nblock_(nblock == 0 ? 2 : nblock) , incr_(500) , size_(0) @@ -163,12 +162,12 @@ dbuf_guard::dbuf_guard(size_t nblock /* = 2 */, size_t capacity /* = 500 */) #ifdef DBUF_HOOK_NEW dbuf_ = dbuf_internal_ = new (nblock_) acl::dbuf_pool; #else - dbuf_ = dbuf_internal_ = new acl::dbuf_pool(nblock_); + dbuf_ = dbuf_internal_ = new acl::dbuf_pool(nblock_, align); #endif init(capacity); } -dbuf_guard::~dbuf_guard(void) +dbuf_guard::~dbuf_guard() { dbuf_objs_link* link = &head_; @@ -204,7 +203,7 @@ bool dbuf_guard::dbuf_reset(size_t reserve /* = 0 */) return dbuf_->dbuf_reset(reserve); } -void dbuf_guard::extend_objs(void) +void dbuf_guard::extend_objs() { dbuf_objs_link* link = (dbuf_objs_link*) dbuf_->dbuf_alloc(sizeof(dbuf_objs_link));