{"id":96385,"date":"2017-06-13T07:00:00","date_gmt":"2017-06-13T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=96385"},"modified":"2019-03-13T01:12:48","modified_gmt":"2019-03-13T08:12:48","slug":"20170613-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20170613-00\/?p=96385","title":{"rendered":"Creating a semaphore with a maximum count from WaitOnAddress"},"content":{"rendered":"<p>Last time, we <!-- backref: Creating a semaphore with a maximum count from WaitOnAddress -->created a simple semaphore from <code>Wait&shy;On&shy;Address<\/code><\/a>. That sempahore did not have a maximum token count. Let&#8217;s add that. <\/p>\n<pre>\nstruct ALT_MAXSEMAPHORE\n{\n  LONG TokenCount;\n  LONG MaxTokenCount;\n};\n\nvoid InitializeMaxAltSemaphore(ALT_MAXSEMAPHORE* Semaphore,\n                               LONG InitialCount,\n                               LONG MaxTokenCount)\n{\n  Semaphore-&gt;TokenCount = InitialCount;\n  Semaphore-&gt;MaxTokenCount = MaxTokenCount;\n}\n\nbool ReleaseMaxAltSemaphore(ALT_MAXSEMAPHORE* Semaphore,\n                            LONG ReleaseCount)\n{\n  while (true) {\n    LONG OriginalTokenCount = Semaphore-&gt;TokenCount;\n    LONG NewTokenCount = OriginalTokenCount + ReleaseCount;\n    if (NewTokenCount &gt; Semaphore-&gt;MaxTokenCount) {\n     return false; \/\/ would exceed maximum\n    }\n    if (InterlockedCompareExchange(&amp;Sempahore-&gt;TokenCount,\n      NewTokenCount,\n      OriginalTokenCount) == OriginalTokenCount) {\n      if (ReleaseCount == 1) {\n        WakeByAddressSingle(&amp;Sempahore-&gt;TokenCount);\n      } else {\n        WakeByAddressAll(&amp;Sempahore-&gt;TokenCount);\n      }\n      return true;\n    }\n  }\n}\n<\/pre>\n<p>Releasing the tokens is a little trickier because we have to verify that we aren&#8217;t going to exceed the maximum token count. Our attempt to release may fail if other threads snuck in and either claimed or released tokens, in which case we loop back and try again. <\/p>\n<p>The code to wait for and claim a token is unchanged. We merely had to tweak how we release tokens. <\/p>\n<p>Okay, next time, we&#8217;ll specialize to the case of an event, which is like a semaphore with a maximum count of 1. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>The exercises continue.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-96385","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The exercises continue.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96385","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=96385"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96385\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=96385"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=96385"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=96385"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}