当前位置: 首页 > news >正文

Android 用java程序模拟binder buffer的分配释放以及buffer的向前和向后合并

用Java代码模拟以下代码,以便理解

/* 处理缓冲区分割:如果找到的缓冲区比需要的大 */if (buffer_size != size) {/* 找到 oversized 缓冲区,需要进行分割 */buffer = rb_entry(best_fit, struct binder_buffer, rb_node);buffer_size = binder_alloc_buffer_size(alloc, buffer);/* 确保条件正确:不应该有精确匹配,且缓冲区确实大于需求 */WARN_ON(n || buffer_size == size);/* 设置新缓冲区的起始地址(原缓冲区地址 + 需求大小) */new_buffer->user_data = buffer->user_data + size;/* 将新缓冲区添加到链表中 */list_add(&new_buffer->entry, &buffer->entry);new_buffer->free = 1;  // 标记为空闲/* 将剩余部分插入空闲树 */binder_insert_free_buffer(alloc, new_buffer);new_buffer = NULL;  // 防止后续重复释放}

Java代码如下:
DemoTwoListDebug.java

import java.util.*;public class DemoTwoListDebug {/* -------------------- 结点 -------------------- */private static final class Node {long addr, size;Node prev, next;Node(long a, long s) { addr = a; size = s; }String range() { return String.format("[%08X,%08X)", addr, addr + size); }}/* -------------------- 两条链表 -------------------- */private final Node allocHead = new Node(-1, -1);private final Node freeHead  = new Node(-1, -1);{ allocHead.next = allocHead.prev = allocHead; }{ freeHead.next  = freeHead.prev  = freeHead; }private final long totalSize;public DemoTwoListDebug(long totalSize) {this.totalSize = totalSize;insertFree(new Node(0, totalSize));debug("初始");}/* ==================== 分配 ==================== */public synchronized long alloc(long req) {if (req <= 0) return -1;Node best = null, cur = freeHead.next;while (cur != freeHead) {if (cur.size >= req && (best == null || cur.size < best.size))best = cur;cur = cur.next;}if (best == null) {debug("alloc failed");return -1;}/* 摘空闲 */removeFree(best);debug(String.format("best-fit 选中 %s", best.range()));/* 切分 */long rem = best.size - req;if (rem > 0) {Node split = new Node(best.addr + req, rem);insertFree(split);debug(String.format("切分剩余 %s", split.range()));}/* 插已分配 */Node allocNode = new Node(best.addr, req);insertAlloc(allocNode);debug("after alloc");return allocNode.addr;}/* ==================== 释放 ==================== */public synchronized void free(long addr) {Node tgt = allocHead.next;while (tgt != allocHead && tgt.addr != addr) tgt = tgt.next;if (tgt == allocHead) throw new IllegalArgumentException("bad addr");removeAlloc(tgt);debug(String.format("free %s", tgt.range()));/* 先插空闲(保持有序)再合并 */insertFree(tgt);coalesce(tgt);debug("after free");}/* ==================== 合并 ==================== */private void coalesce(Node mid) {Node prev = mid.prev, next = mid.next;if (prev != freeHead && prev.addr + prev.size == mid.addr) {debug(String.format("向前合并 %s + %s", prev.range(), mid.range()));prev.size += mid.size;removeFree(mid);mid = prev;}if (next != freeHead && mid.addr + mid.size == next.addr) {debug(String.format("向后合并 %s + %s", mid.range(), next.range()));mid.size += next.size;removeFree(next);}}/* ==================== 链表工具 ==================== */private void insertFree(Node n) {Node cur = freeHead.next;while (cur != freeHead && cur.addr < n.addr) cur = cur.next;Node pre = cur.prev;pre.next = n; n.prev = pre;n.next = cur; cur.prev = n;}private void removeFree(Node n)  { n.prev.next = n.next; n.next.prev = n.prev; }private void insertAlloc(Node n) { /* 头插即可 */ n.next = allocHead.next; n.prev = allocHead;allocHead.next.prev = n; allocHead.next = n; }private void removeAlloc(Node n) { n.prev.next = n.next; n.next.prev = n.prev; }/* ==================== 调试打印 ==================== */private void debug(String phase) {System.out.printf("========== %s ==========%n", phase);System.out.println("freeList (addr升序):");Node cur = freeHead.next;while (cur != freeHead) {System.out.printf("  %s%n", cur.range());cur = cur.next;}System.out.println("allocatedList:");cur = allocHead.next;while (cur != allocHead) {System.out.printf("  %s%n", cur.range());cur = cur.next;}System.out.println();}/* ==================== 交互 ==================== */public static void main(String[] args) {DemoTwoListDebug alloc = new DemoTwoListDebug(1024);Scanner in = new Scanner(System.in);System.out.println("Commands:  alloc <size>  |  free <addr>  |  exit");while (true) {System.out.print("> ");String line = in.nextLine().trim();if (line.equalsIgnoreCase("exit")) break;String[] tok = line.split("\\s+");if (tok.length != 2) { System.out.println("bad cmd"); continue; }try {if (tok[0].equals("alloc")) {long sz = Long.parseLong(tok[1]);long a = alloc.alloc(sz);if (a == -1) System.out.println("alloc failed");} else if (tok[0].equals("free")) {long a = Long.parseLong(tok[1], 16);alloc.free(a);} else {System.out.println("unknown cmd");}} catch (Exception e) {System.out.println("error: " + e.getMessage());}}}
}

调试结果如下:

javac DemoTwoListDebug.java && java DemoTwoListDebug
========== 初始 ==========
freeList (addr升序):[00000000,00000400)
allocatedList:Commands:  alloc <size>  |  free <addr>  |  exit
> alloc 100
========== best-fit 选中 [00000000,00000400) ==========
freeList (addr升序):
allocatedList:========== 切分剩余 [00000064,00000400) ==========
freeList (addr升序):[00000064,00000400)
allocatedList:========== after alloc ==========
freeList (addr升序):[00000064,00000400)
allocatedList:[00000000,00000064)> alloc 300
========== best-fit 选中 [00000064,00000400) ==========
freeList (addr升序):
allocatedList:[00000000,00000064)========== 切分剩余 [00000190,00000400) ==========
freeList (addr升序):[00000190,00000400)
allocatedList:[00000000,00000064)========== after alloc ==========
freeList (addr升序):[00000190,00000400)
allocatedList:[00000064,00000190)[00000000,00000064)> alloc 10
========== best-fit 选中 [00000190,00000400) ==========
freeList (addr升序):
allocatedList:[00000064,00000190)[00000000,00000064)========== 切分剩余 [0000019A,00000400) ==========
freeList (addr升序):[0000019A,00000400)
allocatedList:[00000064,00000190)[00000000,00000064)========== after alloc ==========
freeList (addr升序):[0000019A,00000400)
allocatedList:[00000190,0000019A)[00000064,00000190)[00000000,00000064)> free 190
========== free [00000190,0000019A) ==========
freeList (addr升序):[0000019A,00000400)
allocatedList:[00000064,00000190)[00000000,00000064)========== 向后合并 [00000190,0000019A) + [0000019A,00000400) ==========
freeList (addr升序):[00000190,0000019A)[0000019A,00000400)
allocatedList:[00000064,00000190)[00000000,00000064)========== after free ==========
freeList (addr升序):[00000190,00000400)
allocatedList:[00000064,00000190)[00000000,00000064)> free 0
========== free [00000000,00000064) ==========
freeList (addr升序):[00000190,00000400)
allocatedList:[00000064,00000190)========== after free ==========
freeList (addr升序):[00000000,00000064)[00000190,00000400)
allocatedList:[00000064,00000190)> free 64
========== free [00000064,00000190) ==========
freeList (addr升序):[00000000,00000064)[00000190,00000400)
allocatedList:========== 向前合并 [00000000,00000064) + [00000064,00000190) ==========
freeList (addr升序):[00000000,00000064)[00000064,00000190)[00000190,00000400)
allocatedList:========== 向后合并 [00000000,00000190) + [00000190,00000400) ==========
freeList (addr升序):[00000000,00000190)[00000190,00000400)
allocatedList:========== after free ==========
freeList (addr升序):[00000000,00000400)
allocatedList:
http://www.dtcms.com/a/398550.html

相关文章:

  • 专门做护肤品网站浙江立鹏建设有限公司网站
  • 电商会学着做网站呢设计师接单渠道
  • Postman 学习笔记 II:测试、断言与变量管理
  • electron设置默认应用程序
  • Flink 初体验10 分钟完成下载、安装、本地集群启动与示例作业运行
  • toLua[二] Examples 01_HelloWorld分析
  • asp源码打开网站网站页面数量
  • 安卓手机termux安装ubuntu被kill进程解决
  • java后端工程师进修ing(研一版‖day48)
  • 目标检测进化史
  • 北京做养生SPA的网站建设高端网站建设 来磐石网络
  • 网站建设有哪三部来年做那些网站能致富
  • 外贸公司网站素材产品营销文案
  • VSCode C/C++ 开发环境配置
  • FPGA自学笔记--VIVADO RAM IP核控制和使用
  • 电源——设计DCDC原理图与参数选型
  • 企业网站建设策划书 前言263云通信官方网站
  • pip config list输出为空?如何配置pip镜像源?不同方式配置有什么区别?
  • 表格工具怎么选,国产化替代方案测评(2025 全维度实测版)
  • 分布式 ID 生成方案实战指南:从选型到落地的全场景避坑手册(二)
  • 企业网站建设案例宝安三网合一网站建设
  • 做透水砖的网站vs2019可以做网站吗
  • 鸿蒙后台定时任务实战
  • 【win32】ffmpeg 解码器2
  • MCU知识体系
  • 【win32】ffmpeg 解码器
  • 东莞市官网网站建设公司中企动力z邮箱登录入口
  • wordpress网站seo罗夫曼三大社区模式
  • 搭建一个属于自己的mac摄像头视频流rtsp服务
  • Spring Boot 集成 RabbitMQ 实现可靠消息传递:从配置到实战