Read_seqbegin and apiread_seqbegin of kernel synchronization mechanism API
Read_seqbegin of kernel synchronization mechanism API
Seqlock shows a write-first lock. It can be divided into read sequence locks and write sequence locks. However, write is preferred. The read sequence lock routine is as follows: static inline int grow_chain32 (struct ufs_inode_info * ufsi, struct buffer_head * bh, _ fs32 * v, Indirect * from, Indirect *) {Indirect * p; unsigned seq; to-> bh = bh; do {seq = read_seqbegin (& ufsi-> meta_lock); to-> key32 = * (_ fs32 *) (to-> p = v); for (p = from; p <= to & p-> key32 = * (_ fs32 *) p-> p; p ++);} while (read_seqretry (& ufsi-> meta_lock, seq); return (p> to);} the source code analysis is as follows: we can see that this function is not implemented as an inline function sta. Tic inline unsigned read_seqbegin (const seqlock_t * sl) {return read_seqcount_begin (& sl-> seqcount);} static inline unsigned read_seqcount_begin (const seqcount_t * s) {# The callback (s); return raw_read_seqcount_begin (s);} static inline unsigned raw_read_seqcount_begin (const seqcount_t * s) is empty when CONFIG_DEBUG_LOCK_ALLOC is not defined) {# Start a critical section of seq-read, without barrierunsigned ret = _ rea D_seqcount_begin (s); # barrier smp_ RMB (); return ret;} static inline unsigned _ read_seqcount_begin (const seqcount_t * s) {unsigned ret; repeat: # Here we try to read the value of s-> sequence. If the returned value is 1, it indicates that it may be being written, and the read attempt will continue to be read. # Here we can clearly see that sequential locks give priority to write. Because if the read cannot obtain the lock, it will wait until the write releases the lock. ret = READ_ONCE (s-> sequence); if (unlikely (ret & 1) {cpu_relax (); goto repeat;} return ret ;}