lock_kernel()Àº °¢ ¾ÆÅ°ÅØÃÄ ¸¶´Ù Çϳª¾¿ µû·Î Á¤ÀǵǾî ÀÖ´Ù. º¸Åë $(TOPDIR)/include/asm-*/smplock.h ¿¡ ÇÔ¼ö·Î Á¤ÀǵǾî ÀÖ°í spark64, sh, cris ¾ÆÅ°ÅØÃÄ´Â ¸ÅÅ©·Î·Î Á¤ÀǵǾî ÀÖ´Ù.
¸®´ª½º´Â CPU¸¦ ¿©·¯ °³ °¡Áø ½Ã½ºÅÛ¿¡¼µµ ½ÇÇàµÇ°í À̸¦ Áö¿øÇϰí ÀÖ´Ù. ¸¸¾à ¿©·¯ °³ÀÇ CPU°¡ µ¿½Ã¿¡ °°Àº º¯¼öÀÇ °ªÀ» Á¶Á¤Çϰí Àд °æ¿ì°¡ »ý±ä´Ù¸é ¾î¶»°Ô µÇ°Ú´Â°¡? ¾Æ·¡ÀÇ °£´ÜÇÑ ¿¹¸¦ º¸¸é¼ ¾ê±âÇØ º¸ÀÚ.
very_important_count++; |
µÎ°³ÀÇ CPU°¡ µ¿½Ã¿¡ °°Àº Äڵ带 ½ÇÇàÇß´Ù¸é ¾Æ·¡¿Í °°Àº Ç¥ ó·³ ½ÇÇàµÇ¾ß ¸Â´Ù°í °¡Á¤Çغ¸ÀÚ.
Ç¥ 5-1. ¿¹»ó °á°ú
| Instance1 | Instance2 |
|---|---|
| read very_important_count (5) | |
| add 1 (6) | |
| write very_important_count (6) | |
| read very_important_count (6) | |
| add 1 (7) | |
| write very_important_count (7) |
±×·¯³ª ÀÌ°Ç ¾Æ¸¶µµ ÀÌ·± ½ÄÀ¸·Î ½ÇÇàµÉ ¼öµµ ÀÖ´Ù.
Ç¥ 5-2. °¡´ÉÇÑ °á°ú
| Instance1 | Instance2 |
|---|---|
| read very_important_count (5) | |
| read very_important_count (5) | |
| add 1 (6) | |
| add 1 (6) | |
| write very_important_count (6) | |
| write very_important_count (6) |
°á°ú ÀûÀ¸·Î ¿¹»óÀº Instance1ÀÌ ½ÇÇàµÆÀ» ¶§ °ªÀÌ 6À̵ǰí Instance2°¡ ½ÇÇàµÆÀ» ¶§ 7ÀÌ µÇ±æ ¹Ù¶õ °ÍÀÌÁö¸¸ Ç¥ 5-2 ó·³ ¼·Î ½ÇÇàÀÌ ÁßøµÇ¹ö¸®¸é °á°ú °ªÀÌ 6À¸·Î ¾û¸ÁÀÌ µÉ ¼öµµ ÀÖ´Ù.
ÀÌ·± ÀÏÀ» ¸·±â À§ÇØ º¸Åë ¶ô(lock)À̶õ °ÍÀ» ¾²´Âµ¥ ½±°Ô ¸»ÇØ ¼·Î ÁßøµÇ¼ ½ÇÇàµÇÁö ¾Êµµ·Ï º¸Àå ÇÏ´Â °ÍÀ̶ó°í ÀÌÇØÇÏ¸é µÈ´Ù.
½Ã½ºÅÛÀ» ÃʱâÈ ÇÏ´Â µ¿¾È¿¡ ÀÌ·± ÀÏÀÌ ¹ß»ýÇÏ¸é ½Ã½ºÅÛ ÃʱâÈ´Â ¾û¸ÁÀÌ µÇ°í Ä¿³ÎÀº Á¦´ë·Î ºÎÆÃÇÒ ¼ö ¾ø°Ô µÈ´Ù. ±×·¡¼ ÃʱâÈ µ¿¾È ¶ôÀ» °É°í ³ªÁß¿¡ ÃʱâȰ¡ ´Ù ³¡³ª¸é ¶ôÀ» Ç®¾îÁÖ°Ô µÈ´Ù.
¸ÖƼŽºÅ· OS¿¡¼ ÇÑ º¯¼ö¸¦ ¿©·¯ °³ÀÇ ÇÁ·Î¼¼½º°¡ °øÀ¯Çϰí À̸¦ µ¿½Ã¿¡ »ç¿ëÇÑ´Ù¸é ¿©·¯ ÇÁ·Î¼¼½º °£ÀÇ ¿¬°èµÈ ½Ã°£¿¡ µû¶ó ÀÌ º¯¼ö¸¦ »ç¿ëÇÏ´Â °ÍÀÌ ÁßøµÇ´Âµ¥ À̸¦ º¸Åë ·¹À̽º ÄÁµð¼Ç(race condition) À̶ó°í ºÎ¸¥´Ù. ±×¸®°í µ¿½Ã ¹ß»ý ¹®Á¦¸¦ ´Ù·ç´Â Äڵ带 Å©¸®Æ¼Äà ¸®Àü(critical region)À̶ó ºÎ¸¥´Ù. ¸®´ª½º´Â SMP »ó¿¡¼ µ¿ÀÛÇϹǷΠÀÌ·± ¹®Á¦°¡ Ä¿³Î µðÀÚÀο¡ ÀÖ¾î¼ Áß¿äÇÑ ¹®Á¦Áß Çϳª´Ù.
À§¿¡¼ ¸»ÇÑ µ¿½Ã Á¢±Ù°ú °°Àº ¹®Á¦ÀÇ ÇØ°áÀº ¶ô(lock)À» ÀÌ¿ëÇÏ´Â °ÍÀÌ°í ¶ôÀº Çѹø¿¡ ÇϳªÀÇ Á¢±Ù¸¸ÀÌ Å©¸®Æ¼Äà ¸®Àü¿¡ µé¾î°¡µµ·Ï ÇØ¼ ÇØ°áÇÑ´Ù.
¶ô¿£ µÎ°¡Áö ŸÀÔÀÌ ÀÖ´Ù. Çϳª´Â ½ºÇɶô(spinlock)À¸·Î include/asm/spinlock.h¿¡ Á¤ÀǵǾî ÀÖ´Ù. ÀÌ Å¸ÀÔÀº ½Ì±ÛȦ´õ¶ô(single-holder lock)ÀÌ°í ¸Å¿ì ÀÛ°í ºü¸£°í ¾Æ¹«µ¥¼³ª »ç¿ëÇÒ ¼ö ÀÖ´Ù.
µÎ¹øÂ° ŸÀÔÀº ¼¼¸¶Æ÷¾î·Î include/asm/semaphore.h¿¡ Á¤ÀǵǾî ÀÖ´Ù. ¼¼¸¶Æ÷¾î´Â º¸Åë ½Ì±ÛȦ´õ¶ô (mutex)À¸·Î »ç¿ëµÇÁö¸¸ Çѹø¿¡ ¿©·¯ Ȧ´õ¸¦ °¡Áú ¼ö ÀÖ´Ù. »ç¿ëÀÚ°¡ ¼¼¸¶Æ÷¾î¸¦ ¾òÁö ¸øÇÏ¸é »ç¿ëÀÚÀÇ ÇÁ·Î¼¼½º´Â Å¥¿¡ ³Ö¾îÁö°í ¼¼¸¶Æ÷¾î°¡ »ç¿ë °¡´ÉÇØÁú ¶§ ±ú¾î³ª°ÔµÈ´Ù. ÀÌ ¸»Àº ÇÁ·Î¼¼½º°¡ ±â´Ù¸®´Â µ¿¾È CPU°¡ ´Ù¸¥ ¹º°¡¸¦ ÇÑ´Ù´Â °ÍÀÌ´Ù. ±×·¯³ª ¸¹Àº °æ¿ì¿¡ ±×³É ±â´Ù¸± ¼ö ¾øÀ» ¶§°¡ ÀÖ´Ù. ÀÌ °æ¿ì¿£ ½ºÇɶôÀ» ´ë½Å »ç¿ëÇØ¾ßÇÑ´Ù.
Ä¿³ÎÀ» ¼³Á¤ÇÒ ¶§ SMP Áö¿øÀ» üũÇÏÁö ¾Ê¾Ò´Ù¸é ½ºÇɶôÀº Á¸ÀçÇÏÁö ¾Ê°Ô µÈ´Ù. ÀÌ·± °áÁ¤Àº ¾Æ¹«µµ µ¿½Ã¿¡ ½ÇÇàÇÏÁö ¾Ê°í ¶ôÀ» °É ÀÌÀ¯°¡ ¾ø´Â °æ¿ì ¾ÆÁÖ ÁÁÀº Ä¿³Î µðÀÚÀÎÀÌ¶ó ¸»ÇÒ ¼ö ÀÖ´Ù. ¼¼¸¶Æ÷¾î´Â ¾ðÁ¦³ª Á¸ÀçÇϴµ¥ ÀÌ´Â »ç¿ëÀÚ ÇÁ·Î¼¼½º°£¿¡ µ¿±â¸¦ ¸ÂÃß±âÀ§ÇØ ÇÊ¿äÇϱ⠶§¹®ÀÌ´Ù.
i386 °è¿Àº SMP ½Ã½ºÅÛÀÌ Á¸Àç Çϱ⠶§¹®¿¡ ½ºÇɶôÀÌ Á¤ÀǵǾî ÀÖ°í »ç¿ëµÇÁö¸¸ ARMÀÇ °æ¿ì SMP ½Ã½ºÅÛÀÌ ¾ø±â ¶§¹®¿¡ ½ºÇɶôÀÌ Á¤ÀǵǾî ÀÖÁö ¾Ê´Ù. ±×·¡¼ ARMÀÇ asm/smplock.h´Â ±âº»À¸·Î Á¤ÀÇµÈ °ÍÀÌ »ç¿ëµÈ´Ù.
±âº» Á¤ÀÇµÈ ½ºÇɶôÀº include/linux/spinlock.h¿¡ ´ÙÀ½°ú °°ÀÌ Á¤ÀǵǾî ÀÖ´Ù.
#define spin_lock(lock) (void)(lock) /* Not "unused variable". */ |
ÀÌ¿¡ ¹ÝÇØ i386Àº include/asm-i386/spinlock.h¿¡ ´ÙÀ½°ú °°ÀÌ Á¤ÀǵǾî ÀÖ´Ù.
static inline void spin_lock(spinlock_t *lock)
{
#if SPINLOCK_DEBUG
__label__ here;
here:
if (lock->magic != SPINLOCK_MAGIC) {
printk("eip: %p\n", &&here);
BUG();
}
#endif
(1)
__asm__ __volatile__(
spin_lock_string
:"=m" (lock->lock) : : "memory");
} |