आपका कोड के बराबर होती है करने के लिए:
static __inline__ int xchg_asm(int* lock, int val) {
int save_old_value_at_eax;
save_old_value_at_eax = *lock; /* with a wrong lock prefix */
xchg *lock with val and discard the original value of *lock.
return save_old_value_at_eax; /* but it not the real original value of *lock */
}
आप कोड से देख सकते हैं, save_old_value_at_eax
कोई वास्तविक मूल मूल्य जबकि cpu xchg प्रदर्शन करते हैं। आपको xchg निर्देश द्वारा पुराना/मूल मान प्राप्त करना चाहिए, xchg करने से पहले इसे सहेजकर नहीं। ("यह असली पुराना/मूल मूल्य नहीं है" का अर्थ है, यदि कोई सीपीयू लॉक लेता है तो इस सीपीयू के मूल्य को बचाता है लेकिन इससे पहले कि यह सीपीयू xchg निर्देश करता है, तो इस सीपीयू को गलत पुराना मान मिलेगा, और ऐसा लगता है कि उसने इसे लिया लॉक सफल, इस प्रकार, दो सीपीयू एक ही समय में सीएस में प्रवेश करते हैं)। आपने तीन निर्देशों के लिए एक पठन-संशोधित-लेखन निर्देश अलग कर दिया है, पूरे तीन निर्देश परमाणु रूप से नहीं हैं (यहां तक कि आप लॉक उपसर्ग को xchg पर ले जाते हैं)।
मैं तुम्हें सोचा ताला उपसर्ग पूरे तीन निर्देश लॉक हो जाएगा, लेकिन वास्तव में ताला उपसर्ग केवल केवल अनुदेश जो यह जुड़ा हुआ है (सभी निर्देशों संलग्न किया जा सकता है नहीं) के लिए इस्तेमाल किया जा सकता है लगता है और हम नहीं xchg के लिए एसएमपी पर लॉक उपसर्ग की आवश्यकता है। linux_kernel_src/चाप से उद्धरण/86 ///एएसएम/cmpxchg.h
/*
* Note: no "lock" prefix even on SMP: xchg always implies lock anyway.
* Since this is generally used to protect other memory information, we
* use "asm volatile" and "memory" clobbers to prevent gcc from moving
* information around.
*/
मेरे सुझावों में शामिल हैं:
- अपने आप को दोहराना नहीं है, लिनक्स कर्नेल की स्पिन ताला का इस्तेमाल करें।
- अपने आप को दोबारा न दें, कृपया लिनक्स कर्नेल के xchg(), cmpxchg() का उपयोग करें यदि आप स्पिन लॉक को कार्यान्वित करना चाहते हैं।
- निर्देशों के बारे में और जानें। आप यह भी पता लगा सकते हैं कि लिनक्स कर्नेल इसे कैसे कार्यान्वित करता है।
स्रोत
2012-07-17 03:39:33
मेरा जोड़ा ऊपर है। –
उत्कृष्ट; यह शायद बग नहीं है, लेकिन यह 'spin_destroy()' फ़ंक्शन के लिए 'spin_init() 'द्वारा आवंटित नहीं किया गया था, जो मुक्त स्मृति के लिए मेरे लिए बहुत अजीब लगता है। (क्या कोई 'spin_alloc()' फ़ंक्शन भी है?) – sarnold
spin_destory शायद अधिक है। –