5.2. lock_kernel()

lock_kernel()Àº °¢ ¾ÆÅ°ÅØÃÄ ¸¶´Ù Çϳª¾¿ µû·Î Á¤ÀǵǾî ÀÖ´Ù. º¸Åë $(TOPDIR)/include/asm-*/smplock.h ¿¡ ÇÔ¼ö·Î Á¤ÀǵǾî ÀÖ°í spark64, sh, cris ¾ÆÅ°ÅØÃÄ´Â ¸ÅÅ©·Î·Î Á¤ÀǵǾî ÀÖ´Ù.

5.2.1. LockÀÌ ¿Ö ÇÊ¿äÇÏÁö?

¸®´ª½º´Â CPU¸¦ ¿©·¯ °³ °¡Áø ½Ã½ºÅÛ¿¡¼­µµ ½ÇÇàµÇ°í À̸¦ Áö¿øÇϰí ÀÖ´Ù. ¸¸¾à ¿©·¯ °³ÀÇ CPU°¡ µ¿½Ã¿¡ °°Àº º¯¼öÀÇ °ªÀ» Á¶Á¤Çϰí Àд °æ¿ì°¡ »ý±ä´Ù¸é ¾î¶»°Ô µÇ°Ú´Â°¡? ¾Æ·¡ÀÇ °£´ÜÇÑ ¿¹¸¦ º¸¸é¼­ ¾ê±âÇØ º¸ÀÚ.

very_important_count++;

µÎ°³ÀÇ CPU°¡ µ¿½Ã¿¡ °°Àº Äڵ带 ½ÇÇàÇß´Ù¸é ¾Æ·¡¿Í °°Àº Ç¥ ó·³ ½ÇÇàµÇ¾ß ¸Â´Ù°í °¡Á¤Çغ¸ÀÚ.

Ç¥ 5-1. ¿¹»ó °á°ú

Instance1Instance2
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. °¡´ÉÇÑ °á°ú

Instance1Instance2
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)À̶õ °ÍÀ» ¾²´Âµ¥ ½±°Ô ¸»ÇØ ¼­·Î ÁßøµÇ¼­ ½ÇÇàµÇÁö ¾Êµµ·Ï º¸Àå ÇÏ´Â °ÍÀ̶ó°í ÀÌÇØÇÏ¸é µÈ´Ù.

½Ã½ºÅÛÀ» ÃʱâÈ­ ÇÏ´Â µ¿¾È¿¡ ÀÌ·± ÀÏÀÌ ¹ß»ýÇÏ¸é ½Ã½ºÅÛ ÃʱâÈ­´Â ¾û¸ÁÀÌ µÇ°í Ä¿³ÎÀº Á¦´ë·Î ºÎÆÃÇÒ ¼ö ¾ø°Ô µÈ´Ù. ±×·¡¼­ ÃʱâÈ­ µ¿¾È ¶ôÀ» °É°í ³ªÁß¿¡ ÃʱâÈ­°¡ ´Ù ³¡³ª¸é ¶ôÀ» Ç®¾îÁÖ°Ô µÈ´Ù.

5.2.2. Lock - ±âÃÊÀû ¼³¸í

¸ÖƼŽºÅ· OS¿¡¼­ ÇÑ º¯¼ö¸¦ ¿©·¯ °³ÀÇ ÇÁ·Î¼¼½º°¡ °øÀ¯Çϰí À̸¦ µ¿½Ã¿¡ »ç¿ëÇÑ´Ù¸é ¿©·¯ ÇÁ·Î¼¼½º °£ÀÇ ¿¬°èµÈ ½Ã°£¿¡ µû¶ó ÀÌ º¯¼ö¸¦ »ç¿ëÇÏ´Â °ÍÀÌ ÁßøµÇ´Âµ¥ À̸¦ º¸Åë ·¹À̽º ÄÁµð¼Ç(race condition) À̶ó°í ºÎ¸¥´Ù. ±×¸®°í µ¿½Ã ¹ß»ý ¹®Á¦¸¦ ´Ù·ç´Â Äڵ带 Å©¸®Æ¼Äà ¸®Àü(critical region)À̶ó ºÎ¸¥´Ù. ¸®´ª½º´Â SMP »ó¿¡¼­ µ¿ÀÛÇϹǷΠÀÌ·± ¹®Á¦°¡ Ä¿³Î µðÀÚÀο¡ À־ Áß¿äÇÑ ¹®Á¦Áß Çϳª´Ù.

À§¿¡¼­ ¸»ÇÑ µ¿½Ã Á¢±Ù°ú °°Àº ¹®Á¦ÀÇ ÇØ°áÀº ¶ô(lock)À» ÀÌ¿ëÇÏ´Â °ÍÀÌ°í ¶ôÀº Çѹø¿¡ ÇϳªÀÇ Á¢±Ù¸¸ÀÌ Å©¸®Æ¼Äà ¸®Àü¿¡ µé¾î°¡µµ·Ï ÇØ¼­ ÇØ°áÇÑ´Ù.

¶ô¿£ µÎ°¡Áö ŸÀÔÀÌ ÀÖ´Ù. Çϳª´Â ½ºÇɶô(spinlock)À¸·Î include/asm/spinlock.h¿¡ Á¤ÀǵǾî ÀÖ´Ù. ÀÌ Å¸ÀÔÀº ½Ì±ÛȦ´õ¶ô(single-holder lock)ÀÌ°í ¸Å¿ì ÀÛ°í ºü¸£°í ¾Æ¹«µ¥¼­³ª »ç¿ëÇÒ ¼ö ÀÖ´Ù.

µÎ¹øÂ° ŸÀÔÀº ¼¼¸¶Æ÷¾î·Î include/asm/semaphore.h¿¡ Á¤ÀǵǾî ÀÖ´Ù. ¼¼¸¶Æ÷¾î´Â º¸Åë ½Ì±ÛȦ´õ¶ô (mutex)À¸·Î »ç¿ëµÇÁö¸¸ Çѹø¿¡ ¿©·¯ Ȧ´õ¸¦ °¡Áú ¼ö ÀÖ´Ù. »ç¿ëÀÚ°¡ ¼¼¸¶Æ÷¾î¸¦ ¾òÁö ¸øÇÏ¸é »ç¿ëÀÚÀÇ ÇÁ·Î¼¼½º´Â Å¥¿¡ ³Ö¾îÁö°í ¼¼¸¶Æ÷¾î°¡ »ç¿ë °¡´ÉÇØÁú ¶§ ±ú¾î³ª°ÔµÈ´Ù. ÀÌ ¸»Àº ÇÁ·Î¼¼½º°¡ ±â´Ù¸®´Â µ¿¾È CPU°¡ ´Ù¸¥ ¹º°¡¸¦ ÇÑ´Ù´Â °ÍÀÌ´Ù. ±×·¯³ª ¸¹Àº °æ¿ì¿¡ ±×³É ±â´Ù¸± ¼ö ¾øÀ» ¶§°¡ ÀÖ´Ù. ÀÌ °æ¿ì¿£ ½ºÇɶôÀ» ´ë½Å »ç¿ëÇØ¾ßÇÑ´Ù.

Ä¿³ÎÀ» ¼³Á¤ÇÒ ¶§ SMP Áö¿øÀ» üũÇÏÁö ¾Ê¾Ò´Ù¸é ½ºÇɶôÀº Á¸ÀçÇÏÁö ¾Ê°Ô µÈ´Ù. ÀÌ·± °áÁ¤Àº ¾Æ¹«µµ µ¿½Ã¿¡ ½ÇÇàÇÏÁö ¾Ê°í ¶ôÀ» °É ÀÌÀ¯°¡ ¾ø´Â °æ¿ì ¾ÆÁÖ ÁÁÀº Ä¿³Î µðÀÚÀÎÀÌ¶ó ¸»ÇÒ ¼ö ÀÖ´Ù. ¼¼¸¶Æ÷¾î´Â ¾ðÁ¦³ª Á¸ÀçÇϴµ¥ ÀÌ´Â »ç¿ëÀÚ ÇÁ·Î¼¼½º°£¿¡ µ¿±â¸¦ ¸ÂÃß±âÀ§ÇØ ÇÊ¿äÇϱ⠶§¹®ÀÌ´Ù.

5.2.3. i386, ARMÀÇ ½ºÇɶô

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");
}

(1)
ÀζóÀÎ ¾î¼Àºí¸®¿¡ ´ëÇØ¼± ºÎ·Ï C¸¦ ÂüÁ¶ÇØ ¹«½¼ ³»¿ëÀÎÁö È®ÀÎ Çϱ⠹ٶõ´Ù.