Chinaunix首页 | 论坛 | 博客
  • 博客访问: 174263
  • 博文数量: 60
  • 博客积分: 677
  • 博客等级: 上士
  • 技术积分: 667
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-30 15:49
文章分类

全部博文(60)

文章存档

2015年(1)

2013年(6)

2012年(16)

2011年(9)

2010年(28)

我的朋友

分类: BSD

2012-08-24 17:29:38


点击(此处)折叠或打开

  1. /*
  2.  * Block the current thread on the turnstile assicated with 'lock'. This
  3.  * function will context switch and not return until this thread has been
  4.  * woken back up. This function must be called with the appropriate
  5.  * turnstile chain locked and will return with it unlocked.
  6.  */
  7. void
  8. turnstile_wait(struct turnstile *ts, struct thread *owner, int queue)
  9. {
  10.     struct turnstile_chain *tc;
  11.     struct thread *td, *td1;
  12.     struct lock_object *lock;

  13.     td = curthread;
  14.     /*一些断言,当前线程是不是拥有turnstile的锁,输入是否合理*/
  15.     mtx_assert(&ts->ts_lock, MA_OWNED);
  16.     if (owner)
  17.         MPASS(owner->td_proc->p_magic == P_MAGIC);
  18.     MPASS(queue == TS_SHARED_QUEUE || queue == TS_EXCLUSIVE_QUEUE);

  19.     /*
  20.      * If the lock does not already have a turnstile, use this thread's
  21.      * turnstile. Otherwise insert the current thread into the
  22.      * turnstile already in use by this lock.
  23.      * 没有turnstile则用自己的新建一个(每个kernel线程是绑定一个turnstile的)
  24.      * 有就用现成的,把自己放到turnstile即可。
  25.      */
  26.     tc = TC_LOOKUP(ts->ts_lockobj); /*根据锁找turnstile chain*/
  27.     if (ts == td->td_turnstile) {/*这个这个turnstile就是自己线程的turnstile,看
  28.                                    turnstile_trywait函数 */
  29.     mtx_assert(&tc->tc_lock, MA_OWNED);
  30. #ifdef TURNSTILE_PROFILING
  31.         tc->tc_depth++;
  32.         if (tc->tc_depth > tc->tc_max_depth) {
  33.             tc->tc_max_depth = tc->tc_depth;
  34.             if (tc->tc_max_depth > turnstile_max_depth)
  35.                 turnstile_max_depth = tc->tc_max_depth;
  36.         }
  37. #endif
  38.         tc = TC_LOOKUP(ts->ts_lockobj); /*又来??*/
  39.         LIST_INSERT_HEAD(&tc->tc_turnstiles, ts, ts_hash);/*加入turnstile chain*/
  40.         KASSERT(TAILQ_EMPTY(&ts->ts_pending),
  41.          ("thread's turnstile has pending threads"));
  42.         KASSERT(TAILQ_EMPTY(&ts->ts_blocked[TS_EXCLUSIVE_QUEUE]),
  43.          ("thread's turnstile has exclusive waiters"));
  44.         KASSERT(TAILQ_EMPTY(&ts->ts_blocked[TS_SHARED_QUEUE]),
  45.          ("thread's turnstile has shared waiters"));
  46.         KASSERT(LIST_EMPTY(&ts->ts_free),
  47.          ("thread's turnstile has a non-empty free list"));
  48.         MPASS(ts->ts_lockobj != NULL);
  49.         /*加入到本turnstile的等待队列,居然turnstile的owner也是当前锁的owner*/
  50.         mtx_lock_spin(&td_contested_lock);
  51.         TAILQ_INSERT_TAIL(&ts->ts_blocked[queue], td, td_lockq);
  52.         turnstile_setowner(ts, owner);
  53.         mtx_unlock_spin(&td_contested_lock);
  54.     } else {
  55.         /*turnstile里的等待该锁的所有线程是按优先级排序的*/
  56.         TAILQ_FOREACH(td1, &ts->ts_blocked[queue], td_lockq)
  57.             if (td1->td_priority > td->td_priority)
  58.                 break;
  59.         mtx_lock_spin(&td_contested_lock);
  60.         if (td1 != NULL)
  61.             TAILQ_INSERT_BEFORE(td1, td, td_lockq);
  62.         else
  63.             TAILQ_INSERT_TAIL(&ts->ts_blocked[queue], td, td_lockq);
  64.         MPASS(owner == ts->ts_owner);
  65.         mtx_unlock_spin(&td_contested_lock);
  66.         MPASS(td->td_turnstile != NULL);
  67.         LIST_INSERT_HEAD(&ts->ts_free, td->td_turnstile, ts_hash);/*我不知道ts_free干啥的*/
  68.     }
  69.     thread_lock(td);
  70.     thread_lock_set(td, &ts->ts_lock);
  71.     td->td_turnstile = NULL;/*看来一个thread的turnstile要么就用给lock对象,要么就放到ts_free里*/

  72.     /* Save who we are blocked on and switch. 记录当前线程的状态,卡住了?卡哪里了?*/
  73.     lock = ts->ts_lockobj;
  74.     td->td_tsqueue = queue;
  75.     td->td_blocked = ts;
  76.     td->td_lockname = lock->lo_name;
  77.     td->td_blktick = ticks;
  78.     TD_SET_LOCK(td);
  79.     mtx_unlock_spin(&tc->tc_lock);
  80.     propagate_priority(td);/*很重要的一步,优先级传播*/

  81.     if (LOCK_LOG_TEST(lock, 0))
  82.         CTR4(KTR_LOCK, "%s: td %d blocked on [%p] %s", __func__,
  83.          td->td_tid, lock, lock->lo_name);

  84.     THREAD_LOCKPTR_ASSERT(td, &ts->ts_lock);
  85.     mi_switch(SW_VOL | SWT_TURNSTILE, NULL);

  86.     if (LOCK_LOG_TEST(lock, 0))
  87.         CTR4(KTR_LOCK, "%s: td %d free from blocked on [%p] %s",
  88.          __func__, td->td_tid, lock, lock->lo_name);
  89.     thread_unlock(td);
  90. }

阅读(582) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~