在x86上對16bit,32bit,64bit的運算元進行load和store操作,只要這個運算元是在一條快取行內,則保證是原子的。
#include
#include
alignas(64
)char data[
128]=;
//寫執行緒
void
thread_write
(int val)
}//讀執行緒
void
thread_read
(int val1,
int val2)
//如果load和store是原子的,則下面的**就不會執行
std::cout << val << std::endl;
exit(0
);}int
main()
因為快取行是64個位元組的,所以*(int*)(data + 62)這個整數處於兩條快取行之間,執行緒th_w1不斷的寫入0,執行緒th_w2不斷的寫入-1(用補碼表示就是0xffffffff),讀執行緒th_r1就有可能讀到65535(0x0000ffff)或-65536((0xffff0000)。如果不是跨快取行,比如對*(int*)(data + 32)進行讀寫就是原子的,讀執行緒就只會讀到0或-1。
[參考文件] intel® 64 and ia-32 architectures software developer』s manual 8.1.1節
x86架構的乙個瑕疵 可執行保護
很久以前,曾經寫過一篇關於如何保護棧不可執行的文章 棧的保護 windows和linux 文章的最後談到了一種很好的方式,就是不用段式保護機制而使用頁式保護機制,在頁表項中做文章,但是這種方式有乙個前提就是頁表項必須支援可執行位,傳統的x86 是不支援的,也就是說傳統的x86處理器僅僅支援讀寫保護,...
x86架構的乙個瑕疵 可執行保護
很久以前,曾經寫過一篇關於如何保護棧不可執行的文章 棧的保護 windows和linux 文章的最後談到了一種很好的方式,就是不用段式保護機制而使用頁式保護機制,在頁表項中做文章,但是這種方式有乙個前提就是頁表項必須支援可執行位,傳統的x86 是不支援的,也就是說傳統的x86處理器僅僅支援讀寫保護,...
乙個簡單的例子說明原子性操作
原子性操作例子舉例 a想要從自己的帳戶中轉1000塊錢到b的帳戶裡。那個從a開始轉帳,到轉帳結束的這乙個過程,稱之為乙個事務。在這個事務裡,要做如下操作 1.從a的帳戶中減去1000塊錢。如果a的帳戶原來有3000塊錢,現在就變成2000塊錢了。2.在b的帳戶裡加1000塊錢。如果b的帳戶如果原來有...