{"id":111,"date":"2007-02-28T14:44:30","date_gmt":"2007-02-28T14:44:30","guid":{"rendered":"https:\/\/driverentry.com.br\/en\/2007\/02\/28\/synchronism-x-performance\/"},"modified":"2026-07-25T13:56:36","modified_gmt":"2026-07-25T13:56:36","slug":"synchronism-x-performance","status":"publish","type":"post","link":"https:\/\/driverentry.com.br\/en\/2007\/02\/28\/synchronism-x-performance\/","title":{"rendered":"Synchronism x Performance"},"content":{"rendered":"<div style=\"text-align: right;\"><a href=\"https:\/\/driverentry.com.br\/2007\/02\/28\/sincronismo-x-performance\/\"><img loading=\"lazy\" decoding=\"async\" title=\"Em Portugu\u00eas\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/br.gif\" alt=\"\" width=\"21\" height=\"19\" \/><\/a><\/div>\n<p>No wonder that my last posts brought issues related to linked lists and performance. In  recent weeks, I had been hired by a security company to take a look at one of  their File System filters, in order to reduce the delay caused by them.  In this post, I will talk about synchronism and CPU contention.<\/p>\n<p>I think  it should not be new to many here that a linked list, or any other resource,  when shared among multiple <em>threads<\/em>, should implement some access synchronism control thus, avoiding a <em>thread <\/em>to read invalid data as a result of a  change made by another <em>thread <\/em>at same time.<\/p>\n<h3>But I don&#8217;t have two processors, synchronism for what?<\/h3>\n<p>It is true that computers with only one processor run only one <em>thread <\/em>at any given moment. So we never have two <em>threads <\/em>being executed at the same time. But  it is important to remember that threads are executed in small slices  of time determined by the scheduler, considering each thread quantum  size and its priority. There  are ways of avoiding that a thread be interrupted by the Windows  scheduler, but at normal temperature and pressure conditions, we do not know when a  thread is interrupted giving its place to another thread be executed.<\/p>\n<p>Suppose that <em>thread<\/em> A is scanning a list in search of a certain node. This <em>thread<\/em> reaches record R and is interrupted so that <em>thread<\/em> B can be executed. <em>Thread<\/em> B removes that same record R from the list and deallocates it from RAM. When <em>thread<\/em> A is resumed and reads the fields of the late record R, it will access invalid data and make the following steps unpredictable. Even though it is quite predictable that something blue should happen.<\/p>\n<p>There  are several synchronization mechanisms that we can use, but in this post, I  will comment specifically about those I&#8217;ve been involved in these weeks. But  besides these ones, I have to talk about the most exotic I&#8217;ve seen in years of  experience, which for me was nicknamed <strong>&#8220;Mutex, pero no Mutcho.&#8221;<\/strong> This was a derived class from <strong>VMutex<\/strong> of <strong>VToolsD<\/strong>. The class <strong>enter() <\/strong>method<strong> <\/strong>insanely tried to acquire a <em>mutex <\/em>few thousand times in a loop. If  after these thousands of interactions the mutex has not been acquired, then the thread gave up and accessed the shared resource anyway. Do you think the system was having some trouble of <em>Dead Lock<\/em>? Anyway, it was nice to fix this years ago. There are things we only believe when we see them.<\/p>\n<p>As I  have mentioned in another post, File System Filter is a layer placed over  drivers like <a href=\"http:\/\/en.wikipedia.org\/wiki\/File_Allocation_Table\">FastFAT<\/a>, <a href=\"http:\/\/en.wikipedia.org\/wiki\/Ntfs\">NTFS<\/a>, <a href=\"http:\/\/en.wikipedia.org\/wiki\/ISO_9660\">CDFS<\/a>, <a href=\"http:\/\/en.wikipedia.org\/wiki\/Network_redirector\">Network Redirectors<\/a> and any other  drivers that implement a file system interface. That is, all operations related to files, including <a href=\"http:\/\/en.wikipedia.org\/wiki\/Memory-mapped_file\">File Mapping<\/a> access, pass through <strong>File System<\/strong> filters.<\/p>\n<p><img decoding=\"async\" style=\"float: right; margin: 0px 10px;\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/fs-internals-cover.gif\" border=\"0\" alt=\"\" \/><\/p>\n<p>If  you&#8217;re not only interested to know about <strong>File System<\/strong> filters, but  interested in working with File Systems itself, then you have an obligation to read the  <a href=\"http:\/\/www.amazon.com\/Windows-System-Internals-Classic-Reprints\/dp\/0976717514\/sr=8-1\/qid=1172681530\/ref=sr_1_1\/002-1211540-5848812?ie=UTF8&amp;s=books\">Windows NT File System Internals<\/a> by <strong>Rajeev Nagar<\/strong>. This book is the single known reference that is comprehensive enough on this subject. First  published in <a href=\"http:\/\/www.amazon.com\/Windows-File-System-Internals-Developers\/dp\/1565922492\/sr=8-2\/qid=1172681416\/ref=sr_1_2\/002-1211540-5848812?ie=UTF8&amp;s=books\">1997<\/a> by <a href=\"http:\/\/www.oreilly.com\/\">O&#8217;Reilly<\/a>, this book is still a mandatory tool  for development relative to <strong>File Systems<\/strong> even for Windows Vista. Its  publication was interrupted a few years ago, and during that time, I saw this book being sold for more than U$ 200.00 for a single used copy on <a href=\"http:\/\/www.amazon.com\/\"> Amazon<\/a>. Today <a href=\"http:\/\/www.osr.com\/publications_main.shtml\"> OSR<\/a> holds the book copyrights and it is currently working on an updated  edition, which should bring issues such as <a href=\"http:\/\/en.wikipedia.org\/wiki\/Volume_Shadow_Copy_Service\">Shadow Copy<\/a>, <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/aa365456.aspx\">Transactional  NTFS<\/a>, <strong>Filter Manager<\/strong>, <strong>Mini Redirectors<\/strong> and force volume dismount. However  this is a job that will take some time, then in 2005, the original  version was reprinted to meet this need, while the new edition has been made.<\/p>\n<p>The filter I have worked on maintains several lists to be consulted on each intercepted access. The mechanism used to synchronize access to these lists was the <em>Spin Lock<\/em>. An obvious choice, but inadequate for this scenario, where the activity is too intense. The list group that is used on <strong>IRP_MJ_READ<\/strong> routine is also used at <strong>IRP_MJ_WRITE<\/strong> routine and other events. The result is CPU contention. That  is, when a <em>thread <\/em>gets a <em>Spin Lock<\/em> to do a query on the list,  all other <em>threads<\/em> that need to consult the same list have to sit and  wait until the <em>Spin Lock <\/em>is released (even in cases that we have more  than one processor). Knowing that these lists are not small. Can you imagine how slow it was?<\/p>\n<p>Just as world hunger, cervix cancer, the prostate examination and other ills that affect mankind, something should be done about this. Therefore, in a relentless struggle against the evil forces was created the <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/aa490224.aspx\">ERESOURCE<\/a>. (Angelic chants and a dry ice mist is dissipated into the ground)<\/p>\n<h3>Using ERESOURCE<\/h3>\n<p><strong>ERESOURCE<\/strong> is the most appropriate and native way used to synchronize access to  structures that are part of a file system, such as <strong>FCB<\/strong> (<em>File Control  Block<\/em>), which besides other information, keeps the current file size. With <strong>ERESOURCE<\/strong>, multiple threads can access the same linked list at the same time for reading. Assuming that none of the <em>threads <\/em>would change the data list, then all accesses could be performed simultaneously. In contrast, if necessary, a <em>thread <\/em>can gain exclusive access to the list in order to make a change.<\/p>\n<p>To use <strong>ERESOURSE<\/strong>, you must declare a <strong>ERESOURCE <\/strong>variable, which must  reside in non-paged memory and 8 bytes aligned, and initialize it  using <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/ms797091.aspx\">ExInitializeResourceLite()<\/a> function. For shared access (read only) to the list, you must use <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/aa490041.aspx\">ExAcquireResourceSharedLite()<\/a> function. This function checks for a thread with exclusive access to controlled resource. If so, the function may, depending on a parameter, return failure or wait until the resource to be released. To  have exclusive access, use <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/aa489849.aspx\">ExAcquireResourceExclusiveLite()<\/a> function, which  analogously checks for threads with shared access to the resource, and  optionally, waits until all threads with shared access before releasing the  resource for exclusive access. <span>Finally, to release the access granted, either exclusive or shared, use the <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/ms797094.aspx\">ExReleaseResourceLite()<\/a> function.<\/p>\n<p>An interesting point to notice is that the <strong>Kernel APC<\/strong> delivery must be disabled for the threads that acquire <strong>ERESOURCE<\/strong>. I do not know the real reason for this need, but at least it prevents the  thread holding the resource from being terminated by another thread, knowing that the <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/ms686717.aspx\">TerminateThread()<\/a> is implemented via <strong>Kernel APC<\/strong>. Thus, the most common way to use these functions is as shown below.<\/p>\n<div style=\"font-family: Courier New; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/-f--&gt; Get shared access (read only).<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    KeEnterCriticalRegion();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    ExAcquireResourceSharedLite(&amp;m_Resource, TRUE);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"> <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/-f--&gt; Query the protected values.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"> <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/-f--&gt; Release the resource.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    ExReleaseResourceLite(&amp;m_Resource);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    KeLeaveCriticalRegion();<\/pre>\n<\/div>\n<p>One  downside is that most of the functions that deal with <strong>ERESOURCE<\/strong>, unlike  <em>Spin Locks<\/em>, should be called with <strong>IRQL<\/strong> &lt; <strong>DISPATCH_LEVEL<\/strong>. Thus, perhaps some tricks are necessary when handling IRPs and their <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/ms795636.aspx\">CompletionsRoutines<\/a> to deal with this.<\/p>\n<p>After those modifications, the system has gained a lot of performance on the tests I did. The gain will be even greater as we have more operations in parallel, and of course, on computers with more than one processor.<\/p>\n<p>And everybody has lived happily ever after&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>No wonder that my last posts brought issues related to linked lists and performance. In recent weeks, I had been hired by a security company to take a look at one of their File System filters, in order to reduce the delay caused by them. In this post, I will talk about synchronism and CPU [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"pagelayer_contact_templates":[],"_pagelayer_content":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-111","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/111","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/comments?post=111"}],"version-history":[{"count":3,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/111\/revisions"}],"predecessor-version":[{"id":114,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/111\/revisions\/114"}],"wp:attachment":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/media?parent=111"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/categories?post=111"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/tags?post=111"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}