pintos (4) --Mesa vs. Hoare style

在阅读pintos/src/threads/synch.c的时候,发现了一个令人疑惑的地方:
/* Down or "P" operation on a semaphore. Waits for SEMA's value
to become positive and then atomically decrements it.
This function may sleep, so it must not be called within an
interrupt handler. This function may be called with
interrupts disabled, but if it sleeps then the next scheduled
thread will probably turn interrupts back on. */
void
sema_down (struct semaphore *sema)
{
    enum intr_level old_level;

    ASSERT (sema != NULL);
    ASSERT (!intr_context ());

    old_level = intr_disable ();
    while (sema->value == 0)
    {
        list_push_back (&sema->waiters, &thread_current ()->elem);
        thread_block ();
    }
    sema->value--;
    intr_set_level (old_level);
}
这个函数是信号量的P操作,完成的功能就是
  1. 关中断
  2. 判断信号量是否为0
    • 如果为0,当前进程加入该sema等待队列
    • 不为0,sema–,继续执行
  3. 还原中断

第16行使用了while而不是if,为什么要在这里循环呢?
sema为0陷入阻塞之后,一定是被V操作唤醒的,既然是V操作,那么sema一定不为0,while的意义在哪里呢?


先来看一下V操作:

/* Up or "V" operation on a semaphore.  Increments SEMA's value
   and wakes up one thread of those waiting for SEMA, if any.
   This function may be called from an interrupt handler. */
void
sema_up (struct semaphore *sema) 
{
  enum intr_level old_level;

  ASSERT (sema != NULL);

  old_level = intr_disable ();
  if (!list_empty (&sema->waiters)) 
    thread_unblock (list_entry (list_pop_front (&sema->waiters),
                                struct thread, elem));
  sema->value++;
  intr_set_level (old_level);
}
V操作做了如下的事情
  1. 关中断
  2. 如果waiters队列有进程,执行thread_unblock()
  3. sema++
  4. 还原中断

好像没什么不对的

再来看一下thread_unblock()的实现:
/* Transitions a blocked thread T to the ready-to-run state.
   This is an error if T is not blocked.  (Use thread_yield() to
   make the running thread ready.)
   This function does not preempt the running thread.  This can
   be important: if the caller had disabled interrupts itself,
   it may expect that it can atomically unblock a thread and
   update other data. */
void
thread_unblock (struct thread *t) 
{
  enum intr_level old_level;

  ASSERT (is_thread (t));

  old_level = intr_disable ();
  ASSERT (t->status == THREAD_BLOCKED);
  list_push_back (&ready_list, &t->elem);
  t->status = THREAD_READY;
  intr_set_level (old_level);
}
thread_unblock()做了如下的事情
  1. 关中断
  2. 将进程添加到ready_list,设置状态为READY
  3. 还原中断

竟然没有进行调度!


OK进入正题:

Mesa vs. Hoare style
  • Hoare style:V操作后立即进行调度。
  • Mesa style:V操作后只将进程unblock,然后继续运行等待系统进行调度。

显然PintOs采用的是Mesa style,所以,被unblock的进程在被调度的时候,sema并不一定可用,比如其他进程又进行了P操作,所以必须再次检查sema,如果不可用则继续block,这就是使用while而不是if的理由。

为什么不立即调度呢?这就是他的优点,不立即调度而是等待系统调度,就减少了调度次数,而每次切换上下文都是繁重的工作,进而降低了系统开销。


相关链接:

http://blog.youkuaiyun.com/xiaoguobaf/article/details/52174285
http://blog.chinaunix.net/uid-20545494-id-1929545.html
https://github.com/windr0id/pintos/issues/1

Setting up libwayland-server0:amd64 (1.22.0-2.1build1) ... Setting up libx11-xcb1:amd64 (2:1.8.7-1build1) ... Setting up libpciaccess0:amd64 (0.17-3build1) ... Setting up session-migration (0.3.9build1) ... Created symlink /etc/systemd/user/graphical-session-pre.target.wants/session-migration.service → /usr/lib/systemd/user/session-migration.service. Setting up fontconfig (2.15.0-1.1ubuntu2) ... Regenerating fonts cache... done. Setting up libraw1394-11:amd64 (2.1.2-2build3) ... Setting up libgck-2-2:amd64 (4.2.0-5) ... Setting up libproxy1v5:amd64 (0.5.4-4build1) ... Setting up libdrm-nouveau2:amd64 (2.4.122-1~ubuntu0.24.04.1) ... Setting up libtag1v5-vanilla:amd64 (1.13.1-1build1) ... Setting up libxdamage1:amd64 (1:1.1.6-1build1) ... Setting up libxcb-xfixes0:amd64 (1.15-1ubuntu2) ... Setting up libogg0:amd64 (1.3.5-3build1) ... Setting up desktop-file-utils (0.27-2build1) ... Setting up libspeex1:amd64 (1.2.1-2ubuntu2.24.04.1) ... Setting up libcaca0:amd64 (0.99.beta20-4build2) ... Setting up libv4lconvert0t64:amd64 (1.26.1-4build3) ... Setting up libgcr-4-4:amd64 (4.2.0-5) ... Setting up hicolor-icon-theme (0.17-2) ... Setting up libxi6:amd64 (2:1.8.1-1build1) ... Setting up libtwolame0:amd64 (0.4.0-2build3) ... Setting up libwoff1:amd64 (1.0.2-2build1) ... Setting up libxrender1:amd64 (1:0.9.10-1.1build1) ... Setting up libvte-2.91-common (0.76.0-1ubuntu0.1) ... Setting up libhyphen0:amd64 (2.8.8-7build3) ... Setting up libdatrie1:amd64 (0.2.13-3build1) ... Setting up libvisual-0.4-0:amd64 (0.4.2-2build1) ... Setting up libxcb-render0:amd64 (1.15-1ubuntu2) ... Setting up libaspell15:amd64 (0.60.8.1-1build1) ... Setting up libdrm-radeon1:amd64 (2.4.122-1~ubuntu0.24.04.1) ... Setting up libglvnd0:amd64 (1.7.0-1build1) ... Setting up libxcb-glx0:amd64 (1.15-1ubuntu2) ... Setting up libwebpdemux2:amd64 (1.3.2-0.4build3) ... Setting up libmanette-0.2-0:amd64 (0.2.7-1build2) ... Setting up libdrm-intel1:amd64 (2.4.122-1~ubuntu0.24.04.1) ... Setting up libgdk-pixbuf2.0-common (2.42.10+dfsg-3ubuntu3.1) ... Setting up x11-common (1:7.7+23ubuntu3) ... Setting up libwebrtc-audio-processing1:amd64 (0.3.1-0ubuntu6) ... Setting up libxcb-shm0:amd64 (1.15-1ubuntu2) ... Setting up libsoup-3.0-common (3.4.4-5ubuntu0.3) ... Setting up libmpg123-0t64:amd64 (1.32.5-1ubuntu1.1) ... Setting up libcairo2:amd64 (1.18.0-3build1) ... Setting up libcolord2:amd64 (1.4.7-1build2) ... Setting up gnome-terminal-data (3.52.0-1ubuntu2) ... Setting up libxxf86vm1:amd64 (1:1.1.4-1build4) ... Setting up liborc-0.4-0t64:amd64 (1:0.4.38-1ubuntu0.1) ... Setting up libxcb-present0:amd64 (1.15-1ubuntu2) ... Setting up libdconf1:amd64 (0.40.0-4build2) ... Setting up libasound2-data (1.2.11-1build2) ... Setting up libgles2:amd64 (1.7.0-1build1) ... Setting up libasound2t64:amd64 (1.2.11-1build2) ... Setting up emacsen-common (3.0.5) ... Setting up libepoxy0:amd64 (1.5.10-1build1) ... Setting up libspa-0.2-modules:amd64 (1.0.5-1ubuntu3) ... Setting up libxfixes3:amd64 (1:6.0.0-2build1) ... Setting up libxcb-sync1:amd64 (1.15-1ubuntu2) ... Setting up libavahi-common-data:amd64 (0.8-13ubuntu6) ... Setting up libatspi2.0-0t64:amd64 (2.52.0-1build1) ... Setting up libopus0:amd64 (1.4-1build1) ... Setting up libxinerama1:amd64 (2:1.1.4-3build1) ... Setting up libxv1:amd64 (2:1.0.11-1.1build1) ... Setting up libatomic1:amd64 (14.2.0-4ubuntu2~24.04) ... Setting up libvorbis0a:amd64 (1.3.7-1build3) ... Setting up libxrandr2:amd64 (2:1.5.2-2build1) ... Setting up libnautilus-extension4:amd64 (1:46.2-0ubuntu0.3) ... Setting up libdv4t64:amd64 (1.0.0-17.1build1) ... Setting up libglapi-mesa:amd64 (24.2.8-1ubuntu1~24.04.1) ... Setting up libvulkan1:amd64 (1.3.275.0-1build1) ... Setting up libv4l-0t64:amd64 (1.26.1-4build3) ... Setting up libxcb-dri2-0:amd64 (1.15-1ubuntu2) ... Setting up xdg-dbus-proxy (0.1.5-1build2) ... Setting up libvpx9:amd64 (1.14.0-1ubuntu2.1) ... Setting up alsa-topology-conf (1.2.5.1-2) ... Setting up libtag1v5:amd64 (1.13.1-1build1) ... Setting up libasyncns0:amd64 (0.8-6build4) ... Setting up libxshmfence1:amd64 (1.3-1build5) ... Setting up at-spi2-common (2.52.0-1build1) ... Setting up libwavpack1:amd64 (5.6.0-1build1) ... Setting up libxcb-randr0:amd64 (1.15-1ubuntu2) ... Setting up libtheora0:amd64 (1.1.1+dfsg.1-16.1build3) ... Setting up libharfbuzz0b:amd64 (8.3.0-2build2) ... Setting up libthai-data (0.1.29-2build1) ... Setting up libgdk-pixbuf-2.0-0:amd64 (2.42.10+dfsg-3ubuntu3.1) ... Setting up sgml-data (2.0.11+nmu1) ... Setting up libcairo-gobject2:amd64 (1.18.0-3build1) ... Setting up libflac12t64:amd64 (1.4.3+ds-2.1ubuntu2) ... Setting up libwayland-egl1:amd64 (1.22.0-2.1build1) ... Setting up libhunspell-1.7-0:amd64 (1.7.2+really1.7.2-10build3) ... Setting up glib-networking-common (2.80.0-1build1) ... Setting up libwebpmux3:amd64 (1.3.2-0.4build3) ... Setting up gvfs-common (1.54.0-1ubuntu2) ... Setting up libxcomposite1:amd64 (1:0.4.5-1build3) ... Setting up libpipewire-0.3-0t64:amd64 (1.0.5-1ubuntu3) ... Setting up libsecret-common (0.21.4-1build3) ... Setting up yelp-xsl (42.1-2ubuntu0.24.04.1) ... Setting up libmp3lame0:amd64 (3.100-6build1) ... Setting up libgraphene-1.0-0:amd64 (1.10.8-3build2) ... Setting up libvorbisenc2:amd64 (1.3.7-1build3) ... Setting up libaa1:amd64 (1.4p5-51.1) ... Setting up libiec61883-0:amd64 (1.2.0-6build1) ... Setting up libdrm-amdgpu1:amd64 (2.4.122-1~ubuntu0.24.04.1) ... Setting up libwayland-client0:amd64 (1.22.0-2.1build1) ... Setting up libavc1394-0:amd64 (0.5.4-5build3) ... Setting up libgl1-amber-dri:amd64 (21.3.9-0ubuntu2) ... Setting up mesa-vulkan-drivers:amd64 (24.2.8-1ubuntu1~24.04.1) ... Setting up glib-networking-services (2.80.0-1build1) ... Setting up gtk-update-icon-cache (3.24.41-4ubuntu1.3) ... Setting up mesa-libgallium:amd64 (24.2.8-1ubuntu1~24.04.1) ... Setting up libharfbuzz-icu0:amd64 (8.3.0-2build2) ... Setting up xdg-desktop-portal (1.18.4-1ubuntu2.24.04.1) ... Created symlink /etc/systemd/user/graphical-session-pre.target.wants/xdg-desktop-portal-rewrite-launchers.service → /usr/lib/systemd/user/xdg-desktop-portal-rewrite-launchers.service. Setting up libatk1.0-0t64:amd64 (2.52.0-1build1) ... Setting up libgbm1:amd64 (24.2.8-1ubuntu1~24.04.1) ... Setting up dictionaries-common (1.29.7) ... Setting up alsa-ucm-conf (1.2.10-1ubuntu5.4) ... Setting up libxtst6:amd64 (2:1.2.3-1.1build1) ... Setting up libxcursor1:amd64 (1:1.2.1-1build1) ... Setting up libgl1-mesa-dri:amd64 (24.2.8-1ubuntu1~24.04.1) ... Setting up libavahi-common3:amd64 (0.8-13ubuntu6) ... Setting up libgstreamer-plugins-base1.0-0:amd64 (1.24.2-1ubuntu0.2) ... Setting up dconf-service (0.40.0-4build2) ... Setting up libthai0:amd64 (0.1.29-2build1) ... Setting up libsecret-1-0:amd64 (0.21.4-1build3) ... Setting up libgstreamer-plugins-good1.0-0:amd64 (1.24.2-1ubuntu1.1) ... Setting up libegl-mesa0:amd64 (24.2.8-1ubuntu1~24.04.1) ... Setting up libjavascriptcoregtk-4.1-0:amd64 (2.48.1-0ubuntu0.24.04.1) ... Setting up gstreamer1.0-plugins-base:amd64 (1.24.2-1ubuntu0.2) ... Setting up libshout3:amd64 (2.4.6-1build2) ... Setting up aspell (0.60.8.1-1build1) ... Setting up libgdk-pixbuf2.0-bin (2.42.10+dfsg-3ubuntu3.1) ... Setting up libwayland-cursor0:amd64 (1.22.0-2.1build1) ... Setting up libegl1:amd64 (1.7.0-1build1) ... Setting up hunspell-en-us (1:2020.12.07-2) ... Setting up libsndfile1:amd64 (1.2.2-1ubuntu5.24.04.1) ... Setting up libavahi-client3:amd64 (0.8-13ubuntu6) ... Setting up libatk-bridge2.0-0t64:amd64 (2.52.0-1build1) ... Setting up libglx-mesa0:amd64 (24.2.8-1ubuntu1~24.04.1) ... Setting up libglx0:amd64 (1.7.0-1build1) ... Setting up dconf-gsettings-backend:amd64 (0.40.0-4build2) ... Setting up libpulse0:amd64 (1:16.1+dfsg1-2ubuntu10.1) ... Setting up libenchant-2-2:amd64 (2.3.3-2build2) ... Setting up libpango-1.0-0:amd64 (1.52.1+ds-1build1) ... Setting up aspell-en (2020.12.07-0-1) ... Setting up enchant-2 (2.3.3-2build2) ... Setting up libgl1:amd64 (1.7.0-1build1) ... Setting up libpangoft2-1.0-0:amd64 (1.52.1+ds-1build1) ... Setting up libcups2t64:amd64 (2.4.7-1.2ubuntu7.3) ... Setting up libgtk-3-common (3.24.41-4ubuntu1.3) ... Setting up libpangocairo-1.0-0:amd64 (1.52.1+ds-1build1) ... Setting up gsettings-desktop-schemas (46.1-0ubuntu1) ... Setting up gstreamer1.0-x:amd64 (1.24.2-1ubuntu0.2) ... Setting up librsvg2-2:amd64 (2.58.0+dfsg-1build1) ... Setting up libgstreamer-gl1.0-0:amd64 (1.24.2-1ubuntu0.2) ... Setting up librsvg2-common:amd64 (2.58.0+dfsg-1build1) ... Setting up gstreamer1.0-gl:amd64 (1.24.2-1ubuntu0.2) ... Setting up adwaita-icon-theme (46.0-1) ... update-alternatives: using /usr/share/icons/Adwaita/cursor.theme to provide /usr/share/icons/default/index.theme (x-cursor-theme) in auto mode Setting up humanity-icon-theme (0.6.16) ... Setting up ubuntu-mono (24.04-0ubuntu1) ... Processing triggers for man-db (2.12.0-4build2) ... Processing triggers for libglib2.0-0t64:amd64 (2.80.0-6ubuntu3.4) ... Setting up libgtk-3-0t64:amd64 (3.24.41-4ubuntu1.3) ... Setting up gvfs-libs:amd64 (1.54.0-1ubuntu2) ... Setting up at-spi2-core (2.52.0-1build1) ... Processing triggers for sgml-base (1.31) ... Setting up glib-networking:amd64 (2.80.0-1build1) ... Setting up libhandy-1-0:amd64 (1.8.3-1build2) ... Setting up xdg-desktop-portal-gtk (1.15.1-1build2) ... Setting up docbook-xml (4.5-12) ... Processing triggers for libc-bin (2.39-0ubuntu8.4) ... Setting up libsoup-3.0-0:amd64 (3.4.4-5ubuntu0.3) ... Setting up libgtk-3-bin (3.24.41-4ubuntu1.3) ... Setting up libvte-2.91-0:amd64 (0.76.0-1ubuntu0.1) ... Setting up gvfs-daemons (1.54.0-1ubuntu2) ... Setting up gnome-terminal (3.52.0-1ubuntu2) ... update-alternatives: using /usr/bin/gnome-terminal.wrapper to provide /usr/bin/x-terminal-emulator (x-terminal-emulator) in auto mode Setting up gvfs:amd64 (1.54.0-1ubuntu2) ... Setting up gstreamer1.0-plugins-good:amd64 (1.24.2-1ubuntu1.1) ... Setting up nautilus-extension-gnome-terminal:amd64 (3.52.0-1ubuntu2) ... Setting up libwebkit2gtk-4.1-0:amd64 (2.48.1-0ubuntu0.24.04.1) ... Setting up libyelp0:amd64 (42.2-1ubuntu0.24.04.1) ... Setting up yelp (42.2-1ubuntu0.24.04.1) ... Processing triggers for dictionaries-common (1.29.7) ... aspell-autobuildhash: processing: en [en-common]. aspell-autobuildhash: processing: en [en-variant_0]. aspell-autobuildhash: processing: en [en-variant_1]. aspell-autobuildhash: processing: en [en-variant_2]. aspell-autobuildhash: processing: en [en-w_accents-only]. aspell-autobuildhash: processing: en [en-wo_accents-only]. aspell-autobuildhash: processing: en [en_AU-variant_0]. aspell-autobuildhash: processing: en [en_AU-variant_1]. aspell-autobuildhash: processing: en [en_AU-w_accents-only]. aspell-autobuildhash: processing: en [en_AU-wo_accents-only]. aspell-autobuildhash: processing: en [en_CA-variant_0]. aspell-autobuildhash: processing: en [en_CA-variant_1]. aspell-autobuildhash: processing: en [en_CA-w_accents-only]. aspell-autobuildhash: processing: en [en_CA-wo_accents-only]. aspell-autobuildhash: processing: en [en_GB-ise-w_accents-only]. aspell-autobuildhash: processing: en [en_GB-ise-wo_accents-only]. aspell-autobuildhash: processing: en [en_GB-ize-w_accents-only]. aspell-autobuildhash: processing: en [en_GB-ize-wo_accents-only]. aspell-autobuildhash: processing: en [en_GB-variant_0]. aspell-autobuildhash: processing: en [en_GB-variant_1]. aspell-autobuildhash: processing: en [en_US-w_accents-only]. aspell-autobuildhash: processing: en [en_US-wo_accents-only]. Processing triggers for libgdk-pixbuf-2.0-0:amd64 (2.42.10+dfsg-3ubuntu3.1) ... Processing triggers for sgml-base (1.31) ... Processing triggers for libc-bin (2.39-0ubuntu8.4) ... Scanning processes... Scanning linux images... Running kernel seems to be up-to-date. No services need to be restarted. No containers need to be restarted. No user sessions are running outdated binaries. No VM guests are running outdated hypervisor (qemu) binaries on this host. # Failed to parse arguments: Cannot open display: root@srv771# 使用虚拟控制台(按Ctrl+Alt+F1-F6进入tty终端)y终端) # 返回图形界面按Ctrl+Alt+F7 root@srv771551:~# ^C root@srv771551:~# ^C root@srv771551:~#
最新发布
05-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值