当前位置:网站首页>V79.01 Hongmeng kernel source code analysis (user mode locking) | how to use the fast lock futex (Part 1) | hundreds of blogs analyze the openharmony source code
V79.01 Hongmeng kernel source code analysis (user mode locking) | how to use the fast lock futex (Part 1) | hundreds of blogs analyze the openharmony source code
2022-07-01 08:36:00 【Hongmeng kernel source code analysis】
Analysis of 100 blogs | This article is :( User state lock ) | How to use quick lock Futex( On )
Process communication related articles are :
- v26.08 Hongmeng kernel source code analysis ( spinlocks ) | Be a good comrade of chastity archway
- v27.05 Hongmeng kernel source code analysis ( The mutex ) | It's the same lock, but it's fuller
- v28.04 Hongmeng kernel source code analysis ( Process communication ) | Nine ways of interprocess communication
- v29.05 Hongmeng kernel source code analysis ( Semaphore ) | Who is solving the synchronization between tasks
- v30.07 Hongmeng kernel source code analysis ( Event control ) | How to synchronize many to many tasks
- v33.03 Hongmeng kernel source code analysis ( Message queue ) | How to transfer big data asynchronously between processes
- v76.01 Hongmeng kernel source code analysis ( Shared memory ) | The fastest way to communicate between processes
- v77.02 Hongmeng kernel source code analysis ( Message encapsulation ) | analyse LiteIpc( On ) Process communication content
- v78.01 Hongmeng kernel source code analysis ( Message mapping ) | analyse LiteIpc( Next ) Process communication mechanism
- v79.01 Hongmeng kernel source code analysis ( User state lock ) | How to use quick lock Futex( On )
Quick lock Chapter 3
Hongmeng kernel realizes Futex, This series will use three articles to introduce Quicklock , There are two main reasons :
- Introduction Online
FutexThere are very few articles , A comprehensive and in-depth introduction to the kernel is even less , So let's sort it out and dig it out . - It involves the cooperation between user mode and kernel mode , Interaction means the use of user state ( A piece of ) But also to clarify the implementation of kernel state ( Two articles ). This is the first one , How to use in user mode
Futex, And with the help of ademoExplain the whole process .
Basic concepts
Futex(Fast userspace mutex, User mode fast mutex ), Series abbreviation Quick lock , It's a Linux Implement locking and build high-level Abstract locks such as semaphores and POSIX The basic tool of mutual exclusion , It first appeared in linux Kernel developed 2.5.7 edition ; Its semantic meaning is 2.5.40 Fixed , And then in 2.6.x Series stable kernel appears , It is a system call capability provided by the kernel . Generally, as a basic component, it is combined with the relevant lock logic of user state to form user state lock , It is a kind of lock in which user state and kernel state work together , Its user state part is responsible for locking logic , The kernel state part is responsible for lock scheduling .
When a user thread requests a lock , First, judge and maintain the lock status in user status , If there is no lock competition at this time , Then lock it directly in the user status and return ; conversely , You need to suspend the thread , adopt Futex The system call requests kernel intervention to suspend the thread , And maintain the blocking queue .
When the user thread releases the lock , First, judge and maintain the lock status in user status , If no other thread is blocked by the lock at this time , Then unlock directly in user status and return to ; conversely , You need to wake up the blocked thread , adopt Futex The system call requests the kernel to intervene to wake up the thread in the blocking queue .
Meaning of being
The mutex (
mutex) You must enter the kernel state to know whether the lock can be used or not , If no one disputes with you, take the lock and return to the user state , If someone argues, you have to wait ( Include Finite time waiting and infinite waiting , All need to make wayCPUExecutive power ) Or abandon this application and return to the user status to continue execution . Then why The mutex Be sure to fall into kernel state check ? The mutex (mutex) The essence is to compete for a global variable in kernel space (LosMuxStructure ). Applications also have global variables , But its scope is only valid in its own user space , It belongs to internal resources , Competition is also solved internally by the application itself . And the resource competition between applications ( Kernel resources ) You need a kernel program to solve , There is only one kernel space , Of course, the global variables of the kernel should be managed by the kernel . If an application wants to use kernel resources, it must fall into kernel state through system call , Take over the kernelCPU, The essence of takeover is to change the program status register ,CPUSwitch from user mode stack to kernel mode stack and run , After the execution is completed, you have to switch back to the user status stack to continue the execution , In this way, there is a loss of system performance in the context switching between stacks . If you don't understand, please go to the series ( Mutex ) Look over .Quick lock The solution is whether you can know whether the lock is available in the user state , Because competition doesn't happen all the time , When you go to the kernel state, in fact, no one will argue for you , Running back and forth in vain is a waste of performance . That's the question , How to know whether the lock is available in user mode ? Because you can't access the global variables of the kernel without falling into the kernel state . And the variables in their own private space are invalid for other processes and cannot be used . The deeper you study the kernel, the more you feel , The implementation of the kernel can be derived mathematically , Very interesting . Mathematics is actually based on several common sense axioms to deduce the whole mathematical system , Because you can't be self consistent without this logic . If you have a certain understanding of the kernel , Naturally, it can be deduced here with the help of Shared memory To achieve !
Using process
Look at linux futex official demo Specify how to use in user mode Futex The whole process , Not much code , But there are many knowledge points related to the kernel , Through it, we can test the solid level of basic skills of the kernel .
//futex_demo.c#define _GNU_SOURCE#include <stdio.h>#include <errno.h>#include <stdatomic.h>#include <stdint.h>#include <stdlib.h>#include <unistd.h>#include <sys/wait.h>#include <sys/mman.h>#include <sys/syscall.h>#include <linux/futex.h>#include <sys/time.h>#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \ } while (0)static uint32_t *futex1, *futex2, *iaddr;/// Fast system call static int futex(uint32_t *uaddr, int futex_op, uint32_t val, const struct timespec *timeout, uint32_t *uaddr2, uint32_t val3){ return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);}/// Apply for quick lock static void fwait(uint32_t *futexp){ long s; while (1) { const uint32_t one = 1; if (atomic_compare_exchange_strong(futexp, &one, 0)) break; // Apply for quick lock successfully // Failed to apply for quick lock , Need to wait s = futex(futexp, FUTEX_WAIT, 0, NULL, NULL, 0); if (s == -1 && errno != EAGAIN) errExit("futex-FUTEX_WAIT"); }}/// Release the quick lock static void fpost(uint32_t *futexp){ long s; const uint32_t zero = 0; if (atomic_compare_exchange_strong(futexp, &zero, 1)) {// Release the quick lock successfully s = futex(futexp, FUTEX_WAKE, 1, NULL, NULL, 0);// Wake up and wait for the lock process / Threads if (s == -1) errExit("futex-FUTEX_WAKE"); }}/// The process of father son competition is fast int main(int argc, char *argv[]){ pid_t childPid; int nloops; setbuf(stdout, NULL); nloops = (argc > 1) ? atoi(argv[1]) : 3; iaddr = mmap(NULL, sizeof(*iaddr) * 2, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);// Create read-write anonymous shared memory if (iaddr == MAP_FAILED) errExit("mmap"); futex1 = &iaddr[0]; // Bind lock an address futex2 = &iaddr[1]; // Bind lock 2 address *futex1 = 0; // Lock 1 cannot be applied *futex2 = 1; // Lock two can apply for childPid = fork(); if (childPid == -1) errExit("fork"); if (childPid == 0) {// Subprocess return for (int j = 0; j < nloops; j++) { fwait(futex1);// Apply for a lock printf(" Subprocesses (%jd) %d\n", (intmax_t) getpid(), j); fpost(futex2);// Release lock 2 } exit(EXIT_SUCCESS); } // The parent process returns execution for (int j = 0; j < nloops; j++) { fwait(futex2);// Apply for lock two printf(" The parent process (%jd) %d\n", (intmax_t) getpid(), j); fpost(futex1);// Release the lock } wait(NULL); exit(EXIT_SUCCESS);} Code in wsl2 The results of compiling and running on are as follows :
[email protected]:/home/turing# gcc ./futex_demo.c -o [email protected]:/home/turing# ./futex_demo The parent process (283) 0 Subprocesses (284) 0 The parent process (283) 1 Subprocesses (284) 1 The parent process (283) 2 Subprocesses (284) 2Reading
- By system call
mmapCreate a readable and writable shared memoryiaddr[2]integer array , Complete twofutexLock initialization . The kernel allocates a shared linear area in memory (MAP_ANONYMOUS|MAP_SHARED), The linear area is readable and writable (PROT_READ|PROT_WRITE)
suchfutex1 = &iaddr[0]; // Bind lock an address futex2 = &iaddr[1]; // Bind lock 2 address *futex1 = 0; // Lock 1 cannot be applied *futex2 = 1; // Lock two can apply forfutex1andfutex2Have initial values and are all shared variables , Want to learn moremmapViewable series of Kernel Implementation ( Linear section ) and ( Shared memory ) In detail . childPid = fork();Created a subprocess ,fork The mapping of the linear area of the parent process will be copied to the child process , The result is that the parent process shares the linear region to the child process, which is also the shared linear region , The mapping is the same physical address . YesforkPlease go to the unfamiliar , Series (fork piece )| One call , Two returns Specifically, it .fwait( To apply for the lock ) Andfpost( Release the lock ) Pairs appear , Look at the lock application process alone
The infinite loop break On the condition that/// Apply for quick lock static void fwait(uint32_t *futexp){ long s; while (1) { const uint32_t one = 1; if (atomic_compare_exchange_strong(futexp, &one, 0)) break; // Apply for quick lock successfully // Failed to apply for quick lock , Need to wait s = futex(futexp, FUTEX_WAIT, 0, NULL, NULL, 0); if (s == -1 && errno != EAGAIN) errExit("futex-FUTEX_WAIT"); }}atomic_compare_exchange_strongIt's true , This is an atomic comparison operation , It must be used here , As for why, please go to the series ( Atomic operation )| Who's protecting integrity , Note that it is understandingFutexThe key , It means
The value pointed to obj Atomic comparison with the value pointed toIn the header file <stdatomic.h> In the definition of _Bool atomic_compare_exchange_strong(volatile A * obj,C * expected,C desired);expected, If equal , Replace the former with the formerdesired( Perform read - modify - Write operation ). otherwise , Load the... That the actual value points toobjGet into*expected( Carry out load operation ). What do you mean ? A straightforward explanation :- If
futexp == 1beatomic_compare_exchange_strongReturn to true , At the same timefutexpThe value of the into0,1 Means you can hold the lock , Once held, it becomes 0, Others won't get it . So here is very second . And this happens in user mode . - If
futexp == 0atomic_compare_exchange_strongReturn to leave , Didn't get the lock , You need to fall into the kernel state to suspend the task and wait for the release of the lock
The last parameter is zerofutex(futexp, FUTEX_WAIT, 0, NULL, NULL, 0) // Execute a system call waiting for a lock0It means not staying in the kernel state and directly returning to the user state , The following will be explained in detail in the kernel state section .- If
childPid == 0Is the return of the child process . Keep applyingfutex1Releasefutex2if (childPid == 0) {// Subprocess return for (int j = 0; j < nloops; j++) { fwait(futex1); printf(" Subprocesses (%jd) %d\n", (intmax_t) getpid(), j); fpost(futex2); } exit(EXIT_SUCCESS);}- The return of the last parent process , Keep applying
futex2Releasefutex1// The parent process returns execution for (int j = 0; j < nloops; j++) { fwait(futex2); printf(" The parent process (%jd) %d\n", (intmax_t) getpid(), j); fpost(futex1);}wait(NULL);exit(EXIT_SUCCESS); - The initial value of the two locks is
*futex1 = 0; *futex2 = 1;, The parent process is infwait(futex2)So the parent processprintfWill be executed first ,*futex2 = 0;Lock two becomes not applicable , Release after printingfpost(futex1)Make the result*futex1 = 1;It means that the lock can be applied for , And the child process is waitingfwait(futex1), The result of alternating execution isThe parent process (283) 0 Subprocesses (284) 0 The parent process (283) 1 Subprocesses (284) 1 The parent process (283) 2 Subprocesses (284) 2
Baiwen said that the kernel | Grasp the main context
- Baiwen is equivalent to touching the muscle and organ system of the core , It makes people feel plump and three-dimensional , Because it starts directly from the annotation source code , In the process of annotation , Whenever you have something to learn, sort it out , Slowly formed the following articles . The content is based on the source code , Often take the life scene as an example, put as many kernel knowledge points as possible into a certain scene , With a sense of picture , Easy to understand and remember . It's important to say what others can understand ! A hundred blogs is by no means Baidu's dogmatic talk about a bunch of concepts that are being heckled , That's not interesting . I want to make the kernel more lifelike , I feel very kind .
- And the code needs to be constantly
debugequally , There will be many mistakes and omissions in the content of the article , Please forgive me , But it will be fixed over and over again , Continuous updating ,v**.xxRepresents the article serial number and the number of modifications , Finely crafted , simply , Strive to create quality content . - Bai Wenzai < Hongmeng research station | Open source in China | Blog Garden | 51cto | csdn | You know | Nuggets > Website publishing , The official account replied Baiwen Easy to read .
Press function module :
- Ins and outs >> General catalogue | Scheduling story | Memory master slave | Source code comments | Source structure | Static site | Reference documents |
- Basic tools >> Double linked list | Bitmap management | Stack mode | Timer | Atomic manipulation | time management |
- Load run >> ELF Format | ELF analysis | Static links | relocation | Process image |
- Process management >> Process management | Process concept | Fork | Special process | Process recycling | Signal production | Signal consumption | Shell edit | Shell analysis |
- Compiling and constructing >> Compile environment | The build process | Environment script | Building tools | gn application | ninja ninja |
- Process communication >> spinlocks | The mutex | Process communication | Semaphore | Event control | Message queue | Shared memory | Message encapsulation | Message mapping | User state lock |
- memory management >> Memory allocation | memory management | Memory assembly | Memory mapping | Memory rules | Physical memory |
- task management >> Clock task | Task scheduling | task management | Scheduling queues | Scheduling mechanism | Thread concept | Concurrent parallel | CPU | system call | Task switching |
- file system >> Document concept | file system | The index node | Mount Directory | The root file system | VFS | File handle | Pipeline files |
- Hardware architecture >> Assembly basis | Assembly pass parameters | Working mode | register | Abnormal connection | Compilation summary | Interrupt switching | The concept of interruption | Interrupt management |
- Device drivers >> Character device | Console | Remote login |
Million note source code | Buckle details everywhere
The purpose of million Chinese characters annotation core is to see its capillaries , Cell structure , It's like looking at the core with a magnifying glass . The kernel is not mysterious , It's easy to be addicted to finding answers in the source code with questions , You will find that many articles interpret some problems incorrectly , Or it's hard to justify it without being profound , You will slowly form your own new interpretation , And the new interpretation will encounter new problems , And so on , Roll forward , Holding a magnifying glass, I don't want to let go at all .
< gitee | github | coding | codechina > Four big yards push | Synchronize the official source code , Reply in official account One million Easy to read .
Focus on not getting lost | Code is life

边栏推荐
- Yolov5进阶之七目标追踪最新环境搭建
- Guidelines and principles of did
- Introduction to R language
- Book of quantitative trading - reading notes of the man who conquers the market
- Provincial election + noi Part VII computational geometry
- On several key issues of digital transformation
- MATLAB【函数求导】
- Koltin35, headline Android interview algorithm
- Use threejs simple Web3D effect
- 华为机试真题专栏订阅指引
猜你喜欢

Share 7 books I read in the first half of 2022

Introduction to R language

What is the material of 15CrMoR, mechanical properties and chemical analysis of 15CrMoR

Use threejs simple Web3D effect

01 numpy introduction

《微机原理》-绪论

Comprehensive experiment Li

公网集群对讲+GPS可视追踪|助力物流行业智能化管理调度

P4 installation bmv2 detailed tutorial
![Matlab [function derivation]](/img/ba/9fb9da8a458d0c74b29b21a17328fc.png)
Matlab [function derivation]
随机推荐
2022 ordinary scaffolder (special type of construction work) examination question bank and the latest analysis of ordinary scaffolder (special type of construction work)
Provincial election + noi part I dynamic planning DP
基础:3.opencv快速入门图像和视频
截图小妙招
Leetcode T40: 组合总和II
《单片机原理及应用》—定时器、串行通信和中断系统
Data analysis notes 11
CPU設計實戰-第四章實踐任務一簡單CPU參考設計調試
[untitled]
长安链同步节点配置与启动
TypeError: __ init__ () got an unexpected keyword argument ‘autocompletion‘
15Mo3 German standard steel plate 15Mo3 chemical composition 15Mo3 mechanical property analysis of Wuyang Steel Works
Leetcode t39: combined sum
Principle and application of single chip microcomputer - off chip development
MAVROS发送自定义话题消息给PX4
AES简单介绍
【无标题】
Intelligent water supply system solution
我想知道手机注册股票开户的流程?另外,手机开户安全么?
Codeworks round 803 (Div. 2) VP supplement
