linux ซิงโครไนซ์การนับจองอย่างไร

http://lxr.linux.no/linux+v2.6.35/include/linux/preempt.h#L21

ฉันแค่พยายามรับแหล่งลินุกซ์ ฉันเห็นการนับการจองนี้และ linux จะแน่ใจได้อย่างไรว่าการนับการจองเป็นแบบอะตอมมิก รหัสเพียงเพิ่มค่า

ฉันยังมีอีกคำถามหนึ่ง เหตุใดตัวจัดการขัดจังหวะจึงต้องคงการยกเว้นซึ่งกันและกัน เพราะสามารถดำเนินการได้ครั้งละหนึ่งรายการเท่านั้นใช่ไหม

นอกจากนี้เมื่อปิดการใช้งานการขัดจังหวะ OS ทำอะไร? ละเว้นการขัดจังหวะหรือรักษาคิว ?


person mousey    schedule 03.09.2010    source แหล่งที่มา


คำตอบ (3)


มันเพิ่มขึ้น preempt_count() - สังเกต () - ซึ่งเป็นมาโครที่ถูกกำหนดเป็น:

#define preempt_count() (current_thread_info()->preempt_count)

ดังนั้นจึงเป็นการเพิ่มตัวแปรต่อเธรด ซึ่งไม่จำเป็นต้องล็อคใดๆ และปลอดภัย


วิธีที่ดีที่สุดคือถามคำถามหลายข้อแยกกัน แต่ถามสั้นๆ ดังนี้

  • ตัวจัดการการขัดจังหวะโดยทั่วไปสามารถถูกขัดจังหวะโดยตัวจัดการการขัดจังหวะอื่นๆ
  • ตัวจัดการอินเทอร์รัปต์สามารถทำงานบน CPU คอร์หนึ่งในขณะที่โค้ดเคอร์เนลอื่นกำลังทำงานบนคอร์อื่น
  • โดยทั่วไปการขัดจังหวะจะถูกปิดใช้งานโดยใช้กลไกของฮาร์ดแวร์ สิ่งเหล่านี้มีแนวโน้มที่จะจดจำการขัดจังหวะที่ค้างอยู่ แต่จะจำได้ไม่เกินหนึ่งรายการต่อเวกเตอร์ขัดจังหวะ
person caf    schedule 03.09.2010
comment
ขอบคุณมาก. โปรดตอบคำถามถัดไปของฉันด้วย - person mousey; 03.09.2010
comment
@caf และ mousey: หาก inc/dec ถูกเรียกโดยตัวจัดการข้อผิดพลาดหรือตัวจัดการขัดจังหวะ มันจะปลอดภัยหรือไม่ หรือมีกฎข้อไหนที่บอกว่าทำไม่ได้? ไอเดีย? - person minghua; 26.05.2013
comment
@minghua: ไม่ได้รับอนุญาตให้เข้าถึงในบริบทขัดจังหวะ - มันไม่สมเหตุสมผลเลยที่จะทำเช่นนั้น - person caf; 26.05.2013
comment
@cafe: นั่นคือความเข้าใจของฉันก็เช่นกัน แต่ดูที่ netif_rx() ในตอนท้ายมันจะเรียก put_cpu() ซึ่งจะเรียก preempt_enable() นอกจากนี้ spin_unlock_irqrestore() ยังมักใช้ในตัวจัดการการขัดจังหวะ โดยจะเพิ่มค่า preempt_count ฉันอ่านโค้ดถูกหรือเปล่า? ฉันกำลังดูว่าเมื่อใดที่ CONFIG_PREMPT เปิดใช้งาน - person minghua; 29.05.2013
comment
เมื่อมองไปรอบๆ ฉันเชื่อว่าการนับนั้นดำเนินการโดยตัวจัดการข้อผิดพลาดและตัวจัดการขัดจังหวะด้วย เนื่องจากตัวจัดการข้อบกพร่องและตัวจัดการขัดจังหวะถูกซ้อนกันโดยการออกแบบอย่างเคร่งครัด ดังนั้นจึงไม่ทำให้เกิดความเสียหายต่อค่าการนับ ตัวจัดการในบริบทขัดจังหวะเพียงใช้การนับจำนวนเธรดปัจจุบันตราบใดที่เธรดปัจจุบันไม่สามารถเปลี่ยนได้จนกว่าตัวจัดการทั้งหมดจะกลับมา ด้วยเหตุนี้ การดำเนินการอ่าน-แก้ไข-เขียนจึงไม่ใช่อะตอมมิกจริงๆ รับประกันว่าหลังจาก R-M-W เสร็จสิ้น จะไม่มีการสลับบริบทอีกต่อไปจนกว่าการจับคู่ preempt_disable() และจนกว่าการนับจะถึงศูนย์ - person minghua; 29.05.2013

การดำเนินการกับตัวแปร preempt_count ไม่ใช่อะตอมมิก ขอบเขตโค้ดระหว่าง inc และ dec ของ preempt_count ของเธรดรับประกันว่าจะไม่ถูกเปลี่ยนโดยผู้กำหนดตารางเวลา การสลับบริบทจากเธรดปัจจุบันในภูมิภาคโค้ดนี้สามารถเกิดขึ้นได้ในข้อยกเว้นหรือการขัดจังหวะแบบฝังเพิ่มเติมเท่านั้น หลังจากการดำเนินการ inc ครั้งแรกเสร็จสมบูรณ์ ตัวจัดการเพิ่มเติมจะเห็นว่าตัวแปรไม่เป็นศูนย์ จึงไม่ทำให้เกิดการสลับบริบท ก่อนที่ inc จะเสร็จสิ้น สามารถเปลี่ยนเธรดออกได้ แต่ก็ไม่เป็นไร เนื่องจากโค้ดยังไม่ถึงบริเวณที่มีการป้องกัน

รายละเอียดบางประการ: คำจำกัดความของตัวแปรอะตอมมิกควรเป็นเช่น "ตัวแปรอะตอมมิกคือตัวแปรนั้น ซึ่งการดำเนินการอ่านแก้ไขเขียนเสร็จสิ้นเป็นคำสั่งเดียวโดยไม่มีการหยุดชะงัก" การดำเนินการ "อ่าน-แก้ไข-เขียน" บน preempt_count สามารถถูกขัดจังหวะโดยตัวจัดการข้อยกเว้นอื่นหรือตัวจัดการขัดจังหวะ แต่ในลักษณะที่ฝังอย่างเคร่งครัดเท่านั้น ซึ่งเกิดจากการออกแบบเคอร์เนล เนื่องจากการดำเนินการแบบฝังเหล่านี้เป็นคู่ ดังนั้นค่าของ preempt_count จะไม่เสียหายในที่สุด แม้ว่าการดำเนินการ RMW อาจถูกขัดจังหวะและสามารถเปลี่ยนเธรดปัจจุบันออกได้ (เฉพาะในกรณีที่ไม่มี inc แบบฝังหลายตัวที่เสร็จสมบูรณ์) แต่ก็ไม่เป็นไรเนื่องจากโค้ดยังไม่ถึงภูมิภาคที่มีการป้องกัน เมื่อเธรดถูกเปลี่ยนกลับ การดำเนินการ R-M-W จะยังคงเสร็จสิ้น และจากจุดนั้นบนเธรดปัจจุบันจะไม่ถูกปิดจนกว่า dec ที่จับคู่ทั้งหมดจะเสร็จสิ้น

person minghua    schedule 03.06.2013

โปรเซสเซอร์สมัยใหม่ทุกตัวมีคำสั่ง test-and-set ที่แตกต่างกันออกไป

person msw    schedule 03.09.2010
comment
ตรวจสอบแหล่งที่มา ไม่ได้ใช้คำแนะนำเฉพาะระบบใดๆ มันแค่เพิ่มขึ้นเรื่อยๆ - person mousey; 03.09.2010