Download presentation
Presentation is loading. Please wait.
1
報告者 : 彭敏君 ANT 實驗室 2011/03/24 Concurrency and Race Conditions
2
outline 5.0. 引言 5.1. scull 缺陷 5.2. Concurrency and Its Management 5.3. Semaphores and Mutex 5.4. Completions 機制 5.5. Spinlocks 5.6. 鎖定機制的使用準則 5.7. 鎖定機制外的選擇
3
引言 Scull 存在缺陷的原因 早期 Linux 不支援 SMP 只有在 hardware interrupt 會發生 concurrency
4
Scull 以下是 Scull 中的一段程式碼 if (!dptr->data[s_pos]) { dptr->data[s_pos] = kmalloc(quantum, GFP_KERNEL); if (!dptr->data[s_pos]) goto out; } 假設有兩個 process (A and B) 都執行到 if (!dptr->data[s_pos]) 則 ?
5
Concurrency and Its Managemen Linux 自 2.6 版本後加入了可插隊 目前的系統大多都是 SMP 架構 熱插拔
6
Semaphores and Mutex void sema_init(struct semaphore *sem, int val); DECLARE_MUTEX(name); //1 DECLARE_MUTEX_LOCKED(name);//0 void init_MUTEX(struct semaphore *sem); void init_MUTEX_LOCKED(struct semaphore *sem);
7
Semaphores and Mutex Down up void down(struct semaphore *sem); int down_interruptible(struct semaphore *sem); int down_trylock(struct semaphore *sem); void up(struct semaphore *sem);
8
Semaphores and Mutex 複習一下 Scull_dev 的結構 struct scull_dev { struct scull_qset *data; /* Pointer to first quantum set */ int quantum; /* the current quantum size */ int qset; /* the current array size */ unsigned long size; /* amount of data stored here */ unsigned int access_key; /* used by sculluid and scullpriv */ struct semaphore sem; /* mutual exclusion semaphore */ struct cdev cdev; /* Char device structure */ };
9
Semaphores and Mutex Scull 初始化 for (i = 0; i < scull_nr_devs; i++) { scull_devices[i].quantum = scull_quantum; scull_devices[i].qset = scull_qset; sema_init(&scull_devices[i].sem, 1); scull_setup_cdev(&scull_devices[i], i); }
10
Semaphores and Mutex Reader void init_rwsem(struct rw_semaphore *sem); void down_write(struct rw_semaphore *sem); int down_write_trylock(struct rw_semaphore *sem); void up_write(struct rw_semaphore *sem); void downgrade_write(struct rw_semaphore *sem);
11
Semaphores and Mutex Writer void down_write(struct rw_semaphore *sem); int down_write_trylock(struct rw_semaphore *sem); void up_write(struct rw_semaphore *sem); void downgrade_write(struct rw_semaphore *sem);
12
Completions 等候完成 完成通知 DECLARE_COMPLETION(my_completion); void wait_for_completion(struct completion *c); void complete(struct completion *c); void complete_all(struct completion *c);
13
Completions Read Write ssize_t complete_read (struct file *filp, char __user *buf, size_t count, loff_t *pos){ printk(KERN_DEBUG "process %i (%s) going to sleep\n",current->pid, current- >comm); wait_for_completion(&comp); printk(KERN_DEBUG "awoken %i (%s)\n", current->pid, current->comm); ] return 0; /* EOF */ } ssize_t complete_write (struct file *filp, const char __user *buf, size_t count, loff_t *pos) { printk(KERN_DEBUG "process %i (%s) awakening the readers...\n", current- >pid, current->comm); complete(&comp); return count; /* succeed, to avoid retrial */ }
14
Spinlocks spinlock_t my_lock = SPIN_LOCK_UNLOCKED; void spin_lock_init(spinlock_t *lock); Lock void spin_lock(spinlock_t *lock); unLock void spin_unlock(spinlock_t *lock);
15
Spinlocks Lock void spin_lock(spinlock_t *lock); void spin_lock_irqsave(spinlock_t *lock, unsigned long flags); void spin_lock_irq(spinlock_t *lock); void spin_lock_bh(spinlock_t *lock) unLock void spin_unlock(spinlock_t *lock); void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags); void spin_unlock_irq(spinlock_t *lock); void spin_unlock_bh(spinlock_t *lock);
16
Spinlocks tryLock int spin_trylock(spinlock_t *lock); int spin_trylock_bh(spinlock_t *lock);
17
Spinlocks Read void read_lock(rwlock_t *lock); void read_lock_irqsave(rwlock_t *lock, unsigned long flags); void read_lock_irq(rwlock_t *lock); void read_lock_bh(rwlock_t *lock); void read_unlock(rwlock_t *lock); void read_unlock_irqrestore(rwlock_t *lock, unsigned long flags); void read_unlock_irq(rwlock_t *lock); void read_unlock_bh(rwlock_t *lock);
18
Spinlocks Write void write_lock(rwlock_t *lock); void write_lock_irqsave(rwlock_t *lock, unsigned long flags); void write_lock_irq(rwlock_t *lock); void write_lock_bh(rwlock_t *lock); int write_trylock(rwlock_t *lock); void write_unlock(rwlock_t *lock); void write_unlock_irqrestore(rwlock_t *lock, unsigned long flags); void write_unlock_irq(rwlock_t *lock); void write_unlock_bh(rwlock_t *lock);
19
鎖定機制的使用準則 規則明確 不同時鎖定多個資源 規劃時仔細考慮鎖定的區間
20
鎖定機制外的選擇 無所演算法 連動運算 位元運算 Ready-Copy-Upate (RCU)
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.