Page 507 - 《软件学报》2024年第4期
P. 507

欧阳湘臻 等: 榫卯: 一种可组合的定制化内存分配框架                                                     2085


                 卯内存框架当前提供的可用层级函数如表               2  所示. 其中系统接口层抽象了管理用户堆的方式, 它能将                mmap, brk,
                 virtualAlloc 等操作系统相关的接口抽象, 以提供更好的跨平台移植性. 同时, 系统接口层也允许在无操作系统的嵌
                 入式平台上使用预定义的静态内存池来管理现有内存. 基础层分为主干和附加两类, 其中主干部分是构成内存分
                 配器的主体, 它抽象了内存分配所使用的算法, 如              slab(slab_lk), 伙伴系统  (buddy_glk) 和  TLSF(tlsf_glk). 基础层还
                 包括一些实现较为简单的附加层, 其中有提供额外分配约束的层级, 如内存对齐分配的                            aligned  层, 负责将用户传
                 入的内存请求上下文中的大小对齐到指定大小; 也有改善性能的附加层, 如改善                          CPU cache  局部性的线程缓存
                 thread_cache 与核心感知的缓存的     carrcache_lk, 以及改善  TLB  局部性的  slab_arrcache. 附加层也可以在非内存安
                 全的应用场景下提升系统健壮性, 例如检测缓冲区溢出漏洞的                   tail_chksum, 以及检测释放后使用行为的      delayed_free;
                 还有额外的附加层提供条件绕过机制, 允许线程在满足条件的情况下绕过上一层进行内存分配, 以提供更灵活的
                 组合.


                                              表 2    榫卯内存分配框架的层级函数

                           分类                    层级函数                              说明
                                                mmap_heap                    使用UNIX mmap接口
                                                 brk_heap                      使用C库brk接口
                        系统接口层                  virtalloc_heap                使用virtualAlloc接口
                                                 sheap_glk                   可配置的静态内存堆
                                                malloc_heap                  使用C库malloc接口
                                                  slab_lk                     slab式, 每大小阶锁
                                                 buddy_glk                    伙伴系统, 全局锁
                                                  tlsf_glk                     TLSF, 全局锁
                        基础层 (主干)
                                                 segfit_lk                   分离适配, 每大小阶锁
                                                 segfit_lf                   分离适配, 无锁同步
                                                  slab_wf                     slab式, 无等待同步
                                                  aligned                      分配大小对齐
                                                batched_free                   批量释放缓存层
                                                thread_cache             每线程缓存, 使用LIFO链表管理
                                                carrcache_lk            每CPU核心缓存, 使用缓存数组管理
                                                 tarrcache               每线程缓存, 使用缓存数组管理
                        基础层 (附加)                 szcls_stat             统计该层以上内存请求大小阶分布
                                                 wcet_stat               统计该层以上内存请求延迟分布
                                                 perf_stat               统计该层以上内存请求平均时间
                                                tail_chksum                 内存块末尾增加校验和
                                                delayed_free             内存块头部增加校验与延迟释放
                                                cond_bypass            可自定义判断条件, 绕过上层进行分配
                                               malloc_socket             malloc.h中定义的malloc(3)接口
                                                kernel_socket               Linux内核内存分配接口
                        用户接口层
                                               cmalloc_socket            额外传入核心ID的malloc(3)接口
                                               custom_socket              可自定义入参的malloc(3)接口

                    此外, 一些附加层也可以记录额外的性能信息或者调试信息, 如统计内存请求大小阶分布的                              szclas_stat 和最
                 差情况请求时间分布的        wcet_stat, 能够在运行时统计并记录信息以便系统的后续优化. 基础层使用榫卯框架提供
                 的数据结构实现搭建, 以提高代码的可复用性. 用户接口层定义用户如何与内存分配器交互, 并向上连接基础层.
                 用户接口层的意义在于实现更多样化的用户接口以适配不同的应用场景. 例如在操作系统内核中定制                                  page_alloc/
                 kalloc 接口或者在用户态定制      malloc(3) 接口. 在  CPU  核心感知的应用场景下, 用户可以通过传入额外的             CPU  核
   502   503   504   505   506   507   508   509   510   511   512