Spinlock optimization method and electronic device
By creating a spin lock structure and a request node structure to form a waiting queue, and executing the code of other threads after the spin lock holder completes the critical section code, the performance bottleneck of spin locks in multi-core processors is solved, and cache consistency overhead, queue delay and multi-core scalability are optimized, thereby improving system performance.
Patent Information
- Application Number
- CN202511171852.1
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Filing Date
- 2025-08-20
- Publication Date
- 2025-10-24
- Estimated Expiration
- 2045-08-20
AI Technical Summary
Spin locks have performance bottlenecks in multi-core processors, including cache consistency overhead, wait queue delays, and scalability issues, especially in high-concurrency scenarios where performance degrades.
Create a spin lock structure, including a lock holder pointer and a request node structure, to form a waiting queue. After completing the critical section code, the spin lock holder traverses the waiting queue to execute the critical section code of other threads. Without releasing the lock immediately, the processor core corresponding to the spin lock holder executes the critical section code of other threads.
It significantly improves the performance of spin locks in multi-core processor environments, reduces cache consistency overhead and queue delay, and improves multi-core scalability and system efficiency.
Smart Images

Figure CN120670180B_ABST
Abstract
Description
TECHNICAL FIELD
[0001] The present application relates to the technical field of data processing, and in particular to a spin lock optimization method and an electronic device. BACKGROUND
[0002] In modern multi-core processor architecture, efficient contention access to shared resources has become an important technical bottleneck in the fields of operating systems, cloud computing platforms, and real-time control systems. To this end, spin locks, as a lightweight synchronization mechanism, are widely used, but their performance problems in high concurrency scenarios are increasingly prominent.
[0003] Classic spin lock technology is gradually evolving. The first generation of spin locks is a non-queue simple lock, and the representative scheme is the Test-and-Set lock, which directly operates the lock flag bit through an atomic instruction, and the thread spins and waits for the flag bit to become available.
[0004] The second generation of spin locks is a queue-based fair lock, and the representative scheme is the MCS lock (John Mellor-Crummey and Michael Scott), which constructs a one-way linked list queue through waiting threads, and each node contains a successor pointer and a waiting flag. That is, each waiting thread creates a node containing its own waiting state, and links the node to the end of the linked list. The thread determines whether to obtain the lock by constantly polling the state of its own node, and the predecessor node wakes up by modifying the waiting flag of the successor node.
[0005] However, the above non-queue spin lock competes for the same cache line flag bit of all threads, resulting in a serious bus storm, which is only suitable for dual-core or low contention scenarios. The lock holder of the MCS lock must strictly follow the order of "executing the critical section -> releasing the lock -> waking up the successor", and if the execution time of the critical section is long, the spin waiting time of the successor node will be unnecessarily extended. For example, in a real-time control system, this may cause task scheduling delay to exceed the standard, causing system stability problems. SUMMARY
[0006] The present application provides a spin lock optimization method and an electronic device to at least solve the performance bottleneck of spin locks in multi-core processors in related technologies, specifically including cache coherence overhead, waiting queue delay problems, and the problem that the scalability decreases with the increase in the number of cores. The present application breaks through the performance bottleneck of traditional spin locks in a multi-core environment, realizes all-around optimization of cache coherence overhead, queue delay, energy efficiency ratio, and multi-core scalability, and significantly improves the performance of spin locks in a multi-core processor environment.
[0007] The present application provides a spin lock optimization method, comprising:
[0008] creating and initializing a spin lock structure, wherein the spin lock structure includes a lock holder pointer;
[0009] When each thread acquires the spin lock, a corresponding request node structure is created to form a waiting queue, wherein the request node structure includes a node pointer, a critical section function pointer and a lock structure pointer, the node pointer is used to link the request node structure to the waiting queue, the critical section function pointer points to the critical section code that the thread needs to execute, and the lock structure pointer is used to point to the spin lock structure;
[0010] In the waiting queue, the spin lock holder in the plurality of threads is determined based on the lock holder pointer;
[0011] After the processor core corresponding to the spin lock holder executes the critical section code of the corresponding thread, the waiting queue is traversed, the critical section function pointer of each waiting node is read, and the critical section code in each request node structure is executed in turn on the current processor core based on the critical section function pointer, wherein after the processor core corresponding to the spin lock holder executes the critical section code of the corresponding thread, the spin lock is not immediately released, and the threads other than the thread corresponding to the processor core of the spin lock holder are not woken up by the corresponding thread itself to execute the critical section code.
[0012] The application further provides an electronic device, comprising a memory, a processor, and a program stored in the memory and executable on the processor, wherein the processor executes the program to implement the spin lock optimization method.
[0013] By the present application, a spinlock structure is created and initialized, wherein the spinlock structure comprises a lock holder pointer; when each thread acquires the spinlock, a corresponding request node structure is created to form a waiting queue, wherein the request node structure comprises a node pointer, a critical section function pointer and a lock structure pointer, the node pointer is used to link the request node structure to the waiting queue, the critical section function pointer points to the critical section code that the thread needs to execute, and the lock structure pointer is used to point to the spinlock structure; in the waiting queue, the spinlock holder in the plurality of threads is determined based on the lock holder pointer; after the processor core corresponding to the spinlock holder executes the critical section code of the corresponding thread, the waiting queue is traversed, the critical section function pointer of each waiting node is read, and the critical section code in each request node structure is executed in turn on the current processor core based on the critical section function pointer, wherein after the processor core corresponding to the spinlock holder executes the critical section code of the corresponding thread, the spinlock is not immediately released, and the threads other than the thread corresponding to the processor core corresponding to the spinlock holder are not woken up by the corresponding thread to execute the critical section code. Thus, the method breaks through the performance bottleneck of the traditional spinlock in a multi-core environment, realizes all-round optimization of cache consistency overhead, queue delay, energy efficiency ratio and multi-core scalability, and significantly improves the performance of the spinlock in a multi-core processor environment. BRIEF DESCRIPTION OF DRAWINGS
[0014] In order to more clearly illustrate the embodiments of the present application, the drawings needed in the embodiments will be briefly introduced. Obviously, the drawings in the following description are only some embodiments of the present application, and other drawings can be obtained by those skilled in the art without creative labor.
[0015] Figure 1 Flowchart of the spinlock optimization method according to an embodiment of the present application;
[0016] Figure 2 Flowchart of the spinlock optimization method according to one specific example of the present application;
[0017] Figure 3 Block schematic diagram of the electronic device according to an embodiment of the present application.
[0018] Reference numerals: 200-electronic device, 210-memory, 220-processor. DETAILED DESCRIPTION
[0019] Embodiments of the present application are described below in detail with reference to the accompanying drawings, wherein the same or similar components are denoted by the same or similar reference numerals throughout the drawings. The embodiments described below are exemplary and are intended to explain the present application, and should not be understood as limiting the present application.
[0020] The spin lock optimization method and electronic device according to embodiments of the present application are described below with reference to the accompanying drawings.
[0021] Figure 1 A flowchart of the spin lock optimization method according to embodiments of the present application.
[0022] As shown in Figure 1 the spin lock optimization method according to embodiments of the present application can include the following steps:
[0023] S1, creating and initializing a spin lock structure, wherein the spin lock structure includes a lock holder pointer.
[0024] S2, when each thread acquires the spin lock, creating a corresponding request node structure to form a waiting queue, wherein the request node structure includes a node pointer, a critical section function pointer, and a lock structure pointer, the node pointer is used to link the request node structure to the waiting queue, the critical section function pointer points to the critical section code that the thread needs to execute, and the lock structure pointer is used to point to the spin lock structure.
[0025] S3, in the waiting queue, determining the spin lock holder in the plurality of threads based on the lock holder pointer.
[0026] S4, after the processor core corresponding to the spin lock holder executes the critical section code of the corresponding thread, traversing the waiting queue, reading the critical section function pointer of each waiting node, and executing the critical section code in each request node structure based on the critical section function pointer on the current processor core in turn, wherein after the processor core corresponding to the spin lock holder executes the critical section code of the corresponding thread, the spin lock is not immediately released, and the threads other than the thread corresponding to the processor core corresponding to the spin lock holder do not execute the critical section code after being woken up by the corresponding thread itself.
[0027] Specifically, first, a spinlock structure is created and initialized, where the spinlock structure can include a lock holder pointer. That is, the lock holder pointer points to the thread that currently holds the spinlock. If the pointer is empty, it indicates that the lock is currently not held by any thread, and if it points to a certain thread, it indicates that the thread is the holder of the lock. For example, an instance of the spinlock structure can be created by dynamic memory allocation. For example, a memory allocation mechanism is used to allocate sufficient memory space to store the members of the spinlock structure, or the instance of the spinlock structure can be statically allocated in the global or local area of the program. In this way, the memory is allocated when the program starts, and there is no need for runtime dynamic allocation. Initializing the lock holder pointer is to set the lock holder pointer to a null value, indicating that the spinlock is not held by any thread after initialization, and any thread can determine that the lock is available by checking that the pointer is empty when it first attempts to acquire the lock. Thus, the spinlock structure is correctly initialized and ready for subsequent threads to acquire the lock and form a waiting queue.
[0028] In the implementation of the spinlock, each thread needs to create a request node structure when attempting to acquire the lock. This structure can record the thread's request information, including the thread's critical section code and the thread's identification. And form a waiting queue, that is, link multiple request nodes through node pointers to form a waiting queue. And associate the lock structure, that is, associate the request node with the spinlock structure through the lock structure pointer, to ensure that the thread can correctly interact with the lock. The request node structure contains the following three main members: the node pointer, which is used to link the request node to the waiting queue. When creating the request node, the node pointer is usually initialized to NULL, indicating that the node does not point to the next node at the moment. When the thread adds the request node to the waiting queue, it will point the node pointer of the node to the tail node of the queue. The critical section function pointer is used to point to the critical section code that the thread needs to execute. When creating the request node, the thread will initialize the critical section function pointer to point to the critical section code it needs to execute. When the lock holder traverses the waiting queue and executes the critical section code, it will call the function pointed to by the pointer. The lock structure pointer is used to point to the spinlock structure, ensuring the association of the request node with the lock structure. When creating the request node, the thread will initialize the lock structure pointer to point to the global spinlock structure. Through the lock structure pointer, the request node can access the state information of the lock, such as the lock holder pointer and the head pointer of the waiting queue.
[0029] In creating the request node structure, sufficient memory space can be allocated for the request node structure. The thread needs to allocate a block of memory large enough to store the three members of the request node structure (node pointer, critical section function pointer, and lock structure pointer). After the allocation is complete, the thread obtains an uninitialized request node structure instance. The node pointer of the request node is initialized to NULL, indicating that the node currently does not point to the next node. The critical section function pointer of the request node is initialized to point to the critical section code that the thread needs to execute. The lock structure pointer of the request node is initialized to point to the global spin lock structure. After creating and initializing the request node structure, the thread needs to add the node to the waiting queue. For example, the thread checks the lock status through the lock holder pointer. If the lock holder pointer is empty, it indicates that the lock is not held by any thread, and the thread can attempt to acquire the lock directly. If the lock holder pointer is not empty, it indicates that the lock has been held by other threads, and the thread needs to enter the waiting queue. If the waiting queue is empty, the thread sets the request node as the head node of the waiting queue. If the waiting queue is not empty, the thread links the request node to the tail of the queue. This mechanism enables the spin lock to efficiently manage the requests of multiple threads, ensuring that the waiting queue of threads can be correctly processed when the lock is released.
[0030] In the waiting queue, the spin lock holder among multiple threads can be determined according to the lock holder pointer. That is, the lock holder pointer is an important member of the spin lock structure, used to identify the thread currently holding the lock. Its functions include: quickly determining the status of the lock: by checking whether the lock holder pointer is empty, the status of the lock can be quickly determined. Determine the lock holder: if the lock holder pointer is not empty, the thread it points to is the current lock holder. For example, the spin lock holder can be determined through a pre-established correspondence relationship, such as pre-determining the relationship between the lock holder pointer and the spin lock holder in multiple threads. After the lock holder pointer is determined, the corresponding relationship can be directly called to obtain the spin lock holder.
[0031] After determining the spin lock holder, the critical section code of the corresponding thread can be first executed by the processor core corresponding to the spin lock holder, and after the processor core corresponding to the spin lock holder completes the execution of the critical section code of the corresponding thread, the waiting queue can be traversed, and the critical section function pointer of each waiting node can be read, and the critical section code in each request node structure can be executed in turn on the current processor core based on the critical section function pointer. The critical section code refers to a code segment that needs to be synchronized in a multi-threaded environment. These code segments usually access shared resources (such as global variables, files, devices, etc.), so it is necessary to ensure that only one thread can execute these codes at the same time. When the lock holder completes the execution of its own critical section code, it traverses the waiting queue, and when traversing the waiting queue, the spin lock holder reads the critical section function pointer of each waiting node, which ensures that the lock holder knows the entry point of the critical section code of each thread. The spin lock holder executes the critical section code in each request node structure in turn on the current processor core, which is completed by calling the critical section function pointer of each thread. By directly executing the critical section code of other threads on the current processor core, the overhead of thread switching and context switching is avoided, and the performance of the system is significantly improved, especially in high-concurrency scenarios. That is, the lock holder reads the critical section function pointer of each request node and executes the function on the current processor core, which means that the lock holder will execute the critical section code of the waiting thread instead of the waiting thread.
[0032] It should be noted that after executing the critical section code of the current thread, the spin lock holder does not immediately release the lock, but continues to hold the lock to execute the critical section code of other threads in the waiting queue. This design allows the lock holder to batch process the critical section code of multiple threads on the current processor core, reducing the overhead of frequent release and reacquisition of the lock. When the spin lock holder executes the critical section code of other threads in the waiting queue, these threads will not be awakened and will try to acquire the lock, which avoids the repeated execution of the critical section code by the threads and ensures that the critical section code of each thread is executed only once. In this way, the overhead of thread awakening and context switching can be significantly reduced, and the overall efficiency of the system can be improved.
[0033] For example, assume that threads A, B, and C try to acquire the lock in turn and enter the waiting queue. After the lock holder thread D completes the execution of its own critical section code, it starts processing the waiting queue, i.e., thread D traverses from the head node of the waiting queue. That is, thread D reads the critical section function pointer in the request node of thread A, determines the corresponding critical section code through the critical section function pointer, and after the execution is completed, it can continue to execute the critical section code corresponding to threads B and C. Thread D checks whether to process back to the starting node, and if so, terminates the traversal.
[0034] Thus, by the lock holder actively executing the critical section code, the context switching between threads is avoided, the efficiency of the system is improved, the access of multiple threads to the same cache line is reduced, the overhead of cache inconsistency is reduced, the release efficiency of the lock is significantly improved through batch processing of the requests in the waiting queue, and the throughput is significantly improved, especially in a high contention scenario.
[0035] According to one embodiment of the present application, when each thread acquires the spin lock, a corresponding request node structure is created to form a waiting queue, including: in the case that there is a thread corresponding to the first acquired spin lock among the multiple threads, and the lock holder pointer is a null pointer, the lock holder pointer is set to the identifier of the current thread based on an atomic exchange operation, and the request node structure corresponding to the thread is linked as the head of the waiting queue; in the case that the lock holder pointer is not a null pointer, the corresponding request node structure is sequentially linked as the tail of the waiting queue based on the node pointer and the order in which each thread acquires the spin lock, to form the waiting queue.
[0036] Specifically, when each thread acquires the spin lock, a corresponding request node structure is created to form a waiting queue, first, among the multiple threads, it is judged whether there is a thread corresponding to the first acquired spin lock, and the lock holder pointer is judged, in the case that the lock holder pointer is a null pointer, the lock holder pointer can be set to the identifier of the current thread based on an atomic exchange operation, and the request node structure corresponding to the thread is linked as the head of the waiting queue. That is, when the lock holder pointer is empty, it means that the lock is not held by any thread. At this time, the thread can try to acquire the lock. That is, the thread tries to set the lock holder pointer to its own thread identifier through an atomic exchange operation, if the atomic operation is successful, the thread successfully acquires the lock and becomes the holder of the lock. The thread creates a request node structure and initializes its members. Since the thread is the first thread to acquire the lock, its request node structure is set as the head of the waiting queue.
[0037] When the lock holder pointer is not empty, it means that the lock has been held by other threads. At this time, the thread needs to enter the waiting queue. That is, the thread creates a request node structure and initializes its members. And the thread gets the head pointer of the linked list in the lock structure, finds the tail node of the waiting queue, the thread sets the node pointer of the current request node to NULL, and the thread sets the node pointer of the tail node to the current request node, thereby linking the current request node to the tail of the waiting queue.
[0038] Assuming threads A, B, and C attempt to acquire the lock in sequence, thread A attempts to acquire the lock: the lock holder pointer is null, thread A sets the lock holder pointer to its thread identity through an atomic operation. Thread A creates a request node structure and sets it as the head of the wait queue. The list head pointer in the lock structure points to thread A's request node. Thread B attempts to acquire the lock: the lock holder pointer is not null (points to thread A), thread B enters the wait queue. Thread B creates a request node structure and links it to the tail of the wait queue. The node pointer of thread A's request node points to thread B's request node. Thread C attempts to acquire the lock: the lock holder pointer is not null (points to thread A), thread C enters the wait queue. Thread C creates a request node structure and links it to the tail of the wait queue. The node pointer of thread B's request node points to thread C's request node.
[0039] It should be noted that the atomic exchange operation is the key to ensuring thread-safe acquisition of the lock, which prevents multiple threads from simultaneously setting the lock holder pointer to their own identity, thereby avoiding data races. The thread identity must be unique to ensure that each thread can be correctly distinguished, and this identity can take various forms depending on the operating system and programming environment. That is, the thread identifier is a value provided by the operating system or thread library to uniquely identify a thread. In different programming environments, the type and representation of the thread identifier may be different.
[0040] Thus, through the above steps, the wait queue can be effectively managed when threads acquire the spin lock. The request node of the first thread to acquire the lock becomes the head of the queue, and subsequent threads link the request node to the tail of the queue in sequence. This process ensures that threads wait for the release of the lock in order, improving the fairness and efficiency of the lock.
[0041] According to an embodiment of the present application, determining a spin lock holder among a plurality of threads based on a lock holder pointer includes: detecting whether the lock holder pointer is a null pointer; and in the case that the lock holder pointer is not a null pointer, determining the current thread as the spin lock holder.
[0042] Specifically, when determining a spin lock holder among a plurality of threads based on a lock holder pointer, it is detected whether the lock holder pointer is a null pointer, and in the case that the lock holder pointer is not a null pointer, the current thread can be determined as the spin lock holder. That is, by checking whether the lock holder pointer is null, it can be quickly determined whether the lock has been held by other threads. If the lock holder pointer is null, it indicates that the lock has not been held by any thread, and the current thread can attempt to acquire the lock. If the lock holder pointer is not null, it indicates that the lock has been held by other threads, and the current thread needs to enter the wait queue.
[0043] Thus, through the above steps, the thread can effectively manage the lock holder state when trying to acquire the spin lock. By detecting whether the lock holder pointer is empty, the thread can quickly determine the state of the lock and decide whether to try to acquire the lock or enter the waiting queue. Through atomic operations, the thread can safely set the lock holder pointer, ensuring that the transfer of the lock is thread-safe. This process not only improves the efficiency of the lock, but also ensures the fairness of the system and the safety of the thread.
[0044] According to an embodiment of the present application, the request node structure further includes an atomic waiting flag bit. After sequentially linking the corresponding request node structure as the tail of the waiting queue based on the node pointer and the order in which each thread acquires the spin lock, the spin lock optimization method further includes setting the atomic waiting flag bit to a preset value to enter the spin waiting state. The preset value can be determined according to actual conditions.
[0045] Specifically, the request node structure can further include an atomic waiting flag bit, which is used to mark whether the thread is in a waiting state. That is, after sequentially linking the request node structure as the tail of the waiting queue based on the node pointer and the order in which each thread acquires the lock, the atomic waiting flag bit can also be set to a preset value to enter the spin waiting state.
[0046] That is, the thread creates a request node structure and initializes its members, sequentially links the request node structure to the tail of the waiting queue based on the node pointer and the order in which the thread acquires the lock, and sets the atomic waiting flag bit to a preset value (such as true or 1) to indicate that the thread is in a waiting state. That is, the thread will not be suspended when waiting for the lock to be released, but will use spin waiting to reduce the occupation of the central processing unit, which can significantly improve the performance of the system in a high-concurrency scenario. Thus, through spin waiting, the overhead of thread switching is reduced, ensuring the fairness of the lock and the high-concurrency performance of the system.
[0047] According to an embodiment of the present application, the spin lock optimization method further includes: after the spin lock holder executes the critical section code corresponding to each thread, the preset value of the atomic waiting flag bit is cleared to zero; and after clearing the atomic waiting flag bit, recording the corresponding operation log, wherein the operation log includes at least one of a thread identity and a clearing time.
[0048] Specifically, after the spin lock holder executes the critical section code corresponding to each thread, the preset value of the atomic waiting flag bit is cleared to zero. This process is an important part of the spin lock mechanism, which is used to ensure that the thread can correctly exit from the waiting state and continue execution.
[0049] The atomic waiting flag is a flag used to mark whether a thread is in a waiting state. When a thread enters a waiting queue, the flag is set to a preset value (e.g., true or 1), indicating that the thread is waiting for the release of the lock. After the lock holder completes the execution of the critical section code, the flag needs to be cleared to inform the waiting thread that it can continue to execute. For example, after the lock holder thread completes the execution of its critical section code, it prepares to release the lock. The lock holder starts to traverse the waiting queue to find the first node in the queue. The lock holder clears the atomic waiting flag of the first node to zero through an atomic operation. This step ensures that the clearing of the flag is atomic, avoiding race conditions caused by multiple threads modifying the flag at the same time. After the flag is cleared, the lock holder wakes up the corresponding thread. The woken-up thread checks its atomic waiting flag and finds that the flag has been cleared, so it exits the spin waiting state. When the atomic waiting flag of a thread is cleared, the thread exits the spin waiting state. The thread checks the state of the flag. If the flag is zero, it means that the lock has been released, and the thread can continue to execute. This process reduces the waiting time of the thread and improves the efficiency of the system.
[0050] After the atomic waiting flag is cleared, the relevant operation logs can be recorded, including at least one of a thread identity and a clearing time. These log information is very helpful for subsequent troubleshooting and performance analysis. The thread identity helps to determine which thread performed the operation, facilitating the tracing of the source of the problem, and the clearing time helps to determine the timing relationship of the operation, facilitating the analysis of the time point at which the problem occurred.
[0051] Therefore, after completing the execution of the critical section code, the spin lock holder can efficiently clear the atomic waiting flag, wake up the waiting thread, ensure that the thread can correctly exit the waiting state and continue to execute, and the log information is very helpful for subsequent troubleshooting and performance analysis.
[0052] According to an embodiment of the present application, the spin lock optimization method further comprises: setting the lock holder pointer to a null pointer based on an atomic operation after the spin lock holder completes the execution of the critical section code of all threads; and recording the corresponding operation log after setting the lock holder pointer to the null pointer, wherein the operation log includes at least one of a thread identity and an operation time.
[0053] Specifically, in the optimization method of spinlock, setting the lock owner pointer to NULL is a key step after the lock owner finishes the critical section code of all threads. This operation ensures the correct release of the lock and allows other threads to acquire the lock. That is, the lock owner pointer (owner) is an important member in the spinlock structure, which identifies the thread that currently holds the lock. Its functions include: quickly judging the state of the lock: by checking whether the lock owner pointer is NULL, it can quickly determine whether the lock has been held by other threads; determining the owner of the lock: if the lock owner pointer is not NULL, the thread it points to is the current owner of the lock.
[0054] In the optimization method of spinlock, the lock owner not only executes its own critical section code, but also actively executes the critical section code of other threads in the waiting queue. That is, the lock owner starts from the head of the waiting queue and processes each request node in turn. The lock owner reads the critical section function pointer of each request node and executes the function on the current processor core. After executing the critical section code of each request node, the lock owner atomically clears the waiting flag of the node and wakes up the corresponding thread. When the lock owner finishes the critical section code of all threads, it needs to set the lock owner pointer to NULL. That is, after completing its own critical section code, the lock owner starts to traverse the waiting queue and processes each request node in turn to ensure that the critical section code of all waiting threads is executed. After completing all tasks in the waiting queue, the lock owner sets the lock owner pointer to NULL, indicating that the lock has been released and other threads can try to acquire the lock. When subsequent other threads try to acquire the lock, they will find that the lock owner pointer is NULL, thus having the opportunity to set the lock owner pointer to their own thread identifier through atomic operation and acquire the lock. Among them, the lock owner pointer can be set to NULL using atomic operation, indicating that the lock is currently not held by any thread. Atomic operation can ensure the correctness in a multi-threaded environment, that is, atomic operation can ensure that this setting operation will not be interrupted by other threads, thus avoiding race conditions.
[0055] In addition, after setting the lock owner pointer to NULL, relevant operation logs can be recorded, such as recording the unique identifier of the current thread, which helps to analyze which thread performed the operation later, and recording the specific timestamp of setting the lock owner pointer to NULL, which helps to analyze the timing relationship of the operation, especially in high-concurrency scenarios.
[0056] Assuming that thread A is the current lock holder, thread B and thread C are in the waiting queue, thread A finishes its own critical section code, and prepares to release the lock. Thread A starts from the head of the waiting queue and processes each request node in turn. Thread A reads the critical section function pointer in the request node of thread B, and executes the function. Thread A atomically clears the waiting flag of thread B, and wakes up thread B. Thread A reads the critical section function pointer in the request node of thread C, and executes the function. Thread A atomically clears the waiting flag of thread C, and wakes up thread C. After completing all the tasks in the waiting queue, thread A sets the lock holder pointer to a null pointer. This operation is completed through an atomic operation, which ensures that only one thread can successfully set the lock holder pointer at the same time. After being woken up, thread B and thread C find that the lock holder pointer is empty, and can try to set the lock holder pointer to its own thread identifier through an atomic operation. If thread B successfully sets the lock holder pointer, thread B becomes the new lock holder. If thread C successfully sets the lock holder pointer, thread C becomes the new lock holder.
[0057] Through the above steps, by using an atomic operation to set the lock holder pointer to a null pointer after the spin lock holder executes all the critical section codes corresponding to the threads, and recording the relevant operation log, the correct release of the lock can be ensured, and other threads can be prevented from mistakenly considering that the lock is still occupied. This mechanism not only improves the reliability of the lock, but also ensures the consistency of the system state, and improves the overall performance and stability of the system.
[0058] According to an embodiment of the present application, the spin lock structure further includes a linked list head pointer, the linked list head pointer pointing to the first node of the waiting queue. Initializing the spin lock structure includes: setting the lock holder pointer to a null pointer, and setting the linked list head pointer to a null pointer.
[0059] In particular, in the implementation of the spin lock, the spin lock structure includes a lock holder pointer and a linked list head pointer in addition to the lock holder pointer. The linked list head pointer points to the first node of the waiting queue, which is used to manage threads waiting to acquire the lock. When initializing the spin lock structure, the lock holder pointer can be set to null, and the linked list head pointer can be set to null. Thus, when a thread attempts to acquire the lock, it checks whether the lock holder pointer is null. If it is null, the thread can attempt to set the lock holder pointer to its own thread identifier through an atomic operation, thereby acquiring the lock. If the lock holder pointer is not null, the thread considers that the lock is already held by another thread, and thus enters the waiting queue. Therefore, by setting the lock holder pointer to null during initialization, the initial state of the lock is ensured to be available, avoiding the misjudgment of the lock state by the thread. When the lock is released, the lock holder needs to set the lock holder pointer to null, indicating that the lock has been released. When the lock holder completes the execution of the critical section code, it sets the lock holder pointer to null. Other threads, when attempting to acquire the lock, will find that the lock holder pointer is null, thereby having the opportunity to acquire the lock through an atomic operation. By setting the lock holder pointer to null, the release of the lock is ensured to be fair, and other threads can attempt to acquire the lock in order.
[0060] When initializing the spin lock, the linked list head pointer is set to null, indicating that the waiting queue is currently empty. When the linked list head pointer is null, it indicates that no threads are waiting to acquire the lock. Therefore, the first thread attempting to acquire the lock can directly acquire the lock without entering the waiting queue. If the linked list head pointer is not null, the thread considers that there are other threads waiting to acquire the lock, and thus enters the waiting queue. Therefore, by setting the linked list head pointer to null during initialization, the initial state of the waiting queue is ensured to be empty, avoiding unnecessary waiting.
[0061] Thus, by initializing the lock holder pointer to null, the context switch of threads when attempting to acquire the lock is reduced. By initializing the linked list head pointer to null, the management of the waiting queue is ensured to be efficient and orderly, improving the concurrency performance of the system.
[0062] In addition, in a multi-threaded environment, some threads can be more important than others and need to acquire the lock with priority. By introducing a priority scheduling mechanism, it can be determined which thread can acquire the lock with priority according to the priority of the thread. That is, a priority queue is introduced in the waiting queue, and high-priority threads are processed first. For example, in the waiting queue, the priority of a thread is dynamically promoted according to the waiting time of the thread, so as to avoid thread starvation. When a high-priority thread is waiting for a lock held by a low-priority thread, the priority of the low-priority thread is temporarily promoted to speed up the release of the lock. In addition, in the traditional implementation of the spin lock, the thread will spin continuously when waiting for the lock to be released, which can cause waste of central processing unit resources. By introducing a dynamic adjustment of the spin waiting strategy, the number of spins or the time of spin can be dynamically adjusted according to the system load and the competition of the lock, so as to reduce the unnecessary occupation of the central processing unit. By setting a spin count threshold, the thread enters a sleep state when the threshold is exceeded, reducing the occupation of the central processing unit, or by setting a spin time threshold, the thread enters a sleep state when the threshold is exceeded. Thus, the spin strategy is dynamically adjusted according to the system load, and the number of spins or the time of spin is reduced when the system load is high, which can further improve the performance and efficiency.
[0063] According to an embodiment of the present application, in determining the spin lock holder in the plurality of threads, the spin lock optimization method further comprises: comparing the priority of the current thread with the priority of other waiting threads, or determining the thread that acquires the spin lock earliest in the plurality of threads; in the case that the priority of the current thread is higher than the priority of other waiting threads and the lock holder pointer is not empty, determining the current thread as the spin lock holder, or in the case that the thread that acquires the spin lock earliest and the lock holder pointer is not empty, determining the current thread as the spin lock holder.
[0064] Specifically, in determining the spin lock holder in the plurality of threads, it can also be determined which thread should acquire the lock by comparing the priority of the current thread with the priority of other waiting threads. This mechanism is usually used to ensure that high-priority threads can acquire the lock faster, thereby improving the responsiveness and fairness of the system. That is, each thread has a priority, which is usually set by the operating system or the application. The priority can be an integer value, and the higher the value, the higher the priority. First, traverse the waiting queue to obtain the priority of each waiting thread, and compare the priority of the current thread with the priority of other waiting threads. If the priority of the current thread is higher than the priority of all other waiting threads, the current thread can acquire the lock with priority. If the priority of the current thread is the highest and the lock holder pointer is not empty (indicating that the lock is currently not held by other threads), the current thread is determined as the lock holder.
[0065] Alternatively, the thread that first attempts to acquire the spinlock among multiple threads can also be determined. This approach is commonly used to implement a fair lock, ensuring that threads acquire the lock in the order they requested it. When a thread attempts to acquire the lock, a timestamp of the thread's attempt to acquire the lock is recorded, the wait queue is traversed, and the attempt timestamps of each thread are compared to determine the thread that first attempted to acquire the lock. If the current thread is the one that first attempted to acquire the lock and the lock holder pointer is not null (indicating that the lock is currently not held by another thread), the current thread is determined as the lock holder.
[0066] In this way, by comparing priorities, it ensures that high-priority threads can acquire the lock faster, improving the responsiveness and fairness of the system, which is suitable for real-time systems and scenarios that require priority processing of critical tasks. By determining the thread that first attempts to acquire the lock, it ensures that threads acquire the lock in the order they requested it, avoiding thread starvation, which is suitable for scenarios that require fair scheduling, such as multi-threaded servers and concurrent systems. In summary, by comparing the priority of the current thread with the priority of other waiting threads or determining the thread that first attempts to acquire the spinlock among multiple threads, the appropriate thread can be effectively selected as the lock holder. This mechanism not only improves the fairness of lock allocation, but also ensures that high-priority tasks can be executed in a timely manner, improving the overall performance and responsiveness of the system.
[0067] According to an embodiment of the present application, the spinlock optimization method further comprises: during the acquisition and release process of the spinlock, detecting whether the spinlock is in an abnormal state, wherein the abnormal state includes at least one of the spinlock being occupied and the spinlock being damaged; switching the spinlock to a backup spinlock and synchronizing the state information of the spinlock to the backup spinlock.
[0068] Specifically, during the acquisition and release process of the spinlock, it is necessary to detect whether the lock is in an abnormal state. The abnormal state includes but is not limited to the spinlock being occupied and the spinlock being damaged. Among them, the spinlock being occupied means that a thread holds the lock for too long, or the lock is held by a thread that should not hold it. A reasonable timeout can be set, and if a thread holds the lock for more than this timeout, it is considered that the lock may be occupied, and by checking the thread state of the lock holder, if the holder thread has ended or is in an abnormal state, it is considered that the lock is occupied. The spinlock being damaged means that the internal state of the lock is inconsistent, such as the lock holder pointer being invalid, the lock flag being incorrect, etc. Check if the lock holder pointer is null or points to a valid thread, and check if the lock flag is in a valid state, such as whether it is initialized, whether it is in an error state, etc.
[0069] If an abnormal state of the spinlock is detected, the lock needs to be switched to a backup spinlock. The backup spinlock is a pre-prepared lock that takes over the management of the lock when the main lock is abnormal. For example, during the acquisition and release process of the spinlock, when it is detected that the lock is in an abnormal state, the lock pointer of the current thread can be switched from the main lock to the backup lock, and the state information of the main lock is synchronized to the backup lock, ensuring that the backup lock can correctly take over the management of the lock. Among them, the state information can include a pointer to the thread currently holding the lock, used to identify which thread currently holds the lock, that is, the holder pointer value of the main lock is copied to the holder pointer of the backup lock. It can also include a waiting queue, that is, a data structure (usually a linked list or queue) containing the request nodes of all threads waiting for the lock, and all nodes in the waiting queue of the main lock and their states (such as thread identity, atomic waiting flag, etc.) are copied to the waiting queue of the backup lock. It can also include the flag of the lock, which is used to represent the flag of various states of the lock, such as whether it is initialized, whether it is in an error state, etc., that is, the flag value of the main lock is copied to the flag of the backup lock. In this way, the acquisition or release operation of the lock can continue to be performed on the backup lock. If the backup lock also appears abnormal, it can be further switched to another backup lock, or other recovery measures can be taken.
[0070] In this way, by detecting abnormal states during the acquisition and release process of the spinlock, and switching the lock to a backup spinlock and synchronizing the state information when an abnormality is detected, the reliability of the lock and the stability of the system can be significantly improved. This mechanism not only ensures the correct management of the lock, but also reduces system failures caused by lock abnormalities, and improves the overall performance and reliability of the system.
[0071] The method of the present application will be described below in conjunction with Figure 2 .
[0072] As a specific example, the spinlock optimization method of the present application can include the following steps:
[0073] S101, create and initialize a spinlock structure.
[0074] S102, in a plurality of threads, whether there is a first thread that acquires the spinlock corresponding to the lock, and whether the lock holder pointer is a null pointer. If so, execute step S103; if not, execute step S101.
[0075] S103, set the lock holder pointer to the identity of the current thread based on the atomic exchange operation, and set the request node structure corresponding to the thread as the head of the waiting queue, and determine the current thread as the spinlock holder.
[0076] S104, determine whether the lock holder pointer is not a null pointer. If so, execute step S105; if not, execute step S101.
[0077] S105, based on the node pointer and the order in which each thread acquires the spin lock, sequentially link the corresponding request node structure to the head of the waiting queue to form the waiting queue, and set the atomic waiting flag bit to a preset value to enter a spin waiting state.
[0078] S106, after the processor core corresponding to the spin lock holder executes the critical section code of the corresponding thread, traverse the waiting queue, read the critical section function pointer of each waiting node, and execute the critical section code in each request node structure on the current processor core based on the critical section function pointer, and clear the preset value of the atomic waiting flag bit to zero.
[0079] S017, after the spin lock holder executes the critical section code of all threads, set the lock holder pointer to a null pointer.
[0080] In summary, according to the spin lock optimization method of the embodiment of the application, a spin lock structure is created and initialized, wherein the spin lock structure includes a lock holder pointer; when each thread acquires the spin lock, a corresponding request node structure is created to form a waiting queue, wherein the request node structure includes a node pointer, a critical section function pointer, and a lock structure pointer, the node pointer is used to link the request node structure to the waiting queue, the critical section function pointer points to the critical section code that the thread needs to execute, and the lock structure pointer is used to point to the spin lock structure; in the waiting queue, the spin lock holder in the plurality of threads is determined based on the lock holder pointer; after the processor core corresponding to the spin lock holder executes the critical section code of the corresponding thread, the waiting queue is traversed, the critical section function pointer of each waiting node is read, and the critical section code in each request node structure is executed on the current processor core based on the critical section function pointer, wherein after the processor core corresponding to the spin lock holder executes the critical section code of the corresponding thread, the spin lock is not immediately released, and the threads other than the thread corresponding to the processor core of the spin lock holder are not woken up by the corresponding thread itself to execute the critical section code. Thus, this method breaks through the performance bottleneck of the traditional spin lock in a multi-core environment, realizes all-round optimization of cache consistency overhead, queue delay, energy efficiency ratio, and multi-core scalability, and significantly improves the performance of the spin lock in a multi-core processor environment.
[0081] Corresponding to the above embodiment, the application also provides an electronic device.
[0082] As shown in Figure 3 The electronic device 200 of the embodiment of the application can include a memory 210, a processor 220, and a program stored on the memory 210 and executable on the processor 220, and when the processor 220 executes the program, the spin lock optimization method described above is implemented.
[0083] According to the electronic device of the embodiments of the present application, by performing the spin lock optimization method described above, the performance bottleneck of the traditional spin lock in the multi-core environment is broken through, and the cache consistency overhead, queue delay, energy efficiency ratio and multi-core expansibility are comprehensively optimized, and the performance of the spin lock in the multi-core processor environment is significantly improved.
[0084] It should be noted that the logic and / or steps represented in the flowcharts or otherwise described herein, for example, can be considered as a list of ordered steps for implementing logical functions, and can be embodied in any computer-readable medium for use by an instruction execution system, apparatus, or device, such as a computer-based system, a system including a processor, or other system that can fetch the instructions from the instruction execution system, apparatus, or device and execute the instructions, or in conjunction with these instructions execution systems, apparatuses, or devices. For the purpose of this specification, "computer-readable medium" can be any device that can contain, store, communicate, propagate, or transport a program for use by an instruction execution system, apparatus, or device, or in conjunction with these instruction execution systems, apparatuses, or devices. More specific examples (non-exhaustive list) of computer-readable medium include the following: electrical connections having one or more wires (electronic devices), portable computer disks (magnetic devices), random access memories (RAM), read-only memories (ROM), erasable programmable read-only memories (EPROM or flash memories), fiber optic devices, and portable compact disk read-only memories (CD-ROMs). In addition, the computer-readable medium can even be paper or other suitable medium on which the program can be printed, as the program can be electronically obtained, for example, by optical scanning of the paper or other medium, followed by electronic conversion, interpretation, or processing, if necessary, in other suitable ways, and then stored in a computer memory.
[0085] It should be understood that parts of the present application can be realized in hardware, software, firmware, or a combination thereof. In the above-described embodiments, a plurality of steps or methods can be realized by software or firmware stored in a memory and executed by a suitable instruction execution system. For example, if realized in hardware, and as in another embodiment, any one or a combination of the following technologies known in the art can be used: discrete logic circuit with logic gate circuit for implementing logical functions on data signals, application specific integrated circuit with suitable combination logic gate circuit, programmable gate array (PGA), field programmable gate array (FPGA), etc.
[0086] In the description of the specification, the description of the terms "one embodiment", "some embodiments", "an example", "a specific example", or "some examples" etc. means that the specific features, structures, materials or characteristics described in connection with the embodiment or example are included in at least one embodiment or example of the present application. In the description of the specification, the illustrative description of the above terms does not necessarily mean the same embodiment or example. Moreover, the specific features, structures, materials or characteristics described can be combined in any one or more embodiments or examples in a suitable manner.
[0087] In addition, the terms "first", "second" are only for descriptive purposes, and cannot be understood as indicating or implying relative importance or implicitly indicating the number of the technical features indicated. Therefore, the features defined with "first", "second" can explicitly or implicitly include at least one of the features. In the description of the present application, the meaning of "a plurality of" is at least two, for example, two, three, etc., unless otherwise explicitly specified and limited.
[0088] In the present application, unless otherwise explicitly specified and limited, the terms "mounting", "connection", "connection", "fixing" and other terms should be understood in a broad sense, for example, can be fixedly connected, can also be detachably connected, or integrated; can be mechanically connected, can also be electrically connected; can be directly connected, can also be indirectly connected through an intermediate medium, can be the internal communication of two elements or the interaction relationship between two elements, unless otherwise explicitly limited. For those skilled in the art, the specific meaning of the above terms in the present application can be understood according to the specific circumstances.
[0089] Although the embodiments of the present application have been shown and described above, it can be understood that the above embodiments are exemplary and cannot be understood as limiting the present application, and those skilled in the art can make changes, modifications, replacements and variations to the above embodiments within the scope of the present application.
Claims
1. A spinlock optimization method, comprising: The method comprises: creating and initializing a spin lock structure, wherein the spin lock structure comprises a lock holder pointer; when each thread acquires the spin lock, creating a corresponding request node structure to form a waiting queue, wherein the request node structure comprises a node pointer, a critical section function pointer and a lock structure pointer, the node pointer is used to link the request node structure to the waiting queue, the critical section function pointer points to the critical section code that needs to be executed by the thread, and the lock structure pointer is used to point to the spin lock structure; in the waiting queue, determining the spin lock holder in the plurality of threads based on the lock holder pointer; after the spin lock holder corresponding to the processor core executes the critical section code of the corresponding thread, traversing the waiting queue, reading the critical section function pointer of each waiting node, and sequentially executing the critical section code in each request node structure based on the critical section function pointer on the current processor core, wherein after the spin lock holder corresponding to the processor core executes the critical section code of the corresponding thread, the spin lock is not immediately released, and the threads other than the thread corresponding to the spin lock holder do not execute the critical section code after being woken up by the corresponding thread itself; when determining the spin lock holder in the plurality of threads, the method further comprises: comparing the priority of the current thread with the priority of other waiting threads, or determining the thread that acquires the spin lock earliest in the plurality of threads; in the case that the priority of the current thread is higher than the priority of other waiting threads and the lock holder pointer is not empty, determining the current thread as the spin lock holder, or in the case that the thread that acquires the spin lock earliest and the lock holder pointer is not empty, determining the current thread as the spin lock holder.
2. The spin lock optimization method according to claim 1, wherein: The method further comprises: in the case that there is a thread that acquires the spin lock first in the plurality of threads and the lock holder pointer is a null pointer, setting the lock holder pointer to the identifier of the current thread based on an atomic exchange operation, and linking the request node structure corresponding to the thread as the head of the waiting queue; in the case that the lock holder pointer is not a null pointer, sequentially linking the corresponding request node structure as the tail of the waiting queue based on the node pointer and the order in which each thread acquires the spin lock, to form the waiting queue.
3. The spinlock optimization method of claim 1, wherein, The method further comprises: detecting whether the lock holder pointer is a null pointer; in the case that the lock holder pointer is not a null pointer, determining the current thread as the spin lock holder.
4. The spin lock optimization method according to claim 2, wherein: The request node structure further comprises an atomic waiting flag bit, and the method further comprises: setting the atomic waiting flag bit to a preset value to enter a spin waiting state.
5. The spinlock optimization method of claim 4, wherein, The method further comprises: after the spin lock holder executes the critical section code corresponding to each thread, clearing the preset value of the atomic waiting flag bit to zero; after clearing the atomic waiting flag bit, recording a corresponding operation log, wherein the operation log comprises at least one of a thread identity and a clearing time.
6. The spinlock optimization method of claim 1, wherein, The method further comprises: after the spin lock holder executes the critical section code corresponding to all threads, setting the lock holder pointer to a null pointer based on an atomic operation mode; after setting the lock holder pointer to a null pointer, recording a corresponding operation log, wherein the operation log comprises at least one of a thread identity and an operation time.
7. The spinlock optimization method of claim 1, wherein, The spin lock structure further comprises a linked list head pointer, the linked list head pointer pointing to a first node of the waiting queue, and the initialization spin lock structure comprises: setting the lock holder pointer to a null and setting the linked list head pointer to a null.
8. The spinlock optimization method of claim 1, wherein, The method further comprises: during the acquisition and release of the spin lock, detecting whether the spin lock is in an abnormal state, wherein the abnormal state comprises at least one of the spin lock being occupied and the spin lock being damaged; switching the spin lock to a backup spin lock and synchronizing state information of the spin lock to the backup spin lock.
9. An electronic device, comprising: comprise: a memory, a processor, and a program stored on the memory and executable on the processor, wherein the processor executes the program to implement the spin lock optimization method according to any one of claims 1-8.
Citation Information
Patent Citations
Method, device and equipment for realizing spin lock during resource access
CN111984428A
Critical zone execution method and device in NUMA system
CN112306698A