Gần đây tôi đã lén nhìn vào việc thực hiện hạt nhân Linux của một đọc và viết nguyên tử và một vài câu hỏi xuất hiện.Đọc và viết thực hiện hoạt động nguyên tử trong hạt nhân Linux
Đầu tiên các mã có liên quan từ kiến trúc ia64:
typedef struct {
int counter;
} atomic_t;
#define atomic_read(v) (*(volatile int *)&(v)->counter)
#define atomic64_read(v) (*(volatile long *)&(v)->counter)
#define atomic_set(v,i) (((v)->counter) = (i))
#define atomic64_set(v,i) (((v)->counter) = (i))
Đối với cả đọc và ghi các hoạt động, có vẻ như cách tiếp cận trực tiếp được thực hiện để đọc từ hay ghi vào biến. Trừ khi có một thủ thuật khác ở đâu đó, tôi không hiểu những gì đảm bảo tồn tại rằng hoạt động này sẽ là nguyên tử trong miền lắp ráp. Tôi đoán một câu trả lời rõ ràng sẽ là một hoạt động như vậy dịch sang một mã opcode lắp ráp, nhưng ngay cả như vậy, làm thế nào là đảm bảo khi có tính đến các cấp độ bộ nhớ cache khác nhau (hoặc tối ưu hóa khác)?
Trên các macro đã đọc, loại dễ bay hơi được sử dụng trong thủ thuật đúc. Bất cứ ai cũng có một đầu mối làm thế nào điều này ảnh hưởng đến nguyên tử ở đây? (Lưu ý rằng nó không được sử dụng trong thao tác ghi)
Trong hạt nhân hiện đại, 'biến động' ở đây được sử dụng thông qua macro được gọi là' READ_ONCE() '/' WRITE_ONCE'. Cách diễn giải trong đầu của tôi là các trình biên dịch về mặt kỹ thuật được phép đọc/ghi giá trị * nhiều * lần. Ví dụ. nếu mã sao chép một giá trị đọc vào một biến cục bộ, sau đó nó được sử dụng ở các vị trí khác nhau. Vì vậy, chúng tôi phải mô tả điều này nhiều hơn một chút so với việc ngăn chặn giá trị được lưu trữ cục bộ. Mô tả đầy đủ: https://lwn.net/Articles/508991/ – sourcejedi