<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>Using very short allegro timers in separate thread and getting lots of cpu usage</title>
		<link>http://www.allegro.cc/forums/view/618865</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Sat, 07 Oct 2023 06:49:10 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I am trying to use an allegro timer to control how often I check for packets in a thread dedicated just to checking for and reading packets into a buffer.</p><p>It works as expected, but takes up almost 100% cpu for all 4 cores (I&#39;m looking in windows task manager)</p><p>The whole reason I started this....</p><p>I used to check for packets once per frame (in my case 25ms)<br />This was/is fine for game state info, as I can&#39;t really use it any earlier anyway.</p><p>But I also send packets that I use to control the timing relationship between the master and the clients.<br />These packets I want to receive and process immediately, not wait until the end of the 25ms game loop.</p><p>So what I did was to continually look for and process packets in the wait time at the end of every frame.<br />This improved the accuracy of timing when I received the packets.</p><div class="source-code snippet"><div class="inner"><pre>
loop<span class="k2">(</span><span class="k2">)</span>
<span class="k2">{</span>
   <span class="k1">if</span> <span class="k2">(</span>game_loop_event_timer<span class="k2">)</span>
   <span class="k2">{</span>
      get input
      move
      draw
   <span class="k2">}</span>

   fast_packet_proc<span class="k2">(</span><span class="k2">)</span>

<span class="k2">}</span>
</pre></div></div><p>


But there was still a problem.</p><p>When the time it takes to process and draw a frame increases, the wait time at the end of the frame decreases.<br />And that is the only time I was checking for new packets.<br />If it took 20ms to process a frame, I only had 5ms left to receive packets.<br />And then my timing was considerably less accurate.</p><p>So I looked into and implemented a separate thread to look for and process packets.<br />If it is a timing packet, it is processed immediately.<br />Otherwise is is added to a buffer and processed at the start of the next frame.</p><div class="source-code snippet"><div class="inner"><pre>That worked, but I am having some issues about timing.

Initially the thread ran as fast as it could:

<span class="k1">void</span> <span class="k3">*</span>mwPacketBuffer::rx_thread_func<span class="k2">(</span><a href="http://www.allegro.cc/manual/ALLEGRO_THREAD"><span class="a">ALLEGRO_THREAD</span></a> <span class="k3">*</span>thr, <span class="k1">void</span> <span class="k3">*</span>arg<span class="k2">)</span>
<span class="k2">{</span>
   mPacketBuffer.add_to_rx_buffer<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>


Sometimes it would run 10,000 times per frame!<br />Besides the wasted time and resources, it also ran so fast, it barely left any time the mutexs were unlocked.</p><p>So I experimented with ways to throttle it down to a more reasonable time</p><p>Instead of 10,000 times per frame, I would be happy if it only ran 250 times<br />That way I could measure time to .1ms or 100us</p><p>Initially I just simply tried al_rest()</p><p>Then I tried using a timer.</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span>thr_timer <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_create_timer"><span class="a">al_create_timer</span></a><span class="k2">(</span><span class="n">0</span>.<span class="n">0001</span><span class="k2">)</span><span class="k2">;</span>    <span class="c">// .1ms</span>
<span class="number">  2</span><a href="http://www.allegro.cc/manual/al_register_event_source"><span class="a">al_register_event_source</span></a><span class="k2">(</span>event_queue, <a href="http://www.allegro.cc/manual/al_get_timer_event_source"><span class="a">al_get_timer_event_source</span></a><span class="k2">(</span>thr_timer<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  3</span><a href="http://www.allegro.cc/manual/al_start_timer"><span class="a">al_start_timer</span></a><span class="k2">(</span>thr_timer<span class="k2">)</span><span class="k2">;</span>
<span class="number">  4</span><span class="k1">if</span> <span class="k2">(</span>ev.timer.source <span class="k3">=</span><span class="k3">=</span> thr_timer<span class="k2">)</span> thr_proc <span class="k3">=</span> <span class="n">1</span><span class="k2">;</span>
<span class="number">  5</span>
<span class="number">  6</span><span class="k1">void</span> <span class="k3">*</span>mwPacketBuffer::rx_thread_func<span class="k2">(</span><a href="http://www.allegro.cc/manual/ALLEGRO_THREAD"><span class="a">ALLEGRO_THREAD</span></a> <span class="k3">*</span>thr, <span class="k1">void</span> <span class="k3">*</span>arg<span class="k2">)</span>
<span class="number">  7</span><span class="k2">{</span>
<span class="number">  8</span>   <span class="k1">while</span> <span class="k2">(</span><span class="n">1</span><span class="k2">)</span>
<span class="number">  9</span>   <span class="k2">{</span>
<span class="number"> 10</span><span class="c">//      al_rest(0.001);</span>
<span class="number"> 11</span><span class="c">//      mPacketBuffer.add_to_rx_buffer();</span>
<span class="number"> 12</span>
<span class="number"> 13</span>      <span class="k1">if</span> <span class="k2">(</span>mEventQueue.thr_proc<span class="k2">)</span>
<span class="number"> 14</span>      <span class="k2">{</span>
<span class="number"> 15</span>         mPacketBuffer.add_to_rx_buffer<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 16</span>         mEventQueue.thr_proc <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span>
<span class="number"> 17</span>      <span class="k2">}</span>
<span class="number"> 18</span>   <span class="k2">}</span>
<span class="number"> 19</span><span class="k2">}</span>
</div></div><p>

It seems to work and my game seems to runs fine, but in windows task manager all four cores peg out at nearly 100%</p><p>Is this normal for allegro timers?<br />Am I using them wrong?<br />Is it because the timer interval is so small? (100us)</p><p>I really want to find a way to limit the thread from running wide open at 10,000 iterations per frame, that also doesn&#39;t take up so much cpu time.</p><p>Also because my project (Purple Martians) is cross platform (windows and linux)<br />I do not want any platform specific solutions. That is why I am using allegro threads and allegro timers, etc...</p><p>Also any other advice or pointers would be greatly appreciated!</p><p>I am really new to threads, this is the first time I have actually used them for something other than simple example programs.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Michael Weiss)</author>
		<pubDate>Thu, 05 Oct 2023 08:48:37 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I would expect that with while(1). The thread needs to cede remaining time by sleeping, but sleep after whatever you need to do first.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (DanielH)</author>
		<pubDate>Thu, 05 Oct 2023 20:29:36 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>How do I cede the remaining time?</p><p>If I exit my while loop, my thread will be done, right?</p><p>My thread is always running, waiting for something to process.</p><p>Am I thinking about this the wrong way?</p><p>Basically I want the thread to always be looking for new packets to process.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Michael Weiss)</author>
		<pubDate>Thu, 05 Oct 2023 21:29:03 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>What happens when you add the al_rest?
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">while</span> <span class="k2">(</span><span class="n">1</span><span class="k2">)</span>
<span class="k2">{</span>
     <span class="c">// mPacketBuffer.add_to_rx_buffer();</span>

     <span class="k1">if</span> <span class="k2">(</span>mEventQueue.thr_proc<span class="k2">)</span>
     <span class="k2">{</span>
          mPacketBuffer.add_to_rx_buffer<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
          mEventQueue.thr_proc <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span>
     <span class="k2">}</span>
     <a href="http://www.allegro.cc/manual/al_rest"><span class="a">al_rest</span></a><span class="k2">(</span><span class="n">0</span>.<span class="n">001</span><span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (DanielH)</author>
		<pubDate>Thu, 05 Oct 2023 22:16:35 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I never did both at the same time, It was always one or the other.</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">void</span> <span class="k3">*</span>mwPacketBuffer::rx_thread_func<span class="k2">(</span><a href="http://www.allegro.cc/manual/ALLEGRO_THREAD"><span class="a">ALLEGRO_THREAD</span></a> <span class="k3">*</span>thr, <span class="k1">void</span> <span class="k3">*</span>arg<span class="k2">)</span>
<span class="k2">{</span>
   <span class="k1">while</span> <span class="k2">(</span><span class="n">1</span><span class="k2">)</span>
   <span class="k2">{</span>
      <a href="http://www.allegro.cc/manual/al_rest"><span class="a">al_rest</span></a><span class="k2">(</span><span class="n">0</span>.<span class="n">01</span><span class="k2">)</span><span class="k2">;</span>
      mPacketBuffer.add_to_rx_buffer<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
   <span class="k2">}</span>
<span class="k2">}</span>
</pre></div></div><p>

or</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">void</span> <span class="k3">*</span>mwPacketBuffer::rx_thread_func<span class="k2">(</span><a href="http://www.allegro.cc/manual/ALLEGRO_THREAD"><span class="a">ALLEGRO_THREAD</span></a> <span class="k3">*</span>thr, <span class="k1">void</span> <span class="k3">*</span>arg<span class="k2">)</span>
<span class="k2">{</span>
   <span class="k1">while</span> <span class="k2">(</span><span class="n">1</span><span class="k2">)</span>
   <span class="k2">{</span>
      <span class="k1">if</span> <span class="k2">(</span>mEventQueue.thr_proc<span class="k2">)</span>
      <span class="k2">{</span>
         mPacketBuffer.add_to_rx_buffer<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
         mEventQueue.thr_proc <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span>
      <span class="k2">}</span>
   <span class="k2">}</span>
<span class="k2">}</span>
</pre></div></div><p>







I just ran some tests:</p><div class="source-code snippet"><div class="inner"><pre>
Timer    expected    <a href="http://www.allegro.cc/manual/al_rest"><span class="a">al_rest</span></a>                  al_timer
value    calls<span class="k3">/</span>sec   cpu  actual calls<span class="k3">/</span>sec    cpu  actual calls<span class="k3">/</span>sec
<span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span><span class="k3">-</span>
<span class="n">0</span>.<span class="n">01</span>     <span class="n">100</span>         <span class="n">25</span>   <span class="n">90</span><span class="k3">-</span><span class="n">99</span>               <span class="n">50</span>%  <span class="n">100</span>
<span class="n">0</span>.<span class="n">005</span>    <span class="n">200</span>         <span class="n">25</span>   <span class="n">160</span><span class="k3">-</span><span class="n">199</span>             <span class="n">50</span>%  <span class="n">200</span>
<span class="n">0</span>.<span class="n">001</span>    <span class="n">1000</span>        <span class="n">50</span>   <span class="n">500</span><span class="k3">-</span><span class="n">1000</span>            <span class="n">75</span>%  <span class="n">1000</span>
<span class="n">0</span>.<span class="n">0005</span>   <span class="n">2000</span>        <span class="n">75</span>   <span class="n">1</span>,<span class="n">000</span>,<span class="n">000</span>           <span class="n">75</span>%  <span class="n">2000</span>
<span class="n">0</span>.<span class="n">0001</span>   <span class="n">10000</span>       <span class="n">75</span>   <span class="n">1</span>,<span class="n">000</span>,<span class="n">000</span>           <span class="n">70</span>%  <span class="n">9000</span>
</pre></div></div><p>


I seems like I use less cpu with al_rest, but the problem with al_rest is that it does not seem to work well with short times.</p><p>I gave up on it quite early in testing because of that.</p><p>I read the manual for time routines many times:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">void</span> <a href="http://www.allegro.cc/manual/al_rest"><span class="a">al_rest</span></a><span class="k2">(</span><span class="k1">double</span> seconds<span class="k2">)</span>

Waits <span class="k1">for</span> the specified number of seconds. This tells the <a href="http://www.delorie.com/djgpp/doc/libc/libc_802.html" target="_blank">system</a> to <a href="http://www.delorie.com/djgpp/doc/libc/libc_613.html" target="_blank">pause</a> the
current thread <span class="k1">for</span> the given amount of time. With some operating systems, the
accuracy can be in the order of <span class="n">10</span>ms. That is, even

<a href="http://www.allegro.cc/manual/al_rest"><span class="a">al_rest</span></a><span class="k2">(</span><span class="n">0</span>.<span class="n">000001</span><span class="k2">)</span>

might <a href="http://www.delorie.com/djgpp/doc/libc/libc_613.html" target="_blank">pause</a> <span class="k1">for</span> something like <span class="n">10</span>ms. Also see the section on Timer routines <span class="k1">for</span>
easier ways to <a href="http://www.delorie.com/djgpp/doc/libc/libc_821.html" target="_blank">time</a> your program without <span class="k1">using</span> up all CPU.
</pre></div></div><p>

That led me to trying to use timers....</p><div class="source-code snippet"><div class="inner"><pre><a href="http://www.allegro.cc/manual/al_create_timer"><span class="a">al_create_timer</span></a>

<a href="http://www.allegro.cc/manual/ALLEGRO_TIMER"><span class="a">ALLEGRO_TIMER</span></a> <span class="k3">*</span><a href="http://www.allegro.cc/manual/al_create_timer"><span class="a">al_create_timer</span></a><span class="k2">(</span><span class="k1">double</span> speed_secs<span class="k2">)</span>

Allocates <span class="k1">and</span> initializes a timer. If successful, a pointer to a <span class="k1">new</span> timer object
is returned, otherwise NULL is returned. speed_secs is in seconds per tick, <span class="k1">and</span>
must be positive. The <span class="k1">new</span> timer is initially stopped <span class="k1">and</span> needs to be started with
<a href="http://www.allegro.cc/manual/al_start_timer"><span class="a">al_start_timer</span></a> before ALLEGRO_EVENT_TIMER events are sent.

Usage note: typical granularity is on the order of microseconds, but with some
drivers might only be milliseconds.
</pre></div></div><p>

So i think I might be just running into the limits of what al_rest() can do.</p><p>But why does al_timer seem to be able to handle shorter times than al_rest()?</p><p>Are they not both limited by the underlying system?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Michael Weiss)</author>
		<pubDate>Fri, 06 Oct 2023 17:35:17 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>al_rest(0)?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (DanielH)</author>
		<pubDate>Fri, 06 Oct 2023 18:35:35 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I will try that later, I ran out of time this morning and have to go to work....</p><p>What I did try was:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">void</span> <span class="k3">*</span>mwPacketBuffer::rx_thread_func<span class="k2">(</span><a href="http://www.allegro.cc/manual/ALLEGRO_THREAD"><span class="a">ALLEGRO_THREAD</span></a> <span class="k3">*</span>thr, <span class="k1">void</span> <span class="k3">*</span>arg<span class="k2">)</span>
<span class="k2">{</span>
   <span class="k1">while</span> <span class="k2">(</span><span class="n">1</span><span class="k2">)</span>
   <span class="k2">{</span>
      <span class="k1">static</span> <span class="k1">double</span> t0 <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_get_time"><span class="a">al_get_time</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
      <span class="k1">double</span> t1 <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_get_time"><span class="a">al_get_time</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
      <span class="k1">if</span> <span class="k2">(</span>t1-t0&gt;0.0001<span class="k2">)</span>
      <span class="k2">{</span>
         t0 <span class="k3">=</span> t1<span class="k2">;</span>
         mPacketBuffer.add_to_rx_buffer<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
      <span class="k2">}</span>
   <span class="k2">}</span>
<span class="k2">}</span>
</pre></div></div><p>

I seem to be getting a solid 50% cpu usage and the expected number of packets.</p><p>I will test more later.</p><p>Thank you for your suggestions, I will try al_rest(0) later......
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Michael Weiss)</author>
		<pubDate>Fri, 06 Oct 2023 19:00:10 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span>thr_timer <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_create_timer"><span class="a">al_create_timer</span></a><span class="k2">(</span><span class="n">0</span>.<span class="n">0001</span><span class="k2">)</span><span class="k2">;</span>    <span class="c">// .1ms</span>
<span class="number">  2</span><a href="http://www.allegro.cc/manual/al_register_event_source"><span class="a">al_register_event_source</span></a><span class="k2">(</span>event_queue, <a href="http://www.allegro.cc/manual/al_get_timer_event_source"><span class="a">al_get_timer_event_source</span></a><span class="k2">(</span>thr_timer<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  3</span><a href="http://www.allegro.cc/manual/al_start_timer"><span class="a">al_start_timer</span></a><span class="k2">(</span>thr_timer<span class="k2">)</span><span class="k2">;</span>
<span class="number">  4</span><span class="k1">if</span> <span class="k2">(</span>ev.timer.source <span class="k3">=</span><span class="k3">=</span> thr_timer<span class="k2">)</span> <span class="k3">+</span><span class="k3">+</span>thr_proc<span class="k2">;</span>
<span class="number">  5</span>
<span class="number">  6</span><span class="k1">void</span> <span class="k3">*</span>mwPacketBuffer::rx_thread_func<span class="k2">(</span><a href="http://www.allegro.cc/manual/ALLEGRO_THREAD"><span class="a">ALLEGRO_THREAD</span></a> <span class="k3">*</span>thr, <span class="k1">void</span> <span class="k3">*</span>arg<span class="k2">)</span>
<span class="number">  7</span><span class="k2">{</span>
<span class="number">  8</span>    <span class="k1">while</span> <span class="k2">(</span><span class="n">1</span><span class="k2">)</span>
<span class="number">  9</span>    <span class="k2">{</span>
<span class="number"> 10</span>        <span class="k1">while</span> <span class="k2">(</span>mEventQueue.thr_proc<span class="k2">)</span>
<span class="number"> 11</span>        <span class="k2">{</span>
<span class="number"> 12</span>            mPacketBuffer.add_to_rx_buffer<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 13</span>            <span class="k3">-</span><span class="k3">-</span>mEventQueue.thr_proc<span class="k2">;</span>
<span class="number"> 14</span>        <span class="k2">}</span>
<span class="number"> 15</span>        <a href="http://www.allegro.cc/manual/al_rest"><span class="a">al_rest</span></a><span class="k2">(</span><span class="n">0</span>.<span class="n">01</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 16</span>    <span class="k2">}</span>
<span class="number"> 17</span><span class="k2">}</span>
</div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (DanielH)</author>
		<pubDate>Fri, 06 Oct 2023 20:31:17 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Just a thought, but how about pushing the packets (or rather, their availability state) through an (user) event source so you could simply wait until a new packet is available?</p><p>Edit: Ah, okay, didn&#39;t read the thread right I think. How about resting the remainder of the time that you didn&#39;t need to consume the packet? Or have you tried that already? Do you need to poll for packets or is there a way to wait for them (I don&#39;t know what networking lib you are using)?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Polybios)</author>
		<pubDate>Sat, 07 Oct 2023 00:50:27 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>DanielH</p><p>Your last suggestion:</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span>
<span class="number">  2</span>thr_timer <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_create_timer"><span class="a">al_create_timer</span></a><span class="k2">(</span><span class="n">0</span>.<span class="n">0001</span><span class="k2">)</span><span class="k2">;</span>    <span class="c">// .1ms</span>
<span class="number">  3</span><a href="http://www.allegro.cc/manual/al_register_event_source"><span class="a">al_register_event_source</span></a><span class="k2">(</span>event_queue, <a href="http://www.allegro.cc/manual/al_get_timer_event_source"><span class="a">al_get_timer_event_source</span></a><span class="k2">(</span>thr_timer<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  4</span><a href="http://www.allegro.cc/manual/al_start_timer"><span class="a">al_start_timer</span></a><span class="k2">(</span>thr_timer<span class="k2">)</span><span class="k2">;</span>
<span class="number">  5</span><span class="k1">if</span> <span class="k2">(</span>ev.timer.source <span class="k3">=</span><span class="k3">=</span> thr_timer<span class="k2">)</span> <span class="k3">+</span><span class="k3">+</span>thr_proc<span class="k2">;</span>
<span class="number">  6</span>
<span class="number">  7</span><span class="k1">void</span> <span class="k3">*</span>mwPacketBuffer::rx_thread_func<span class="k2">(</span><a href="http://www.allegro.cc/manual/ALLEGRO_THREAD"><span class="a">ALLEGRO_THREAD</span></a> <span class="k3">*</span>thr, <span class="k1">void</span> <span class="k3">*</span>arg<span class="k2">)</span>
<span class="number">  8</span><span class="k2">{</span>
<span class="number">  9</span>    <span class="k1">while</span> <span class="k2">(</span><span class="n">1</span><span class="k2">)</span>
<span class="number"> 10</span>    <span class="k2">{</span>
<span class="number"> 11</span>        <span class="k1">while</span> <span class="k2">(</span>mEventQueue.thr_proc<span class="k2">)</span>
<span class="number"> 12</span>        <span class="k2">{</span>
<span class="number"> 13</span>            mPacketBuffer.add_to_rx_buffer<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 14</span>            <span class="k3">-</span><span class="k3">-</span>mEventQueue.thr_proc<span class="k2">;</span>
<span class="number"> 15</span>        <span class="k2">}</span>
<span class="number"> 16</span>        <a href="http://www.allegro.cc/manual/al_rest"><span class="a">al_rest</span></a><span class="k2">(</span><span class="n">0</span>.<span class="n">01</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 17</span>    <span class="k2">}</span>
<span class="number"> 18</span><span class="k2">}</span>
</div></div><p>

Would it not cause bursts?</p><p>While al_rest(0.01), would not thr_proc increment to 100?<br />Then a burst of 100 &#39;add_to_rx_buffer&#39; while thr_proc decrements back to zero?</p><p>The main thing I want to do is get the packets arrival time.<br />I am not actually processing them yet, I am just sticking them in a buffer for later processing.</p><p>I have to poll to check if there are any packets waiting.</p><p>This is what I want to do at a regular interval.</p><p>I have thought about it today at work and I realize a mistake I made.</p><p>Using event timers like I do, depends on how often I process the event queue.</p><p>And I am still processing that like this:</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span>
<span class="number">  2</span>loop<span class="k2">(</span><span class="k2">)</span>
<span class="number">  3</span><span class="k2">{</span>
<span class="number">  4</span>   proc_event_queue<span class="k2">(</span><span class="k2">)</span>
<span class="number">  5</span>
<span class="number">  6</span>   <span class="k1">if</span> <span class="k2">(</span>game_loop_event_timer<span class="k2">)</span>
<span class="number">  7</span>   <span class="k2">{</span>
<span class="number">  8</span>      get input
<span class="number">  9</span>      move
<span class="number"> 10</span>      draw
<span class="number"> 11</span>   <span class="k2">}</span>
<span class="number"> 12</span>
<span class="number"> 13</span>
<span class="number"> 14</span><span class="k2">}</span>
</div></div><p>

When the code in the game loop takes a significant time I am not processing the event queue, so I am not setting the variable that triggers the &#39;add_to_rx_buffer&#39;<br />in the other thread.</p><p>This is exactly the problem I was trying to solve in the first place!</p><p>So I think I will abandon allegro timers for this case and tentatively use my own custom self contained al_rest:</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span>
<span class="number">  2</span><span class="k1">void</span> <span class="k3">*</span>mwPacketBuffer::rx_thread_func<span class="k2">(</span><a href="http://www.allegro.cc/manual/ALLEGRO_THREAD"><span class="a">ALLEGRO_THREAD</span></a> <span class="k3">*</span>thr, <span class="k1">void</span> <span class="k3">*</span>arg<span class="k2">)</span>
<span class="number">  3</span><span class="k2">{</span>
<span class="number">  4</span>   <span class="k1">while</span> <span class="k2">(</span><span class="n">1</span><span class="k2">)</span>
<span class="number">  5</span>   <span class="k2">{</span>
<span class="number">  6</span>      <span class="k1">static</span> <span class="k1">double</span> t0 <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_get_time"><span class="a">al_get_time</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  7</span>      <span class="k1">double</span> t1 <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_get_time"><span class="a">al_get_time</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  8</span>      <span class="k1">if</span> <span class="k2">(</span>t1-t0&gt;0.0001<span class="k2">)</span>
<span class="number">  9</span>      <span class="k2">{</span>
<span class="number"> 10</span>         t0 <span class="k3">=</span> t1<span class="k2">;</span>
<span class="number"> 11</span>         mPacketBuffer.add_to_rx_buffer<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 12</span>      <span class="k2">}</span>
<span class="number"> 13</span>   <span class="k2">}</span>
<span class="number"> 14</span><span class="k2">}</span>
</div></div><p>

I still have plenty of testing to do though...</p><p>Polybios:</p><p>I have to actively poll to see if a new packet is available.</p><p>I am using an ancient library: libnet 0.10.2 from 1999</p><p>Thank you both for your time and suggestions.</p><p>I need to do much more experimenting and testing....</p><p>EDIT</p><p>I have done much more experimenting and here is what I have found:</p><p>Allegro threads with al_rest() work like I would expect. They do not spin lock and waste cpu time.<br />The down side is that I cannot seem to get lower than 1 ms with al_rest() and 2ms on a windows 10 machine.</p><p>I experimented with C++ 11 std:threads and got very similar results<br />I used std::this_thread::sleep_for() but I was again not able to get better than 1ms.</p><p>I am pretty sure its limited by the underlying system.</p><p>My method of:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">static</span> <span class="k1">double</span> t0 <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_get_time"><span class="a">al_get_time</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="k1">double</span> t1 <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_get_time"><span class="a">al_get_time</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="k1">if</span> <span class="k2">(</span>t1-t0 <span class="k3">&gt;</span> <span class="n">0</span>.<span class="n">001</span><span class="k2">)</span>
</pre></div></div><p>

turned out to be the worst of all.<br />It could actually do times less than 1ms, but the high cpu usage caused everything else to break.</p><p>So I will probably stick with running the packet checking thread at 1000Hz, which is not so bad.</p><p>Or I will go back to the old method, of checking as fast as it will go, but only in the wait time after processing the game loop.</p><p>I have actually added a few more manual packets checks in the middle of the game loop to help.</p><p>It is really a shame though that it does not seem possible to throttle the speed of the thread past a certain point.</p><p>1000Hz (or 1ms) seems to be the limit.  But yet when there is no limit it can run at 200kHz (5us) to over 1MHz (&lt;1us)</p><p>That seems like such a huge difference.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Michael Weiss)</author>
		<pubDate>Sat, 07 Oct 2023 06:49:10 +0000</pubDate>
	</item>
</rss>
