Advanced Tutorial: Linux kernel synchronization mechanism 2

Source: Internet
Author: User
Article title: master advanced: Linux kernel synchronization mechanism 2. Linux is a technology channel of the IT lab in China. Includes basic categories such as desktop applications, Linux system management, kernel research, embedded systems, and open source.
   IV. read/write semaphores (rw_semaphore)
  
The read/write semaphores segment visitors, or are readers or writers. readers can only read and access the shared resources protected by the read/write semaphores while maintaining the read/write semaphores, if a task requires reading and writing, it must be classified as a writer. before accessing shared resources, it must first obtain the writer identity, the writer can downgrade to a reader if he finds that he does not need to write access. The number of readers of a read/write semaphore is unlimited. that is to say, multiple readers can have a read/write semaphore at the same time.
  
If a read/write semaphore is not owned by the writer and is not waiting for the reader to release the semaphore, any reader can successfully obtain the read/write semaphore. otherwise, the reader must be suspended until the writer releases the semaphore. If a read/write semaphore is not owned by a reader or writer and is not waiting for the semaphore, a writer can successfully obtain the read/write semaphore. Otherwise, the writer will be suspended until no visitor exists. Therefore, writers are exclusive and dedicated.
  
Read/write semaphores can be implemented in two ways. one is universal and independent from the hardware architecture. Therefore, you do not need to re-implement the new architecture, but the disadvantage is that the performance is low, the overhead for obtaining and releasing read/write semaphores is high; the other is architecture-related. Therefore, the overhead for obtaining and releasing read/write semaphores is low, but the new architecture needs to be implemented again. During kernel configuration, you can use the options to control which implementation to use.
  
APIs related to read/write semaphores include:
  
DECLARE_RWSEM (name)
  
This macro declares a read/write semaphore name and initializes it.
  
Void init_rwsem (struct rw_semaphore * sem );
  
This function initializes the read/write semaphores sem.
  
Void down_read (struct rw_semaphore * sem );
  
The reader calls this function to obtain the read and write semaphores sem. This function will cause the caller to sleep and therefore can only be used in the process context.
  
Int down_read_trylock (struct rw_semaphore * sem );
  
This function is similar to down_read, but it does not cause the caller to sleep. It tries its best to get the read and write semaphores sem. if it can get it immediately, it will get the read and write semaphores and return 1. Otherwise, it indicates that it cannot get the semaphores immediately and returns 0. Therefore, it can also be used in the interrupt context.
  
Void down_write (struct rw_semaphore * sem );
  
The writer uses this function to obtain the read/write semaphores sem, which also causes the caller to sleep and can only be used in the process context.
  
Int down_write_trylock (struct rw_semaphore * sem );
  
This function is similar to down_write, but it does not cause the caller to sleep. This function tries its best to obtain the read/write semaphores. if it can be obtained immediately, it obtains the read/write semaphores and returns 1. Otherwise, it indicates that it cannot be obtained immediately and returns 0. It can be used in the interrupt context.
  
Void up_read (struct rw_semaphore * sem );
  
The reader uses this function to release the read/write semaphores sem. It is used in combination with down_read or down_read_trylock. If down_read_trylock returns 0, you do not need to call up_read to release the read/write semaphores, because the semaphores are not obtained at all.
  
Void up_write (struct rw_semaphore * sem );
  
The writer calls this function to release the semaphores sem. It is used in combination with down_write or down_write_trylock. If down_write_trylock returns 0, you do not need to call up_write because 0 indicates that the read/write semaphore is not obtained.
  
Void downgrade_write (struct rw_semaphore * sem );
  
This function is used to downgrade the writer to a reader, which is sometimes necessary. Because the writer is exclusive, no reader or writer can access the shared resources protected by the read/write semaphores when the writer maintains the read/write semaphores, for those who do not need to write access under the current conditions, the downgrading will enable the readers waiting for access to access immediately, thus increasing concurrency and improving efficiency.
  
The read/write semaphores are suitable for reading and writing less data. in the Linux kernel, the read/write semaphores are used to protect access to the memory image description structure of processes.
  
In Linux, each process is described by a structure of task_t or struct task_struct. The field mm of the structure of struct mm_struct describes the memory image of the process, in particular, the mmap field in the mm_struct structure maintains the memory block list of the entire process. this list will be greatly exploited or modified during the process's survival.
  
Therefore, the mm_struct structure has a field mmap_sem to protect mmap access. mmap_sem is a read/write semaphore, and there are many interfaces for process memory usage in the proc file system, they can be used to view the memory usage of a process. The free, ps, and top commands obtain the memory usage information through proc, the proc interface uses down_read and up_read to read the mmap information of the process.
  
When a process dynamically allocates or releases memory, you need to modify mmap to reflect the memory image allocated or released, therefore, the dynamic memory allocation or release operation requires obtaining the read/write semaphore mmap_sem as the writer to update mmap. The system calls brk and munmap and uses down_write and up_write to protect access to mmap.
  
   5. spin lock)
  
The spin lock is similar to the mutex lock, but the spin lock does not cause the caller to sleep. if the spin lock has been maintained by other execution units, the caller always loops there to see if the lock owner has released the lock. Therefore, the word "spin" is named.
  
Because spin locks are usually kept for a very short period of time, it is necessary to choose spin instead of sleep. the efficiency of spin locks is much higher than that of mutex locks.
  
Semaphores and read/write semaphores are suitable for long periods of time. They can cause the caller to sleep, so they can only be used in the process context (the _ trylock variant can be used in the interrupt context ), the spin lock can be used in any context when the holding time is very short.
  
If the protected shared resource is accessed only in the context of the process, it is very suitable to use semaphores to protect the shared resource. if the access time to the shared resource is very short, the spin lock can also be used. However, if the protected shared resource needs to interrupt context access (including the bottom half, namely the interrupt processing handle and the top half, that is, the soft interrupt), the spin lock must be used.
  
During the spin lock holding period, the preemption fails, while the Semaphore and read/write semaphores can be preemptible. The spin lock is required only when the kernel can be preemptible or SMP. in a single CPU and kernel that cannot be preemptible, all operations of the spin lock are null.
  
Like a mutex lock, an execution unit must first obtain a lock to access the shared resources protected by the spin lock. after accessing the shared resources, the lock must be released. If no execution unit keeps the lock when obtaining the spin lock, the lock will be obtained immediately. if the lock already has the lock when obtaining the spin lock, the Get lock operation will spin there, until the lock is released by the holder of the spin lock.
  
No matter whether it is a mutex lock or a spin lock, there can be at most one lock at any time. that is to say, at most one execution unit can get the lock at any time.
  
The spin lock APIs include:
  
Spin_lock_init (x)
  
This macro is used to initialize the spin lock x. The spin lock must be initialized before it is actually used. This macro is used for dynamic initialization.
  
DEFINE_SPINLOCK (x)
  
The macro declares a spin lock x and initializes it. The macro was defined for the first time in 2.6.11 and is not in the previous kernel.
  
SPIN_LOCK_UNLOCKED
  
This macro is used to initialize a spin lock statically.
  
DEFINE_SPINLOCK (x) is equivalent to spinlock_t x = SPIN_LOCK_UNLOCKED
Spin_is_locked (x)
  
This macro is used to determine whether the spin lock x has been maintained by an execution unit (that is, locked). If yes, true is returned; otherwise, false is returned.
  
Spin_unlock_wait (x)
  
The macro is used to wait for the spin lock x to become not maintained by any execution unit. If no execution unit keeps the spin lock, the macro returns immediately; otherwise, the loop will be there, the spin lock is released until it is retained.
  
Spin_trylock (lock)
  
The macro tries its best to get the spin lock. if it can get the lock immediately, it gets the lock and returns the true value. Otherwise, it cannot get the lock immediately and returns false immediately. It does not spin to wait for the lock to be released.
  
Spin_lock (lock)
  
This macro is used to obtain the spin lock. if the lock can be obtained immediately, it will return immediately. Otherwise, it will spin there until the holder of the spin lock is released, it acquires the lock and returns it. In short, only the lock is returned.
  
Spin_lock_irqsave (lock, flags)
  
When this macro obtains the spin lock, it saves the value of the flag register to the variable flags and invalidates local interruptions.
  
Spin_lock_irq (lock)
  
The macro is similar to the spin_lock_irqsave, but the macro does not save the value of the flag register.
  
Spin_lock_bh (lock)
  
This macro fails the local soft interrupt while obtaining the spin lock.
  
Spin_unlock (lock)
  
This macro releases the spin lock, which is used in pairs with the spin lock or the spin lock. If spin_trylock returns false, it indicates that the spin lock is not obtained, so you do not need to use the spin_unlock release.
  
Spin_unlock_irqrestore (lock, flags)
  
When the macro releases the spin lock, it also restores the value of the flag register to the value saved by the variable flags. It is used in combination with spin_lock_irqsave.
  
Spin_unlock_irq (lock)
  
This macro releases the spin lock and also enables local interruption. It is paired with the spin_lock_irq.
  
Spin_unlock_bh (lock)
  
This macro releases the spin lock and also enables local soft interruptions. It is used together with spin_lock_bh.
  
Spin_trylock_irqsave (lock, flags)
  
If the macro gets the spin lock, it will also save the value of the flag register to the variable flags, and the local interrupt will be invalidated. if the macro does not get the lock, it will do nothing.
  
Therefore, if the lock can be obtained immediately, it is equivalent to the spin_lock_irqsave. if the lock cannot be obtained, it is equivalent to the spin_trylock. If the macro gets the spin lock, use the spin_unlock_irqrestore to release it.
  
Spin_trylock_irq (lock)
  
The macro is similar to the spin_trylock_irqsave, but the macro does not save the Mark Register. If the macro gets the spin lock, use the spin_unlock_irq to release it.
  
Spin_trylock_bh (lock)
  
If the macro gets a spin lock, it also invalidates the local soft interrupt. If the lock is not obtained, it does not do anything. Therefore, if a lock is obtained, it is equivalent to spin_lock_bh. If no lock is obtained, it is equivalent to spin_trylo.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.