<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Sue Loh's blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/sloh/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/sloh/feed.xml</link>
    <description>Random spurts of inspired discussion</description>
    <lastBuildDate>Tue, 16 Apr 2019 05:27:48 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>DirectX managed redistributable</title>
      <link>https://docs.microsoft.com/archive/blogs/sloh/directx-managed-redistributable</link>
      <pubDate>Fri, 03 Feb 2006 00:52:00 GMT</pubDate>
      <dc:creator><![CDATA[sloh]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sloh/2006/02/03/directx-managed-redistributable/</guid>
      <description><![CDATA[Sorry for the problems you've had running the "Whack-a-PM" sample program.&nbsp; It requires the...]]></description>
      <content:encoded><![CDATA[<p>Sorry for the problems you've had running the "Whack-a-PM" sample program.&nbsp; It requires the managed DirectX redistributable package, which you can now download from here:</p>
<p><a href="https://thelohs.net/wumpus/DirectX_managed_redist.zip">https://thelohs.net/wumpus/DirectX_managed_redist.zip</a>&nbsp;(about 3MB)</p>
<p>This file is password-protected just like the samples were, with the same password.&nbsp; If you don't remember the password, ask Mr. Ghebru or email us.</p>
<p>Sue &amp; Rob</p>]]></content:encoded>
    </item>
    <item>
      <title>Week 2: Object-oriented Design and Visual J# Projects</title>
      <link>https://docs.microsoft.com/archive/blogs/sloh/week-2-object-oriented-design-and-visual-j-projects</link>
      <pubDate>Thu, 02 Feb 2006 19:38:00 GMT</pubDate>
      <dc:creator><![CDATA[sloh]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sloh/2006/02/02/week-2-object-oriented-design-and-visual-j-projects/</guid>
      <description><![CDATA[This week's lecture is about object-oriented design, and how we're going to do the design for our...]]></description>
      <content:encoded><![CDATA[<p>This week's lecture is about object-oriented design, and how we're going to do the design for our Hunt the Wumpus game.&nbsp; We'll also cover what a "project" is in Visual J# and how to create your own.&nbsp; This will be the first step of building your part of the Hunt the Wumpus game.</p>
<p>This week's assignment is to do the second of the two required modifications to the "CD Library" sample program, and to create a "calculator" program.&nbsp; You'll build a graphical interface that you can type into and use to do simple arithmetic calculations.</p>
<p>Sue</p>]]></content:encoded>
    </item>
    <item>
      <title>Week 1: The game and the sample code</title>
      <link>https://docs.microsoft.com/archive/blogs/sloh/week-1-the-game-and-the-sample-code</link>
      <pubDate>Mon, 23 Jan 2006 00:24:00 GMT</pubDate>
      <dc:creator><![CDATA[sloh]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sloh/2006/01/23/week-1-the-game-and-the-sample-code/</guid>
      <description><![CDATA[This week's lecture is a more detailed description of the Hunt the Wumpus game you will be building,...]]></description>
      <content:encoded><![CDATA[<p>This week's lecture is a more detailed description of the Hunt the Wumpus game you will be building, and&nbsp;an introduction to the sample code.&nbsp; The sample code is not related to the game at all, but you'll be referring to it&nbsp;as an example of how to implement the things you'll need to implement in J#.&nbsp; You can find the samples here: <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><a title="https://www.thelohs.net/wumpus/Wumpus Samples 2k5.zip" href="https://www.thelohs.net/wumpus/Wumpus Samples 2k5.zip">https://www.thelohs.net/wumpus/Wumpus Samples 2k5.zip</a>&nbsp; </span>The file is password-protected, to minimize how much it spreads across the web.&nbsp; We'll be giving the password out in class.</p>
<p>The first assignment handout is slightly confusing.&nbsp; You'll see that it lists two "required" modifications and three "additional" modifications.&nbsp; This week's assignment is to choose ONE of the required modifications and ONE of the additional modifications, and do those.&nbsp; Have them done by next week's class.&nbsp; If you have any problems or questions, you can ask Mr. Ghebru, or email us at the HTW-ATL address.</p>
<p>Sue</p>]]></content:encoded>
    </item>
    <item>
      <title>Now actively recruiting Atlanta Hunt the Wumpus Mentors</title>
      <link>https://docs.microsoft.com/archive/blogs/sloh/now-actively-recruiting-atlanta-hunt-the-wumpus-mentors</link>
      <pubDate>Thu, 01 Dec 2005 10:51:00 GMT</pubDate>
      <dc:creator><![CDATA[sloh]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sloh/2005/12/01/now-actively-recruiting-atlanta-hunt-the-wumpus-mentors/</guid>
      <description><![CDATA[I posted an initial notification but then spent time trying to find a school to work with...]]></description>
      <content:encoded><![CDATA[<P>I <a href="https://blogs.msdn.com/sloh/archive/2005/09/12/463846.aspx">posted an initial notification </A>but then spent time trying to find a school to work with first.&nbsp; I'm pleased to announce that the Saint Pius X high school (<A href="https://www.spx.org">www.spx.org</A>) has agreed to participate in our Hunt the Wumpus program.&nbsp; I'm now going back to recruiting volunteer mentors.&nbsp; I need to recruit 2-3 people in addition to myself and the teacher Abe Ghebru.</P>
<P>The&nbsp;primary commitment is to particpate in one initial training day and then&nbsp;one class session per week, Fridays at 2pm mostly in February and March.&nbsp; Here is the tentative schedule:</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: none; mso-list-change: · 'Sue Loh' 20051127T1709">1/20/05&nbsp;– Kick off program with students.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Mentors visit during class to introduce themselves and psych up the students.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: none; mso-list-change: · 'Sue Loh' 20051127T1710">1/21/06 (Saturday) – <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><st1:City w:st="on"><st1:place w:st="on">Mentor</st1:place></st1:City>/Teacher training session, several hours.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: none; mso-list-change: · 'Evan F. Goldring' 20051010T2033">1/27 – HTW mentor session #1</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">2/3 – mentor session #2</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">2/10 – mentor session #3</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">2/17 – mentor session #4</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">2/24 – mentor session #5</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">3/3 – mentor session #6</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">3/10 – mentor session #7</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">3/17 – mentor session #8</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">3/24 – mentor session #9</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">3/31 – mentor session #10</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: none; mso-list-change: · 'Evan F. Goldring' 20051010T2033">4/7 – no class</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">4/14 – no class</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">4/21 – no HTW, students study for AP exam!</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">4/28 – no HTW, students study for AP exam!</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: none; mso-list-change: · 'Evan F. Goldring' 20051010T2033">5/2 – AP Exam</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-list: none; mso-list-change: · 'Evan F. Goldring' 20051010T2033">5/5 – mentor session #11</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">5/12 – mentor session #12</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">5/19 – Final meeting.<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;Student</SPAN> presentation of their project!</P>
<P>
<P>The schedule is still tentative right now; the actual curriculum is only 10 sessions so we may remove a couple from this list.&nbsp; Mentors do not have to be able to make it to all of the class sessions, but if they'd have to miss too many it would make life tougher on everyone else.</P>
<P>In addition to the class sessions, mentors will end up spending some preparation time and probably some time interacting with students on the side.&nbsp; The official quote is a commitment of 5 hours of work&nbsp;per week, though in practice it will likely be front-loaded where the program takes that much time at first and diminishes over time.</P>
<P>If you are interested in participating, please contact me through the "contact" link to the left.</P>
<P></P>]]></content:encoded>
    </item>
    <item>
      <title>Hunt the Wumpus in Atlanta</title>
      <link>https://docs.microsoft.com/archive/blogs/sloh/hunt-the-wumpus-in-atlanta</link>
      <pubDate>Mon, 12 Sep 2005 00:29:00 GMT</pubDate>
      <dc:creator><![CDATA[sloh]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sloh/2005/09/12/hunt-the-wumpus-in-atlanta/</guid>
      <description><![CDATA[I'm looking to recruit other software folks to help teach software engineering practices as part of...]]></description>
      <content:encoded><![CDATA[<P>I'm looking to recruit other software folks to help teach software engineering practices as part of our Hunt the Wumpus program.&nbsp; This project is something that Microsoft has already been running in the Seattle area for several years, and I am looking to bring it to Atlanta.</P>
<P>You wouldn't have to be employed by or affiliated with Microsoft at all in order to help.&nbsp; Here is how the program works.&nbsp; We go to a local high school which runs an AP computer science class.&nbsp; We&nbsp;ask the AP CS teacher to take a look at their students, and find the top 6 or so who really could breeze through the class since they know a lot already.&nbsp; The CS teacher puts those students on an accelerated track, where they get done with the assigned classwork by late January or so.&nbsp; Then, from approx. Feb through April (schedule depends on local AP testing schedule)&nbsp;we (this is where you come in) meet with the students once a week during their regular AP class time, and lead them through a software engineering project as a real project team.&nbsp; The project is to build a "Hunt the Wumpus" game (you know HTW right? if not do a web search and you'll find it), complete with planning, individual implementation of the components, integration, testing.&nbsp; The students will be using the .NET framework to build everything.&nbsp; At the end, the students do a presentation about their project.&nbsp; (If this really takes off we can have a local Wumpus competition like they do in Seattle, but I'm aiming for only a single school this inaugural year in Atlanta.)&nbsp; Then we "give them back" to their AP CS teacher about a month before the AP exam, for final test preparation.</P>
<P>The Hunt the Wumpus project is something that Microsoft has already been running in the Seattle area for several years, and invested enough to develop a full professionally-produced curriculum.&nbsp; We'd already have all the materials, schedule, lesson plans we'd need.&nbsp; Your commitment would be 1 hour of classroom time each week from approx. Feb-April, plus probably some out-of-class time helping out the students on the side.&nbsp; The official estimate is max. 5 hours per week, where really it's less than that after you get rolling.</P>
<P>I'm looking for people in Atlanta who would like to help&nbsp;the students, especially folks who know&nbsp;are familiar with C#/.NET&nbsp;but that is not a requirement.&nbsp; And for fairness I should say, I myself am NOT a .NET programmer (yet).&nbsp; I spend all of my time&nbsp;working with&nbsp;C / C++.&nbsp; This would be the first year running this&nbsp;program in Atlanta but we hope to turn it into an annual event to inspire kids around the area to go into computer science.&nbsp; Please contact me via my blog <a href="https://blogs.msdn.com/sloh/">https://blogs.msdn.com/sloh/</A>&nbsp;if you would like to be involved.</P>
<P>Sue</P>]]></content:encoded>
    </item>
    <item>
      <title>[MIT enews] When I Testified Before Congress</title>
      <link>https://docs.microsoft.com/archive/blogs/sloh/mit-enews-when-i-testified-before-congress</link>
      <pubDate>Wed, 13 Jul 2005 10:56:00 GMT</pubDate>
      <dc:creator><![CDATA[sloh]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sloh/2005/07/13/mit-enews-when-i-testified-before-congress/</guid>
      <description><![CDATA[A thought-provoking article about the state of science and engineering education in the...]]></description>
      <content:encoded><![CDATA[<P>A thought-provoking article about the state of science and engineering education in the U.S.</P>
<P><A href="https://mit.edu/engineering/enews/feature.html">https://mit.edu/engineering/enews/feature.html</A></P>
<P>&nbsp;</P>]]></content:encoded>
    </item>
    <item>
      <title>Windows Embedded Challenge ROCKS!</title>
      <link>https://docs.microsoft.com/archive/blogs/sloh/windows-embedded-challenge-rocks</link>
      <pubDate>Sat, 18 Jun 2005 23:54:00 GMT</pubDate>
      <dc:creator><![CDATA[sloh]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sloh/2005/06/18/windows-embedded-challenge-rocks/</guid>
      <description><![CDATA[I know I said I'd be blogging on the ce_base team blog now, but I figured my personal blog is a...]]></description>
      <content:encoded><![CDATA[<P>I know I said I'd be blogging on the ce_base team blog now, but I figured my personal blog is a better place for this one as it's more personal in nature.&nbsp; I just finished two days of serving as a judge for the <A href="https://www.windowschallenge.com/">Windows Embedded Student Challenge</A>.&nbsp; I had a most wonderful time.&nbsp; The quality of the work,&nbsp;the innovation, and the energy of the students were simply amazing.&nbsp; What a diversity of projects from a diverse cross-section of the world!&nbsp; How energizing to see people take the work I do and build such impressive systems on top of it!&nbsp; The only disappointing part of the competition was that I didn't have a chance to see all 30 projects.</P>
<P>I also feel somewhat emotional about the event because it was heartbreaking to&nbsp;give some of these teams such disappointments.&nbsp;&nbsp;Everyone has worked so hard and cares so much.&nbsp; So to those teams out there who might read this, I want to say that just because you weren't chosen doesn't mean we didn't like your projects, or think that they could become successful products.&nbsp; In some cases we had to eliminate teams because their projects just weren't 100% ready, or because we felt&nbsp;they didn't adequately describe important aspects of their project during their presentation.&nbsp; It was clear in many cases that the teams intended to continue working on their projects, in an attempt to build a real commercial product.&nbsp; I would encourage you all to continue following the dream.&nbsp; If you want more feedback please do ask for it; we would be happy to help you understand what parts of the project were weak and how to improve on them for the future.</P>
<P>I loved meeting everyone.&nbsp; Thank you for your hard work, and for sharing it with us.&nbsp; I wish you all the best of luck, and hope to see you again!&nbsp; (Maybe next year?)&nbsp; Stay in touch, and I will see you online.&nbsp; ;-)</P>
<P>Sue</P>]]></content:encoded>
    </item>
    <item>
      <title>Windows CE Base Team Blog</title>
      <link>https://docs.microsoft.com/archive/blogs/sloh/windows-ce-base-team-blog</link>
      <pubDate>Mon, 06 Jun 2005 20:27:00 GMT</pubDate>
      <dc:creator><![CDATA[sloh]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sloh/2005/06/06/windows-ce-base-team-blog/</guid>
      <description><![CDATA[We just created a new team blog, the CE base team blog, to cover kernel &amp; file system...]]></description>
      <content:encoded><![CDATA[<P>We just created a new team blog, the CE base team blog, to cover kernel &amp; file system issues.</P>
<P><a href="https://blogs.msdn.com/ce_base/">https://blogs.msdn.com/ce_base/</A></P>
<P>I'm going to start posting there instead of here.&nbsp; I probably won't have a lot of side-posts on this blog; I don't really have the energy for lots of&nbsp;off-topic personal stuff.&nbsp; So if you are subscribed to this blog, you may want to switch over to that one.&nbsp; We're hoping that the new blog will get more of our team involved in posting, and provide a more consistent stream of information (as I tend to write in bursts).</P>
<P>Don't worry, I still have a list of&nbsp;things I want to write up "when I get the chance."&nbsp; See you there,</P>
<P>Sue</P>]]></content:encoded>
    </item>
    <item>
      <title>Lock Convoys and How to Recognize Them</title>
      <link>https://docs.microsoft.com/archive/blogs/sloh/lock-convoys-and-how-to-recognize-them</link>
      <pubDate>Fri, 27 May 2005 11:39:00 GMT</pubDate>
      <dc:creator><![CDATA[sloh]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sloh/2005/05/27/lock-convoys-and-how-to-recognize-them/</guid>
      <description><![CDATA[The problem: When using a particular application on one specific device, users noticed very bad UI...]]></description>
      <content:encoded><![CDATA[<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><B style="mso-bidi-font-weight: normal">The problem:</B> When using a particular application on one specific device, users noticed very bad UI response for a period of a few seconds.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>After those seconds, UI responsiveness went back to normal.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><B style="mso-bidi-font-weight: normal">The investigation:</B> I used ActiveSync to drop celog.dll and oscapture.exe onto a standalone device.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I could have hooked the device up to Platform Builder and run Remote Kernel Tracker over KITL, but in this case the device I had was configured to run without KITL.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I just didn’t bother reconfiguring it.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p>&nbsp;</o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p></o:p>&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">I made a .lnk file to start oscapture, and a second .lnk file to trigger it (run a second instance of oscapture with the “-c” parameter).<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I dropped these onto the Start menu of the device.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I ran oscapture, and played around with the errant application until the UI slowdown occurred.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>As quickly as I could (due to the UI slowdown it took a few seconds) I brought up the start menu and clicked the link to trigger oscapture.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>OScapture saved its data to a file.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I then hooked up ActiveSync again, and copied the log file off the device.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Actually now that I think of it, I probably could have just connected Remote Kernel Tracker to the device over ActiveSync, but you know I’m not that smart.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">Here is what I saw when opening up the file in Remote Kernel Tracker:</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><EM>(scroll down if you can't see anything)</EM></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><EM></EM>&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><IMG src="https://cenet.members.winisp.net/sloh_files/kt_convoy.png" mce_src="https://cenet.members.winisp.net/sloh_files/kt_convoy.png"></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">The main thread of pimg.exe is taking all the CPU time, and a few other threads (notably a couple in telshell.exe, which is responsible for the Smartphone UI) took little blips of time here and there, contending over a critical section.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I know they are contending because CeLog only logs critical section entry and exit events when there is contention.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Critical sections are acquired and released far too often to log uncontended operations. You don’t see any critical section exit events in this screen shot, but they’re there; they happen so close to the entry events that the “exit” icons are hidden underneath the “entry” icons.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>If I had zoomed in some more, you’d see them resolve into distinct events.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>All of these threads are at the same priority, 251 (THREAD_PRIORITY_NORMAL).<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I know the thread priorities because I hovered over the thread lines and saw the priorities in the resulting tooltips. <SPAN style="mso-spacerun: yes">&nbsp;</SPAN>But despite the equal priorities in this case, only one thread, that from pimg.exe, is getting very much CPU time.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>It is running to the completion of its quantum.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I know that because I set the “time marker 1 &amp; 2” in the time scale bar – you can see them in the screen shot.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>In the bottom right of the Remote Kernel Tracker window, where it says “Marker Time Delta,” is the time between the two markers.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>That time is about 100ms, the default thread quantum in Windows CE.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Each time the pimg.exe thread runs for about the same length of time, about 100ms.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">I immediately recognized this as a lock convoy problem.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Let me describe what that means.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>A lock convoy is a situation which occurs when two or more threads at the same priority frequently (several times per quantum) acquire a synchronization object, even if they only hold that object for a very short amount of time.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>It happens most often with critical sections, but can occur with mutexes, etc as well.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>For a while the threads may go along happily without contending over the object.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>But eventually some thread’s quantum will expire while it holds the object, and then the problem begins.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The expired thread (let’s call it Thread A) stops running, and the next thread at that priority level begins.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Soon that thread (let’s call it Thread B) gets to a point where it needs to acquire the object.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>It blocks on the object.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The kernel chooses the next thread in the priority-queue.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>If there are more threads at that priority which end up trying to acquire the object, they block on the object too.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>This continues until the kernel returns to Thread A which owns the object.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>That thread begins running again, and soon releases the object.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Here are the two important points.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>First, once Thread A releases the object, the kernel chooses a thread that’s blocked waiting for the object (probably Thread B), makes that thread the next owner of the object, and marks it as “runnable.”<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Second, Thread A hasn’t expired its quantum yet, so it continues running rather than switching to Thread B.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Since the threads in this scenario acquire the synchronization object frequently, Thread A soon comes back to a point where it needs to acquire the object again.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>This time, however, Thread B owns it.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>So Thread A blocks on the object, and the kernel again chooses the next thread in the priority-queue to run.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>It eventually gets to Thread B, who does its work while owning the object, then releases the object.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The next thread blocked on the object receives ownership, and this cycle continues endlessly until eventually the threads stop acquiring so often.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">The real performance killer about a lock convoy situation is that every time the threads involved need to acquire the synchronization object, they block and take at least a couple of context switches.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Since the premise of this situation is that the threads acquire the object frequently (several times a quantum), they are running for much less than a quantum between each context switch.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The less time they run between acquires, the more context switches involved – and remember that this is all regardless of how long or short of a time they spend owning the object.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">The other performance killer in a lock convoy situation is that it dramatically increases the percentage of CPU time non-contending threads at the same priority level get to run.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>If all threads at that priority level are contending over the object, what you see is very frequent context switching between them all.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>If one or more threads at that level are running continuously without blocking on any objects, those threads get to run for a full quantum each time the contending threads loop on the object.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>That is what you see in the screen shot above; the pimg.exe thread is not involved in the lock convoy, but since it’s at the same priority level as all the threads in the convoy, it gets all the CPU time.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>In this case, the UI threads only ran very tiny periods once each quantum of the pimg.exe thread execution, so the UI was very slow to respond to user input.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Eventually the pimg.exe thread completed its work, the UI threads completed their convoy, and the UI response time went back to its snappy old self.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><B style="mso-bidi-font-weight: normal">The solution:</B> Lock convoys are not always easy to solve.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>In this case, I don’t know the solution for sure, but I believe they either lowered the priority of the pimg.exe main thread or made it do its work at another time.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>While that doesn’t actually get rid of the lock convoy, it speeds it up to the point where it is unnoticeable to the user.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">Another work-around might have been to make the pimg.exe thread yield frequently, by calling Sleep(0), to allow the other threads to do their work more frequently than once per quantum.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Note, however, that this isn’t a very ideal work-around, because it’d lead to very frequent thread switching.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Context-switching very often is a problem in itself; you spend all your time making the kernel reschedule threads instead of letting those threads run.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">A different work-around is to reduce contention over the object by allowing it to be shared more often.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>For example, suppose the object is a critical section protecting some data.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>You don’t want threads to read the data while it’s being written, or write concurrently, etc.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>If reads are relatively frequent while writes are relatively rare, then a way to reduce contention over the lock is to convert it to a reader / writer lock.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>If writes are frequent, the improvement of using a reader/writer lock is minimal, but otherwise such a change can allow threads to read at the same time without serializing over a lock.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">Sometimes you can work around the problem by acquiring the lock at some other time.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>For example, I note that there’s a thread in filesys.exe involved in the convoy.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>So I suspect the critical section that was undergoing contention was inside filesys.exe.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>(While critical sections cannot be shared between processes, the non-filesys.exe threads may have used its critical section during calls into filesys.exe APIs.)<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Maybe the UI threads were reading from files to draw icons, or reading from the registry, or writing to a log file.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>In the read case, perhaps the UI could have kept the objects in a cache so as to avoid entering the file system.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>In the write case, perhaps it could queue up file system writes to execute at a later time.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Either solution amounts to caching data and performing operations asynchronously, instead of during time-critical UI processing.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">While lock convoys are also possible in Windows XP, they’re a little less problematic because of the priority boosting and aging that the Windows XP scheduler does.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>If a thread blocks on an object, then when it becomes un-blocked the XP scheduler temporarily boosts its priority a little.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>When a thread runs to the completion of its quantum, the XP scheduler ages its priority a little.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>In this manner, threads that block often end up at higher priority than threads that run continuously without blocking.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Then the lock convoy isn’t eliminated, but there is less chance of another unrelated thread skunking up the works by running a full quantum each thread switch.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">A better solution, if you can change all the code that acquires the contentious lock, is to use TryEnterCriticalSection to acquire the lock only when it’s uncontended.<o:p>&nbsp;</o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p></o:p>&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>retries = 0;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>while(!TryEnterCriticalSection(&amp;CritSec)) {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN>if( retries++ &lt; SpinLimit ){<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN>Sleep(0);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN>continue;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN>}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN>EnterCriticalSection(&amp;CritSec);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN>break;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">This code will use TryEnterCriticalSection a number of times, yielding the processor on each failure until it reaches the SpinLimit and then uses regular EnterCriticalSection.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The SpinLimit is necessary in case the critical section is owned by a lower-priority thread which would not run and release the critical section while the current thread is looping.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>In that case the EnterCriticalSection call is required to make the kernel invert the priority of the owning thread briefly, so that the higher-priority thread can acquire the critical section.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">You may expect this code, which basically polls for the critical section, to hurt performance.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>But believe it or not, it can greatly improve it.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The difference between this loop and a regular EnterCriticalSection call is that threads do not enter the queue to acquire the critical section if some other thread owns it.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>So in the example above, when Thread A releases the critical section, Thread B does not immediately become the owner.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Thread A is free to continue running and even acquire and release the critical section a few more times before Thread B comes back and tries to acquire it again.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Even with a SpinLimit of 2 (= 1 Sleep() call) two threads can recover from critical section contention without creating a convoy.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">Alas, this solution is unavailable if you cannot change the code which acquires the critical section.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">To those of you who might ask whether we intend to make changes to Windows CE to eliminate lock convoys, I’m not at liberty to discuss what we may or may not do in future products.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I can only say the standard non-informative spiel: Microsoft is committed to improving the quality of its products and considers all improvements in the context of other improvements we wish to make, to provide our customers the biggest benefits possible in the time available blah blah blah.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>(By the way that spiel, while hokey, really is true.)</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">In the meantime I hope I’ve provided you with some information you can use to identify and escape this problem if you encounter it.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><STRONG><EM>UPDATE 26 June 06:</EM></STRONG>&nbsp; Discussion of whether the TryEnter/Sleep solution hurts perf.&nbsp; I don’t really think the Sleep() will hurt perf at all.&nbsp; Here is what would happen:</P>
<OL>
<LI>
<DIV class=MsoNormal style="MARGIN: 0in 0in 0pt">Thread 1 quantum expires while holding the CS (which is what starts a convoy)</DIV></LI>
<LI>
<DIV class=MsoNormal style="MARGIN: 0in 0in 0pt">Thread 2 does TryEnter, fails, and sleeps</DIV></LI>
<LI>
<DIV class=MsoNormal style="MARGIN: 0in 0in 0pt">Thread 1 runs again, acquires and releases the CS a bunch of times, and quantum expires while not holding the CS</DIV></LI>
<LI>
<DIV class=MsoNormal style="MARGIN: 0in 0in 0pt">Thread 2 runs again, does TryEnter again, succeeds.&nbsp; Now it can acquire and release the CS a bunch of times.</DIV></LI></OL>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">So the sleep causes a thread switch, but it’s a thread switch you’d have taken anyway if you were using regular EnterCriticalSection.&nbsp; And now that I think more about this, I think your change to hold the CS for a longer period would negatively impact the perf of the TryEnter solution, because it’d increase the chances of expiring your quantum while holding the CS.&nbsp; Though the impact would still not be bad because in general the threads would run to quantum completion.</P>]]></content:encoded>
    </item>
    <item>
      <title>[misc] Getting Kids into Computers</title>
      <link>https://docs.microsoft.com/archive/blogs/sloh/misc-getting-kids-into-computers</link>
      <pubDate>Thu, 26 May 2005 13:06:00 GMT</pubDate>
      <dc:creator><![CDATA[sloh]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sloh/2005/05/26/misc-getting-kids-into-computers/</guid>
      <description><![CDATA[Links I turned up from recent discussions of this topic:

Scobleizer:...]]></description>
      <content:encoded><![CDATA[<P>Links I turned up from recent discussions of this topic:</P>
<UL>
<LI>Scobleizer: <A href="https://radio.weblogs.com/0001011/2005/05/25.html#a10197">https://radio.weblogs.com/0001011/2005/05/25.html#a10197</A></LI>
<LI>Erick Mack: <A href="https://www.ericmackonline.com/ica/blogs/emonline.nsf/dx/how-to-get-your-kids-interested-in-computers">https://www.ericmackonline.com/ica/blogs/emonline.nsf/dx/how-to-get-your-kids-interested-in-computers</A></LI>
<LI>Jeff Sandquist, Bitman's Palace: <A href="https://www.jeffsandquist.com/WelcomeToBitmansPlace.aspx">https://www.jeffsandquist.com/WelcomeToBitmansPlace.aspx</A></LI>
<LI>Kid's Programming Language: <A href="https://www.ms-inc.net/kpl.aspx">https://www.ms-inc.net/kpl.aspx</A></LI></UL>
<P>I keep thinking of how I'd like to get more involved in getting kids into programming.&nbsp; I even tried seeing if I could volunteer-teach an after-school thing at my local high school, but they don't have anything like that, and the school-year timing was wrong to start something.&nbsp; I think the first thing I'll do is go through Bitman's palace and give them my feedback....</P>
<P>&nbsp;</P>]]></content:encoded>
    </item>
  </channel>
</rss>