पर एक लेख है: http://lwn.net/Articles/378262/ जो लिनक्स कर्नेल सर्कुलर बफर कार्यान्वयन का वर्णन करता है। के बाद से इस कोड को स्पष्ट रूप से स्मृति आदेश और atomicity spin_lock की बात है क्या के साथ संबंधितलिनक्स कर्नेल परिपत्र बफर को समझना
- ():
यहाँ "निर्माता" है::
spin_lock(&producer_lock); unsigned long head = buffer->head; unsigned long tail = ACCESS_ONCE(buffer->tail); if (CIRC_SPACE(head, tail, buffer->size) >= 1) { /* insert one item into the buffer */ struct item *item = buffer[head]; produce_item(item); smp_wmb(); /* commit the item before incrementing the head */ buffer->head = (head + 1) & (buffer->size - 1); /* wake_up() will make sure that the head is committed before * waking anyone up */ wake_up(consumer); } spin_unlock(&producer_lock);
प्रश्न मैं कुछ सवाल हैं ?
- अभी तक, मेरी समझ यह है कि ACCESS_ONCE संकलक रीडरिंग को रोकता है, सच?
- क्या उत्पादन_item (आइटम) आइटम से जुड़े सभी लेखों को बस जारी करता है?
- मुझे विश्वास है कि smp_wmb() गारंटी देता है कि product_item (आइटम) में सभी लिखने से पहले "प्रकाशन" लिखने से पहले पूरा हो जाता है। सच?
- पृष्ठ पर टिप्पणी जहां मुझे यह कोड मिला है, यह इंगित करता है कि एक smp_wmb() सामान्य रूप से हेड इंडेक्स को अपडेट करने के बाद आवश्यक हो, लेकिन wake_up (उपभोक्ता) ऐसा करता है, इसलिए यह आवश्यक नहीं है। क्या यह सच है? यदि ऐसा है तो क्यों?
spin_lock(&consumer_lock); unsigned long head = ACCESS_ONCE(buffer->head); unsigned long tail = buffer->tail; if (CIRC_CNT(head, tail, buffer->size) >= 1) { /* read index before reading contents at that index */ smp_read_barrier_depends(); /* extract one item from the buffer */ struct item *item = buffer[tail]; consume_item(item); smp_mb(); /* finish reading descriptor before incrementing tail */ buffer->tail = (tail + 1) & (buffer->size - 1); } spin_unlock(&consumer_lock);
प्रश्न "उपभोक्ता" के लिए विशिष्ट:
यहाँ "उपभोक्ता" है
- क्या smp_read_barrier_depends() क्या करता है? एक मंच में कुछ टिप्पणियों से ऐसा लगता है कि आप यहां एक smp_rmb() जारी कर सकते थे, लेकिन कुछ आर्किटेक्चर पर यह अनावश्यक (x86) और बहुत महंगा है, इसलिए smp_read_barrier_depends() को वैकल्पिक रूप से ऐसा करने के लिए बनाया गया था ... उसने कहा, वास्तव में समझ में नहीं आता क्यों smp_rmb() हमेशा जरूरी है!
- क्या smp_mb() वहाँ यह गारंटी देने के लिए है कि इसके बाद लिखने से पहले सभी पढ़े जाएंगे?