greendrm
´ÙÀ½ ¹®¼´Â KELPÀÇ ¸ñ¿ä¼¼¹Ì³ª¸¦ À§ÇÑ Âü°í ÀÚ·áÀÌ´Ù.
1.1.1. ¿øÀÚÀûÀÎ Á¤¼ö ¿¬»ê ¶¿øÀÚÀû Á¤¼ö ¿¬»êÀº Ưº°ÇÑ ÀÚ·á ±¸Á¶ÀÎ atomic_t¸¦ »ç¿ëÇÑ´Ù.
¸®´ª½º Ä¿³Î 2.6.11ÀÇ include/asm/atomic.h¿¡ ¼±¾ðµÈ ³»¿ëÀº ´ÙÀ½°ú °°´Ù.
typedef struct { volatile int counter; } atomic_t;
Ã¥ÀÇ ³»¿ëÁß sparc¿¡¼´Â 24ºñÆ®¸¸À» »ç¿ëÇÑ´Ù´Â ºÎºÐÀº Ãʱâ Ä¿³Î ¹öÀü¿¡¼ÀÇ À̾߱âÀÌ´Ù. Çö Ä¿³Î 2.6.11¿¡¼´Â ¾Õ¼ º¸´Â °Í°ú °°Àº ÀÚ·áÇüÀ¸·Î ¼±¾ðµÇ¾î ÀÖÀ¸¸ç spin_lock_irqsave/spin_unlock_irqrestore¸¦ ÀÌ¿ëÇÏ¿© ¿øÀÚÀû µ¿ÀÛÀ» ó¸®ÇÏ°í ÀÖ´Ù. ÀÌ¿¡ ´ëÇÑ ºÎºÐÀº Ä¿³Î ¼Ò½º include/asm-sparc/atomic.h¿Í arch/sparc/lib/atomic32.c¸¦ º¸¶ó.
atomic_t´Â ´ÙÀ½°ú °°ÀÌ Á¤ÀÇÇÑ´Ù.
atomic_t u; /* ÃʱâÈ ÇÏÁö ¾ÊÀº »óÅ·Πu¸¦ Á¤ÀÇ */
ƯÈ÷ ´ÙÀ½°ú °°ÀÌ ÃʱâÈ ÇÏÁö ¾Êµµ·Ï ÁÖÀÇÇØ¾ß ÇÑ´Ù.
atomic_t v = ATOMIC_INIT(0); /* v¸¦ Á¤ÀÇÇÏ°í 0À¸·Î ÃʱâÈ */ atomic_t v = 0; /* À߸øµÈ ÃʱâÈ´Ù */
ÇÔ¼öµéÀº ¸ðµÎ °£´ÜÇÑ ÇüÅ·ΠµÅ ÀÖ´Ù.
atomic_set(&v, 4); /* v->counter = 4 (atomically) */
°ü·Ã ÇÔ¼ö´Â <asm/atomic.h>¿¡¼ ãÀ» ¼ö ÀÖ´Ù.
°ü·Ã ÇÔ¼ö ¸ñ·ÏÀº Ã¥ p119ÀÇ Ç¥ 8.1 ¿øÀÚÀû Á¤¼ö ¿¬»ê ¸ñ·ÏÀ» Âü°íÇ϶ó.
atomic_add(2, &v); /* v->counter = v->counter + 2 = 6 (atomically) */ atomic_inc(&v); /* v->counter = v->counter + 1 = 7 (atomically) */ 1.1.2. ¿øÀÚÀûÀÎ ºñÆ® ¿¬»ê ¶Ä¿³ÎÀº ¿øÀÚÀûÀÎ Á¤¼ö ¿¬»ê°ú ÇÔ²², ºñÆ® ´ÜÀ§·Î µ¿ÀÛÇÏ´Â ÇÔ¼öµéÀ» Á¦°øÇÑ´Ù. À̵é ÇÔ¼ö´Â <asm/bitops.h>¿¡ Á¤ÀǵǾî ÀÖ´Ù.
ÀÚ¼¼ÇÑ ³»¿ëÀº Ã¥ p120, 121À» Âü°íÇÑ´Ù. °ü·Ã ÇÔ¼ö ¸ñ·ÏÀº Ã¥ p121ÀÇ Ç¥ 8.2 ¿øÀÚÀû ºñÆ® ¿¬»ê ¸ñ·ÏÀ» Âü°íÇ϶ó. 1.2. ½ºÇÉ·Ï ¶¸ðµç À§Ç豸¿ª(critical region)À» ÇϳªÀÇ º¯¼ö¸¦ ´Ã¸®´Â °Í°ú °°Àº °°Àº °£´ÜÇÑ µ¿ÀÛÀ¸·Î Ç×»ó º¸Á¸ÇÒ ¼ö ¾ø´Ù. ÀÌ·¯ÇÑ °æ¿ì¿¡ ÃæºÐÇÑ º¸È£¸¦ Á¦°øÇÒ ÇÊ¿ä°¡ ÀÖÀ¸¸ç À̸¦ À§ÇØ ·Ï(lock)ÀÌ ÇÊ¿äÇÏ´Ù.
¸®´ª½º Ä¿³Î¿¡¼´Â À̸¦ À§ÇØ °¡Àå ¸¹ÀÌ »ç¿ëÇÏ´Â °ÍÀÌ ½ºÇÉ·Ï(spin lock)ÀÌ´Ù. ½ºÇÉ·ÏÀº ÃÖ´ëÇÑ ÇϳªÀÇ ½º·¹µå¿¡ ÀÇÇØ Àá±æ ¼ö ÀÖ´Â ·ÏÀ» ¸»ÇÑ´Ù. ¸¸¾à ¾î¶² ½º·¹µå°¡ ÀÌ¹Ì Àá°ÜÁø ½ºÇÉ·ÏÀ» ´Ù½Ã Àá±×·Á ½ÃµµÇÑ´Ù¸é ±× ½º·¹µå´Â ·çÇÁ(busy loop)¸¦ µ¹¸é¼(spin) ·ÏÀ» Àá±Û ¼ö ÀÖÀ» ¶§±îÁö ±â´Ù¸°´Ù. ½ºÇÉ·ÏÀº °¡º±°í ¼ÒÀ¯ÀÚ°¡ ÇϳªÀÎ ·ÏÀ¸·Î¼ ªÀº ±â°£ µ¿¾È¸¸ ¼ÒÀ¯ µÅ¾ß ÇÑ´Ù. ½ºÇÉ·Ï°ú °ü·ÃµÈ ÀÎÅÍÆäÀ̽º´Â <linux/spinlock.h>¿¡ Á¤ÀǵǾî ÀÖ´Ù. ½ºÇÉ·ÏÀÇ ±âº»ÀûÀÎ »ç¿ë¹ýÀº ´ÙÀ½°ú °°´Ù.
spinlock_t mr_lock = SPIN_LOCK_UNLOCKED;
½ºÇÉ·ÏÀº SMP¿¡¼¸¸ À¯È¿ÇÏ´Ù. UP ±â±â¿¡¼´Â ÄÄÆÄÀϽà ·ÏÀÌ Á¦°ÅµÇ¾î Æ÷ÇÔµÇÁö ¾Ê´Â´Ù. ±×·¯³ª Ä¿³ÎÀÇ ¼±Á¡ÀÌ °¡´ÉÇÑ°¡¸¦ ³ªÅ¸³»´Â Ç¥Áö·Î »ç¿ëµÉ ¼ö ÀÖ´Ù. ¸¸¾à Ä¿³Î ¼±Á¡ÀÌ ºñÈ°¼ºÈ µÇ¾î ÀÖ´Â °æ¿ì¿¡´Â ÄÄÆÄÀÏ ½Ã ¿ÏÀüÈ÷ Á¦°ÅµÈ´Ù.
spin_lock(&mr_lock); /* critical region ... */
spin_unlock(&mr_lock);
ÁÖÀÇ: ½ºÇÉ·ÏÀº Àç±ÍÀûÀÌÁö ¾Ê´Ù ½ºÇÉ·ÏÀº ÀÎÅÍ·´Æ® Çڵ鷯¿¡¼µµ »ç¿ë °¡´ÉÇÏ´Ù. ÀÎÅÍ·´Æ® Çڵ鷯¿¡¼ ·ÏÀ» »ç¿ëÇÒ °æ¿ì¿¡, Ä¿³Î ³»ÀÇ µ¥ÀÌÅ͸¦ ÀÎÅÍ·´Æ® Çڵ鷯¿¡¼ °øÀ¯ÇÏ´Â °æ¿ì ·ÏÀ» ¾ò±â Àü¿¡ ¹Ýµå½Ã ·ÎÄà ÀÎÅÍ·´Æ®¸¦ ºñÈ°¼ºÈÇØ¾ß ÇÑ´Ù. À̶§ ·ÎÄà ÀÎÅÍ·´Æ®ÀÇ È°¼ºÈ ¿©ºÎ¸¦ ¾Ë ¼ö ¾ø´Ù¸é ´ÙÀ½°ú °°Àº ÀÎÅÍÆäÀ̽º¸¦ ÀÌ¿ëÇØ¾ß ÇÑ´Ù. spinlock_t mr_lock = SPIN_LOCK_UNLOCKED;
unsigned long flags;
¸¸¾à ÀÎÅÍ·´Æ® È°¼ºÈ »óÅÂÀÓÀ» ¾Ë°í ÀÖ´Ù¸é ´ÙÀ½ÀÇ ÀÎÅÍÆäÀ̽º¸¦ »ç¿ëÇصµ µÈ´Ù.
spin_lock_irqsave(&mr_lock, flags); /* critical region ... */
spin_unlock_irqrestore(&mr_lock, flags);
spinlock_t mr_lock = SPIN_LOCK_UNLOCKED;
½ºÇÉ·Ï µð¹ö±ë
spin_lock_irq(&mr_lock); /* critical region ... */
spin_unlock_irq(&mr_lock);
¼³Á¤ ¿É¼ÇÀÇ ÇϳªÀÎ CONFIG_DEBUG_SPINLOCKÀº ½ºÇÉ·Ï ÄÚµåÀÇ ¸¹Àº µð¹ö±ë °Ë»ç¸¦ È°¼ºÈ½ÃŲ´Ù. 1.2.2. ½ºÇÉ·Ï°ú º¸ÅèÇÏÇÁ ¶
1.3. ¸®´õ-¶óÀÌÅÍ ½ºÇÉ·Ï ¶·ÏÀÇ »ç¿ëÀÌ ¸®´õ(reader)¿Í ¶óÀÌÅÍ(writer)·Î È®¿¬È÷ ±¸ºÐµÇ´Â °æ¿ì¿¡ »ç¿ëÇÑ´Ù.
Àд ÁßÀÎ °æ¿ì¿¡´Â ¾²±â¸¸ ¹æÁöÇØ¾ß Çϸç, ¾²±â ÁßÀÏ ¶§´Â Àбâ¿Í ¾²±â ¸ðµÎ ¹æÁöÇØ¾ß ÇÑ´Ù. ¸®´õ-¶óÀÌÅÍ ½ºÇÉ·ÏÀ» ÃʱâÈÇÏ·Á¸é ´ÙÀ½°ú °°ÀÌ ÇÑ´Ù. rwlock_t mr_rwlock = RW_LOCK_UNLOCKED;
¸®´õÀÎ °æ¿ì¿¡´Â ´ÙÀ½°ú °°ÀÌ »ç¿ëÇÑ´Ù.
read_lock(&mr_rwlock);
¶óÀÌÅÍÀÎ °æ¿ì¿¡´Â ´ÙÀ½°ú °°ÀÌ »ç¿ëÇÑ´Ù.
/* critical section (read only) ... */
read_unlock(&mr_rwlock);
write_lock(&mr_lock);
¸®´õ·ÏÀ» ÇÑ »óÅ¿¡¼ ¶óÀÌÆ®·ÏÀ» ÇÒ ¼ö ¾ø´Ù.
/* critical section (read and write) ... */
write_unlock(&mr_rwlock);
read_lock(&mr_rwlock);
write_lock(&mr_rwlock);
ÀÌ¿Í °°Àº °æ¿ì¿£ µ¥µå·Ï¿¡ ºüÁö°Ô µÈ´Ù.
¸¸¾à, ¸®´õ¿Í ¶óÀÌÅÍ°¡ ¼¯ÀÌ´Â °æ¿ì°¡ ÀÖ´Ù¸é À̶§´Â ½ºÇÉ·ÏÀ» »ç¿ëÇÑ´Ù.
±×¸®°í ÀÎÅÍ·´Æ® Çڵ鷯°¡ ÀÖÀ» ¶§ ÇÁ·Î¼¼½º ÄÁÅؽºÆ®¿¡¼´Â ¸®´õ ½ºÇÉ·ÏÀ» ÀÎÅÍ·´Æ® Çڵ鷯¿¡¼´Â ¶óÀÌÅÍ ½ºÇÉ·ÏÀ» »ç¿ëÇÑ´Ù¸é ÀÎÅÍ·´Æ®¸¦ ºñÈ°¼ºÈ ½ÃÅ°´Â ·ÏÀ» »ç¿ëÇؾ߸¸ ÇÑ´Ù. °ü·Ã ÇÔ¼ö´Â Ã¥ p127ÀÇ Ç¥ 8.4 ¸®´õ-¶óÀÌÅÍ ½ºÇÉ·Ï ÇÔ¼ö¸¦ Âü°íÇ϶ó. 1.4.1. ¼¼¸¶Æ÷¾î¸¦ »ý¼ºÇÏ°í ÃʱâÈ ¶¼¼¸¶Æ÷¾î ±¸ÇöÀº <asm/semaphore.h>¿¡ Á¤ÀǵŠÀÖ´Ù.
ÀÚ·áÇüÀº struct smeaphore ÀÌ´Ù.
¼¼¸¶Æ÷¾î´Â Á¤Àû°ú µ¿ÀûÀ¸·Î »ý¼ºÇÒ ¼ö ÀÖ´Ù.
1.4.2. ¼¼¸¶Æ÷¾î »ç¿ë ¶¼¼¸¶Æ÷¾î¸¦ ¾ò´Â ¹æ¹ýÀ¸·Î´Â µÎ°¡Áö°¡ ÀÖ´Ù.
up(&mr_sem); °ü·ÃÇÔ¼ö´Â Ã¥ p130 Ç¥ 8.5 ¼¼¸¶Æ÷¾î ÇÔ¼ö¸¦ Âü°íÇ϶ó. 1.4.3. ¸®´õ-¶óÀÌÅÍ ¼¼¸¶Æ÷¾î ¶½ºÇÉ·Ï°ú °°Àº ¹æ½ÄÀ¸·Î ½ºÇɷϺ¸´Ù´Â ¼¼¸¶Æ÷¾î¸¦ ÀÌ¿ëÇØ¾ß ÇÏ´Â °æ¿ì¿¡ »ç¿ëÇÑ´Ù.
¸®´õ-¶óÀÌÅÍ ¼¼¸¶Æ÷¾î´Â <linux/rwsem.h>¿¡ Á¤ÀÇµÈ struct rw_semaphore ÀÚ·áÇü¿¡ ÀÇÇØ Ç¥ÇöµÈ´Ù.
¼±¾ð ¹æ¹ýÀº ´ÙÀ½°ú °°´Ù.
1.5. ¿Ï·á º¯¼ö ¶¿Ï·á º¯¼ö(completion variable)´Â Ä¿³ÎÀÇ µÎ ŽºÅ©¸¦ µ¿±âȽÃÅ°±â À§ÇØ »ç¿ëµÇ´Â Æí¸®ÇÑ ¹æ¹ý Áß ÇϳªÀÌ´Ù.
¿Ï·á º¯¼ö´Â <linux/completion.h> Á¤ÀÇµÈ struct completion ÀÚ·áÇü¿¡ ÀÇÇØ Ç¥ÇöµÈ´Ù.
¼±¾ðÀº ´ÙÀ½°ú °°´Ù.
°ü·Ã ÇÔ¼ö´Â Ã¥ p132 Ç¥ 8.7 ¿Ï·á º¯¼ö ÇÔ¼öÀ» Âü°íÇ϶ó. 1.6. Å« Ä¿³Î ·Ï ¶Å« Ä¿³Î ·Ï(Big Kernel Lock(BKL)Àº Àü¿ª ½ºÇÉ·ÏÀÌ´Ù.
1.7. Seq ·Ï ¶Ä¿³Î 2.6¿¡¼ºÎÅÍ µµÀÔµÈ »õ·Î¿î Á¾·ùÀÇ ·ÏÀÌ´Ù. ÀÌ ·ÏÀº ½ÃÄö½º Ä«¿îÅÍ(sequence counter)¸¦ »ç¿ëÇÏ¿© ±¸ÇöµÈ´Ù. ·ÏÀº 0ºÎÅÍ ½ÃÀÛÇÏ¿© ·ÏÀ» Àá±×¸é Ȧ¼ö°¡ µÇ°í ´Ù½Ã ·ÏÀ» Ç®¸é ¦¼ö°¡ µÈ´Ù.
seqlock_t mr_seq_lock = SEQLOCK_UNLOCKED; write_seqlock(&mr_seq_lock); /* write lock is obtained ... */
write_sequnlock(&mr_seq_lock);
unsigned long seq; do { seq = read_seqbegin(&mr_seq_lock);
} while (read_seqretry(&mr_seq_lock, seq));
/* read data here ... */
1.8. ¼±Á¡ÀÇ ºñÈ°¼ºÈ ¶Ä¿³Î ¿ª½Ã ¼±Á¡ÇüÀ̹ǷÎ, Ä¿³Î ¾È¿¡ ÀÖ´Â ÇÁ·Î¼¼½º´Â ¾ðÁ¦¶óµµ ´õ ³ôÀº ¿ì¼±¼øÀ§¸¦ °®´Â ÇÁ·Î¼¼½º¸¦ ½ÇÇà½ÃÅ°±â À§ÇØ Áß´ÜµÉ ¼ö ÀÖ´Ù.
preempt_disable(); /* ¼±Á¡ÀÌ ºñÈ°¼ºÈµÊ ... */
preempt_enable();
°ü·Ã ÇÔ¼ö´Â Ã¥ p136 Ç¥ 8.9 Ä¿³Î ¼±Á¡ °ü·Ã ÇÔ¼ö¸¦ Âü°íÇ϶ó. 1.9. ¹è¸®¾î ¶´Ù¼öÀÇ ÇÁ·Î¼¼¼³ª Çϵå¿þ µð¹ÙÀ̽º°£ÀÇ µ¿±âÈ ¹®Á¦¸¦ ´Ù·ê ¶§´Â, Á¾Á¾ ¸Þ¸ð¸® Àбâ(load)¿Í ¸Þ¸ð¸® ¾²±â(store)¸¦ ÇÁ·Î±×·¥ Äڵ忡 Á¤ÀÇµÈ ¼ø¼´ë·Î ÇàÇØ¾ß ÇÏ´Â °æ¿ì°¡ ¹ß»ýÇÑ´Ù. ¼ø¼¸¦ ¹Ù²ÙÁö ¸»µµ·Ï Áö½ÃÇÏ´Â ¸í·ÉÀ» ¹è¸®¾î(barrier)¶ó°í ÇÑ´Ù.
|
If it pours before seven, it has rained by eleven. |