自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(80)
  • 收藏
  • 关注

原创 kernel 内核中的pd域

【代码】kernel 内核中的pd域。

2025-11-25 22:33:39 74

原创 kernel 6.12 中 select_task_rq_fair 选核的逻辑分析

摘要:本文分析了Linux内核CFS调度器的核心函数select_task_rq_fair,该函数负责为唤醒任务选择目标CPU运行队列。函数主要处理三种调度域标志(SD_BALANCE_WAKE/FORK/EXEC)和唤醒标志(WF_TTWU),通过判断CPU负载情况、任务亲和性等条件,分别采用快速路径(优先选择空闲兄弟CPU)或慢速路径(在调度域内负载均衡)进行CPU选择。文章还详细解析了记录任务唤醒关系的record_wakee机制,以及判断CPU过载状态的is_rd_overutilized函数,这些

2025-11-04 22:09:46 902

原创 C语言完成Socket通信

本文介绍了基于Windows平台的TCP客户端/服务器通信实现。服务器端通过socket()、bind()、listen()和accept()建立连接,使用recv()/send()进行数据收发,监听8080端口。客户端通过socket()创建套接字,connect()连接服务器,并实现交互式消息收发功能。代码采用Winsock API,需链接ws2_32库,使用gcc编译时需添加-lws2_32参数。实现过程包括初始化WSA、创建套接字、地址绑定、连接处理及资源释放等完整流程,支持本地回环测试(127.0

2025-11-01 18:36:23 217

原创 用C语言实现时间的打印 time

摘要:这段C语言代码展示了如何获取并格式化系统时间。首先通过time()获取UTC时间,然后使用ctime()输出标准时间格式。接着使用localtime()转换为本地时间结构体,并利用strftime()自定义格式化为中国标准时间格式(YYYY-MM-DD HH:MM:SS)。最终输出两种格式的当前时间:默认格式和中国格式的本地时间。

2025-11-01 12:25:11 133

原创 C语言 了解一下回调函数(钩子函数)的使用

本文分析了Linux内核中cpufreq_add_update_util_hook()机制的作用与实现。该函数用于在CPU调度器和频率调控器之间建立回调机制,当任务负载变化时能及时触发频率调整。文章通过代码示例展示了回调函数的注册流程,包括参数解析(CPU编号、回调指针等)和实际使用方法。模拟实验验证了该机制能正确响应I/O唤醒(UTIL_UPDATE_IOWAIT)等事件,输出结果显示当flags标志位变化时能成功触发预设的回调函数。这种机制实现了调度器与CPUFreq子系统的高效联动,为动态调频提供实时

2025-10-30 22:55:42 522

原创 了解一下 sugov_cpu 结构体

本文分析了Linux内核中的sugov_cpu结构体及相关调度算法。sugov_cpu是每个CPU核心独立存储的状态结构,包含利用率(util)、I/O等待提升(iowait_boost)等字段,通过per_cpu宏访问。在共享策略下(sugov_next_freq_shared),算法会遍历所有CPU,获取各自的利用率(包括I/O等待提升处理后),取最大值作为整体负载依据。其中sugov_iowait_apply函数处理I/O等待提升逻辑:若无I/O事件则衰减提升值,有事件则转换为统一量纲进行比较。这种设

2025-10-29 21:47:41 697

原创 学习一下kernel6.12中sugov_iowait_apply的函数逻辑

本文介绍了Linux内核中schedutil调频策略的I/O等待加速机制。该机制通过临时提升CPU频率来优化I/O密集型任务的响应速度,解决任务因I/O阻塞后被唤醒时CPU频率滞后的问题。核心函数sugov_iowait_apply()负责管理I/O boost的衰减与重置:当检测到新I/O请求时保持或提升boost值,无新请求时则指数衰减,CPU空闲时重置boost。该机制通过权衡高频I/O任务加速和低频率I/O任务保守处理,有效改善了系统响应性和I/O吞吐性能。

2025-10-28 23:08:09 402

原创 了解一下kernel6.12中cpu_util_cfs_boost函数的逻辑

本文分析了Linux内核中CPU利用率计算的核心函数cpu_util(),重点解析了util_avg(实际CPU利用率)和runnable_avg(可运行任务压力)两个关键指标的区别与联系。util_avg反映任务实际执行时间,而runnable_avg包含等待调度的任务压力。通过max(util_avg, runnable_avg)计算,调度器能准确识别CPU真实负载情况,包括任务排队等隐性压力,避免仅依赖实际利用率导致的调度偏差。这一机制为负载均衡、能效调度和CPU调频提供了精准依据,是确保系统调度高效

2025-10-28 22:28:13 1030

原创 记录一下Linux 6.12 中 cpu_util函数的作用

摘要: cpu_util()是Linux内核中用于估算CFS任务CPU利用率的函数,其返回值与CPU算力单位一致(0~1024)。核心功能包括: 应用场景:支持能效调度(EAS)、CPU调频(schedutil)和负载均衡决策; 计算逻辑:基于PELT的util_avg和util_est,通过任务迁移模拟(增减贡献值)和Boost模式(取util_avg与runnable_avg最大值)动态调整估算; 竞态处理:针对任务迁移中的状态间隙,通过current==p检查减少利用率误判; 参数组合:不同参数配置可

2025-10-27 22:16:04 991

原创 dumpsys meminfo 中的 Lost RAM 怎样计算?

摘要: dumpsysmeminfo中的LostRAM是系统未明确归类到特定用途的内存,计算公式为:TotalRAM减去已统计内存(进程使用、缓存、内核占用等)。其成因包括统计口径差异(如内核专有驱动内存未计入)、缓存机制或重复计算(可能导致负值)。MTK平台可通过page_owner_full.txt分析内核层内存分配,借助Linux的PageOwner机制(需手动开启)追踪内存页面来源,但需注意性能开销和早期分配漏检问题。该工具适用于调试内存泄漏及“内存黑洞”,尤其针对芯片厂商的预留内存(如ION)或图

2025-10-22 22:57:29 730

原创 C语言对单链表的操作

本文实现了一个带头结点的单链表数据结构,包含链表的基本操作。首先定义了链表节点结构体,包含数据域和指针域。主要功能包括:初始化空链表、判断链表是否为空、头插法和尾插法插入节点、按位置/值插入/删除节点、按值/位置查找节点、遍历链表以及销毁链表等操作。其中头插法在链表头部插入节点,尾插法在链表尾部追加节点。所有操作都基于带头结点的设计,头结点不存储实际数据,其next指针指向第一个有效节点。最后在main函数中演示了链表的创建和使用方法。

2025-10-19 21:42:00 246

原创 Linux memfree 的计算逻辑

本文分析了Linux系统中MemFree的计算逻辑及其与内核函数global_node_page_state(NR_FREE_PAGES)的关系。MemFree表示系统当前空闲物理内存,其值主要来源于global_node_page_state对NUMA节点空闲页数的全局统计。文章详细比较了MemFree与/proc/zoneinfo中nr_free_pages的区别,前者是全局汇总值,后者按内存区域细分。内核实现上,MemFree的计算在fs/proc/meminfo.c中完成,通过si_meminfo获

2025-10-19 20:52:46 607

原创 Linux 内核伙伴系统在快速路径分配内存时,对一个内存区域(Zone)进行水位线检查和内存压力评估的关键逻辑

摘要:本文分析了Linux内核内存分配中的伙伴系统和水位线机制。在伙伴系统中,get_page_from_freelist()函数通过zone_watermark_fast()快速检查zone的水位线,若失败则通过cond_accept_memory()进行二次评估,体现了效率与安全的平衡。水位线计算部分,__setup_per_zone_wmarks()根据min_free_kbytes和zone内存占比计算各水位线,对低端和高端内存采用不同策略,并通过watermark_scale_factor实现动态

2025-10-18 11:58:32 824

原创 Linux 系统下 ZONE 区域的划分

本文介绍了Linux内存管理中的zone分区和伙伴系统机制。内核将物理内存划分为DMA、DMA32和NORMAL等zone区域,每个zone使用struct zone结构管理。伙伴系统通过free_area数组(包含11个不同大小的空闲链表)来高效管理内存页块,支持2^0到2^10个连续页框的分配。alloc_pages()函数通过快速路径直接查找空闲链表,失败时进入慢速路径触发内存回收等操作。这种机制既能满足多样化的内存需求,又能有效减少内存碎片。

2025-10-17 21:05:27 785

原创 当内存紧张时出现mm_vmscan_direct_reclaim 直接回收,需要对其分析

Linux内核内存管理中的mm_vmscan_direct_reclaim路径负责同步直接页面回收,当系统空闲内存低于低水位线时触发。该过程会阻塞申请进程,通过try_to_free_pages()函数执行回收,可能导致性能抖动。关键监控指标包括pgscan_direct、pgsteal_direct和allocstall。调优建议包括调整lowmem_reserve_ratio参数优化内存域保留页比例。try_to_free_pages()作为核心回收函数,通过scan_control结构体控制回收行为,

2025-10-16 23:07:48 746

原创 lmkd.cpp 部分逻辑

摘要:这段代码展示了Android LMKD(低内存杀手守护进程)的核心决策逻辑,用于在内存压力下选择终止进程。系统通过监测内存水位线、PSI压力指标、交换空间使用率和内存抖动等多项指标,判断当前内存状态并触发相应操作。决策过程采用分级策略,优先终止低优先级进程(oom_score_adj值高),同时保护用户可感知的应用(adj≤200)。典型终止原因包括:内存回收后仍低于阈值、系统响应延迟、交换空间不足伴随内存抖动等。该机制通过多维度监控和智能决策,在保障系统稳定的同时最大限度减少对用户体验的影响。

2025-10-16 22:23:05 797

原创 Lmkd查杀功能的详细步骤

摘要: LMKD是Android系统管理内存的关键守护进程,通过PSI、vmpressure或内存水位线监控压力,动态调整查杀阈值(min_score_adj)并终止目标进程(按oom_score_adj和内存占用选择)。频繁查杀adj200进程可能因内存不足、PSI阈值过低或配置激进(如ro.lmk.critical=0)导致。优化建议包括:1) 调高PSI阈值(如ro.lmk.psi_partial_stall_ms至100ms);2) 监控/proc/meminfo的MemAvailable和/pro

2025-10-15 23:37:25 1075

原创 AIDL 接口的定义与生成,使用

Android开发中,AIDL生成的asStub()方法(实为Stub.asInterface())是跨进程通信的核心。服务端继承Stub类实现业务逻辑,通过onBind()返回Binder对象;客户端通过asInterface()将Binder转换为接口代理。系统服务层(如ActivityManagerService)同样基于此机制,需继承Stub并注册到ServiceManager。整个过程通过Binder驱动实现数据封装和进程间方法调用,使远程调用如同本地操作。

2025-10-14 23:08:45 702

原创 Python中循环的使用

Python提供了两种主要循环结构:for循环用于遍历序列(列表、字符串、字典等),适合已知循环次数或逐个处理元素的场景;while循环则根据条件重复执行,适用于不确定循环次数但知道结束条件的情况。此外,break语句用于立即终止整个循环,而continue语句用于跳过当前循环继续下一次。这些控制结构可以灵活组合使用,满足不同编程需求。

2025-10-10 10:25:15 313

原创 Python项目如何调用摄像头拍照并发送到邮件中

摘要:该Python脚本实现了通过摄像头捕捉图像并发送邮件功能。首先使用OpenCV打开摄像头并拍摄照片,将照片以时间戳命名保存到指定目录。然后通过SMTP协议配置163邮箱发送邮件,将拍摄的照片作为附件添加到邮件中,并附带预设的文本内容。整个过程包括摄像头初始化、图像捕获、文件保存、邮件构造(含附件)和发送等步骤,最后释放摄像头资源并输出操作结果。代码中包含了异常处理机制,确保在出现错误时能够输出提示信息。

2025-10-09 18:37:25 106

原创 kernel 6.6中新增的EEVDF特性

Linux内核调度器从6.6版本开始引入EEVDF(Earliest Eligible Virtual Deadline First)算法,取代传统的vruntime排序机制。EEVDF通过虚拟截止时间和服务欠账计算来选择任务,在保持公平性的同时优化延迟和性能。其核心流程包括:单任务优化直接返回;检查当前任务是否仍符合条件;优先选择红黑树最左侧任务;通过堆搜索找到最早截止时间的符合条件任务。相比传统CFS,EEVDF能更好处理高负载场景,确保短任务及时调度,同时避免长任务被过度抢占,实现更优的任务切换效率。

2025-09-21 21:45:17 1211

原创 关于CFS队列pick_next_task_fair选取下一个任务的分析

摘要:pick_next_task_fair是Linux CFS调度器的核心函数,用于公平选择下一个运行任务。其主要流程包括:1)检查可运行任务,若无则进入负载均衡;2)通过update_curr更新当前任务的虚拟运行时间(vruntime);3)使用红黑树按vruntime排序,优先选择最小vruntime任务;4)处理多级调度组时最小化更新范围。关键机制在于:vruntime只更新运行中任务,但通过维护min_vruntime基准和红黑树排序,确保未运行任务通过较小vruntime获得补偿调度,实现全局

2025-09-21 19:48:36 890

原创 记录Python中安装face_recognition

本文详细介绍了在Mac和Windows系统上安装face-recognition库的步骤。Mac用户可通过Homebrew安装CMake和OpenBLAS依赖项后,使用pip直接安装。Windows用户需先安装Python、Visual C++构建工具,建议下载预编译的dlib wheel文件简化安装过程,最后通过pip安装face-recognition。两种系统都推荐使用清华镜像源加速下载。安装完成后可通过import命令验证是否成功。

2025-09-18 22:51:14 744

原创 分析下kernel6.6中如何获取下一次的cpu频率

本文分析了Linux内核中schedutil频率调节器的核心函数get_next_freq()的工作原理。该函数通过基于CPU利用率的动态频率调整算法,计算并返回适合当前负载的新频率。主要实现原理是:当利用率可频率不变时,新频率与利用率成正比;否则采用近似计算。算法引入C=1.25的增益系数,实现80%利用率触发基准频率的效果。通过真实ARM64移动设备案例,展示了函数在不同负载场景下的计算过程,包括频率约束处理、驱动支持频率匹配等关键步骤。最后介绍了实际调试方法,包括ftrace追踪和实时监控,揭示了该算

2025-09-17 23:38:19 740

原创 kernel侧CPU是怎样判断共享的?

Linux CPUFreq子系统的shared策略设计摘要 CPUFreq子系统通过policy_is_shared()函数判断多个CPU是否共享频率策略,当cpumask_weight(policy->cpus)>1时视为共享。这源于硬件限制,如ARM big.LITTLE架构中同一cluster的CPU共享时钟源。共享策略会采用sugov_update_shared函数,取所有CPU的最大利用率来决定频率,并需要加锁同步。相比独立策略,共享策略减少了频率切换但响应较慢,适用于多核共享时钟域的

2025-09-17 22:27:14 741

原创 cpu调频触发逻辑

本文分析了Linux内核中CPU频率更新的触发机制,主要分为三个阶段: 注册阶段(sugov_start): 初始化策略状态参数 清零per-CPU数据结构 根据硬件能力选择最优回调函数 为每个CPU调用注册函数 绑定阶段(cpufreq_add_update_util_hook): 进行参数检查和安全验证 设置回调函数指针 发布到全局per-CPU变量 形成完整的调用链关系 触发阶段(cpufreq_update_util): 调度器感知负载变化 获取当前CPU的钩子指针 安全读取RCU保护的指针 调用已

2025-09-16 22:54:45 573

原创 C语言函数指针的使用

本文介绍了函数指针的基本用法及其在结构体中的应用。主要内容包括:1.函数指针的声明语法;2.如何在结构体中嵌入函数指针成员;3.定义匹配函数的注意事项;4.结构体实例初始化的三种方式;5.通过结构体调用函数指针的实现方法。文中通过具体代码示例,详细说明了从函数指针声明、赋值到调用的完整流程,并展示了结构体中函数指针的实际应用场景。最后提供了一个完整的案例代码,帮助理解函数指针与结构体的结合使用。

2025-09-14 20:06:31 414

原创 Sugov 关于频率变化

本文分析了Linux内核中sugov_start()函数的实现,该函数用于初始化CPU频率调节策略。主要功能包括:1) 初始化策略参数,如频率更新延迟、缓存频率等;2) 根据硬件能力动态选择最优的update_util回调函数,提供三种路径:共享策略(sugov_update_shared)、高性能路径(sugov_update_single_perf)和兼容路径(sugov_update_single_freq);3) 为每个CPU注册回调钩子。性能测试显示,不同路径的延迟差异显著,其中高性能路径延迟最低

2025-09-14 19:15:08 911

原创 CPU Driver

这个函数的主要作用是将一个新的governor添加到系统的governor列表中,以便系统可以使用它来管理CPU频率。在Linux内核中,CPU频率调节策略(governor)是通过cpufreq_register_governor。结构体的指针,表示要注册的governor。CPU 频率调节策略(governor)新版内核(5.0+)的推荐选择。节能优先(如笔记本省电模式)(高负载→升频,空闲→降频)(现代内核默认,响应更快)通用场景(旧版内核常用):始终运行在最高频率。:始终运行在最低频率。

2025-09-14 16:56:11 821

原创 Kernel内核代码中 cpumask

Linux内核使用结构体cpumask(别名cpumask_t)表示CPU状态位图,该结构体通过DECLARE_BITMAP宏定义了一个unsigned long数组来存储位图。DECLARE_BITMAP利用BITS_TO_LONGS宏将所需的比特位数量转换为足够容纳的数组长度,通过向上取整确保数组能完整存储NR_CPUS个有效比特位。其中BITS_TO_LONGS基于CPU架构的long类型长度进行计算,最终生成的位图可能存在部分无效比特位。

2025-09-10 22:45:53 276

原创 内核Sched调度关于find_idlest_cpu选核逻辑

该代码实现了一个全局负载均衡算法,用于寻找系统中最空闲的CPU来调度任务。核心逻辑是通过逐层遍历调度域和调度组结构:1. 首先检查任务是否允许在当前调度域中的CPU上运行;2. 同步任务的负载信息以便准确计算;3. 从顶层调度域开始,寻找最空闲的调度组和CPU;4. 若当前层级未找到更优解,则继续向子调度域深入搜索;5. 最终返回负载最低的CPU。调度域采用层次化结构(NUMA域→MC域→SMT域),支持在不同粒度上实现负载均衡。该算法综合考虑CPU利用率、任务数、缓存热度等因素,确保任务被合理分配到最合适

2025-08-31 19:38:52 837

原创 C语言中如何使用NULL

C语言中NULL是表示空指针的标准宏,常用于初始化指针、检查指针有效性(如malloc失败时返回NULL)以及标记数据结构终点。NULL通常被定义为(void*)0或0,但语义上专用于指针上下文。使用时需注意:不可解引用NULL指针,否则会导致程序崩溃;推荐使用NULL而非0以提高代码可读性。合理使用NULL能避免野指针问题,确保内存操作安全。

2025-08-31 18:08:33 574

原创 用函数实现方程函数解题

本文介绍了线性方程和二次方程的求解方法及C语言实现。对于线性方程ax+b=0,通过x=-b/a求解,并处理a=0的错误情况。二次方程ax²+bx+c=0通过判别式Δ判断根的类型(实根/复根),使用结构体返回结果。两种方法均包含错误处理机制,确保a≠0。代码示例展示了不同情况下的解法和输出格式,包括正常解、重根和复数根的情况。

2025-08-17 16:18:39 331

原创 C语言中回调函数的作用

回调函数是一种编程设计模式,通过函数指针实现"反向调用",让底层函数在适当时调用上层定义的函数。它解决了代码复用问题,使通用函数(如排序)能适应不同需求(如升序/降序)。实现步骤包括定义回调接口、编写具体回调函数、在通用函数中调用回调。回调函数提高了代码灵活性,支持运行时动态绑定,广泛应用于排序、事件处理等场景。使用时需注意函数指针匹配和生命周期管理问题。

2025-08-17 12:44:39 1063

原创 一(3)理解 newNode->next = head 和 Node* temp = head 的区别

C语言中指针变量存储内存地址,是链表操作的基础。指针赋值(如temp=head)复制地址值,使多个指针指向同一节点。链表节点包含数据域和指向下一节点的指针域。头插法通过newNode->next=head将新节点连接到链表头部,再用head=newNode更新头指针。这种地址复制机制使得链表操作直观高效,新节点插入后成为新的头节点,原链表成为其后继。理解指针的地址复制本质是掌握链表操作的关键。

2025-08-05 21:50:52 1035

原创 一(2)关于单链表中的疑问 head = head->next; 和 head->next = head 的核心区别

这篇文章对比分析了链表操作中两个关键语句的区别:head=head->next和head->next=head。前者是合法操作,通过临时指针保存原头节点后移动头指针到下一个节点,常用于链表遍历或头节点删除;后者则是错误操作,会使头节点指向自身形成死循环,破坏链表结构。文章通过代码示例验证了两种操作的不同效果,并强调后者通常会导致链表无法正常使用。理解这两种操作的本质区别对正确处理链表操作至关重要。

2025-08-04 22:47:49 932

原创 一(1)关于单链表中的疑问

摘要: Node*temp=head;是将头指针head存储的节点地址复制给临时指针temp,使两者指向同一链表节点(或均为NULL)。此时: 指针关系:temp是head的副本,修改temp的指向(如temp=temp->next)不会影响head,但通过temp修改节点内容(如temp->data)会同步反映到head指向的节点。 作用:避免直接操作head导致链表入口丢失,常用于安全遍历链表。 关键点:指针赋值是地址复制,非指向反转;temp作为临时变量可维护头指针稳定性,提升代码安全性。

2025-08-04 22:20:53 777

原创 C语言实现单链表的操作

单链表是一种线性数据结构,由节点组成,每个节点包含数据域和指向下一个节点的指针。文章详细介绍了单链表的基本操作:创建节点、头插法/尾插法插入节点、遍历打印链表、删除头节点、释放链表内存等。重点讲解了指定位置插入节点的两种实现方式(前插和后插),并分析了边界条件处理。单链表的优点在于动态大小和高效插入删除(头插O(1)),缺点是查找效率低(O(n))和需要额外指针空间。文中提供了完整的C语言实现代码,包括测试用例,适合初学者理解单链表的基本原理和操作方法。

2025-08-04 21:28:20 935

原创 数组和指针的关系

C语言中指针和数组既有联系又有本质区别。数组名在大多数情况下会退化为指向首元素的指针(如arr等价于&arr[0]),但数组名本身不是指针变量,不能重新赋值。关键区别在于:指针是变量可修改指向,而数组名是常量指针;arr和&arr值相同但类型不同(int* vs int()[n]),导致指针运算步长不同。数组访问arr[i]本质是指针算术(arr+i),函数传参时数组会退化为指针,无法在函数内获取数组大小。指针更灵活可指向任意内存,而数组是固定大小的连续内存块。

2025-08-03 22:43:27 709

原创 记录Sched学习

2025-07-20 19:47:11 132

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除