<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>The Community Needs You. New Tutorial (Threads)</title>
		<link>http://www.allegro.cc/forums/view/607455</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Thu, 23 Jun 2011 05:44:32 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>A crazy noob has just created a new but uncompleted tutorial and put it on the Wiki, it&#39;s your objective to clean it and refine it. So others members can use it and not get confused. 
</p><pre>
Objectives:

- Orthography
- Typos
- Expressions
</pre><p>

<a href="http://wiki.allegro.cc/index.php?title=Allegro_5_Tutorial/Threads">START</a><br />OPTIONS<br />CREDITS<br />EXIT
</p><pre>Published by: UBISOFT™         A game by: AMCerasoli™
</pre><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (AMCerasoli)</author>
		<pubDate>Sat, 28 May 2011 02:17:36 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You don&#39;t explain well why you should check for the is_ready flag, you skip explaining lock_cond, there were some typo&#39;s and I still can&#39;t log into the wiki<span class="ref"><sup>[<a href="#">1</a>]</sup></span>.<br />Oh yeah, and good job <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" /> Personally I&#39;d like to squeeze out the C++ bits, and mash it all into a smooth Allegro example. It&#39;s gonna be loovely. &lt;/ tvchefimpersonation&gt;
</p><div class="ref-block"><h2>References</h2><ol><li><a href="http://www.allegro.cc/forums/thread/598607">http://www.allegro.cc/forums/thread/598607</a></li></ol></div></div>]]>
		</description>
		<author>no-reply@allegro.cc (weapon_S)</author>
		<pubDate>Sat, 28 May 2011 04:26:19 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>When the Wiki read your sign, said <b>NO WAY BODY!</b>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (AMCerasoli)</author>
		<pubDate>Sat, 28 May 2011 05:07:19 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>Sarting</p></div></div><p>
<a href="http://www.youtube.com/watch?v=YvTW7341kpA">Sarting out sarting</a>? <img src="http://www.allegro.cc/forums/smileys/huh.gif" alt="???" /></p><p>Oh, and as for the C++: learn to use <a href="http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6">initialization lists</a>.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (gnolam)</author>
		<pubDate>Sat, 28 May 2011 05:48:55 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Oh, thanks gnolam, I didn&#39;t know anything about initialization list, well I think was obvious hohohoho.</p><p>Anyway I have changed it:</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">class</span> DATA<span class="k2">{</span>
<span class="number">  3</span>
<span class="number">  4</span>   public:
<span class="number">  5</span>
<span class="number">  6</span>      <a href="http://www.allegro.cc/manual/ALLEGRO_MUTEX"><span class="a">ALLEGRO_MUTEX</span></a> <span class="k3">*</span>mutex<span class="k2">;</span>
<span class="number">  7</span>      <a href="http://www.allegro.cc/manual/ALLEGRO_COND"><span class="a">ALLEGRO_COND</span></a>  <span class="k3">*</span>cond<span class="k2">;</span>
<span class="number">  8</span>      <span class="k1">float</span>          posiX<span class="k2">;</span>
<span class="number">  9</span>      <span class="k1">float</span>          posiY<span class="k2">;</span>
<span class="number"> 10</span>      <span class="k1">bool</span>           modi_X<span class="k2">;</span>
<span class="number"> 11</span>      <span class="k1">bool</span>           ready<span class="k2">;</span>
<span class="number"> 12</span>
<span class="number"> 13</span>   DATA<span class="k2">(</span><span class="k2">)</span> <span class="k2">:</span> mutex<span class="k2">(</span><a href="http://www.allegro.cc/manual/al_create_mutex"><span class="a">al_create_mutex</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">)</span>,
<span class="number"> 14</span>            cond<span class="k2">(</span><a href="http://www.allegro.cc/manual/al_create_cond"><span class="a">al_create_cond</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">)</span>,
<span class="number"> 15</span>            posiX <span class="k2">(</span><span class="n">0</span><span class="k2">)</span>,
<span class="number"> 16</span>            posiY <span class="k2">(</span><span class="n">0</span><span class="k2">)</span>,
<span class="number"> 17</span>            modi_X<span class="k2">(</span><span class="k1">false</span><span class="k2">)</span>,
<span class="number"> 18</span>            ready <span class="k2">(</span><span class="k1">false</span><span class="k2">)</span> <span class="k2">{</span><span class="k2">}</span>
<span class="number"> 19</span>
<span class="number"> 20</span>   ~DATA<span class="k2">(</span><span class="k2">)</span><span class="k2">{</span>
<span class="number"> 21</span>
<span class="number"> 22</span>      <a href="http://www.allegro.cc/manual/al_destroy_mutex"><span class="a">al_destroy_mutex</span></a><span class="k2">(</span>mutex<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 23</span>      <a href="http://www.allegro.cc/manual/al_destroy_cond"><span class="a">al_destroy_cond</span></a><span class="k2">(</span>cond<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 24</span>
<span class="number"> 25</span>   <span class="k2">}</span>
<span class="number"> 26</span>
<span class="number"> 27</span><span class="k2">}</span><span class="k2">;</span>
</div></div><p>

I think now it&#39;s fine.</p><p>and what for it&#39;s the <span class="source-code"><span class="k2">{</span><span class="k2">}</span></span> at the end now?</p><p>@weapon_S I can&#39;t manage to explain better the example, how would you explain it? write it here, and I&#39;ll post it. Only that part that you said.</p><p><span class="remote-thumbnail"><span class="json">{"name":"604195","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/9\/99e8f31cf663c1df6d02aa0e3ba52274.png","w":343,"h":623,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/9\/99e8f31cf663c1df6d02aa0e3ba52274"}</span><img src="http://www.allegro.cc//djungxnpq2nug.cloudfront.net/image/cache/9/9/99e8f31cf663c1df6d02aa0e3ba52274-240.jpg" alt="604195" width="240" height="435" /></span>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (AMCerasoli)</author>
		<pubDate>Mon, 30 May 2011 01:44:14 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>In that loose {}, you should be checking the return values of <span class="source-code"><a href="http://www.allegro.cc/manual/al_create_mutex"><span class="a">al_create_mutex</span></a><span class="k2">(</span><span class="k2">)</span></span> and <span class="source-code"><a href="http://www.allegro.cc/manual/al_create_cond"><span class="a">al_create_cond</span></a><span class="k2">(</span><span class="k2">)</span></span>, if they failed to be created, then either throwing an exception, or set a value to mark the class as bad.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Timorg)</author>
		<pubDate>Mon, 30 May 2011 04:43:52 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Or have a separate init method that can return a failure.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Mon, 30 May 2011 07:46:21 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Some things I don&#39;t understand, some things I think should be improved, but don&#39;t know how, and some things I know are wrong but-what-the-hey are marked with triple question marks \???<br />I also think this should be either god-grieving C++ or satanlicious C: not a mix.<br />You know what would be kinky? If the parent thread used a (second) condition to start the two child threads.<br />&lt;insert worst profanity /&gt; <img src="http://www.allegro.cc/forums/smileys/kiss.gif" alt=":-*" /> It seems file upload I broken too. (But only for me of course. And, yes, I know about the new backwards editing procedure.)
</p><div class="spoiler"><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="s">''</span><span class="s">'Under Construction'</span><span class="s">''</span>
<span class="number">   2</span>
<span class="number">   3</span>In <span class="k1">this</span> section we<span class="s">'ll learn how to use the Allegro 5 threading interface.</span>
<span class="number">   4</span><span class="s">=== Abstract ===</span>
<span class="number">   5</span><span class="s"></span>
<span class="number">   6</span><span class="s">In this example we'</span>re going to use the same bitmap created in the previous example, but instead of changing its axis with the mouse, we<span class="s">'re going to let two thread to modified them.</span>
<span class="number">   7</span><span class="s"></span>
<span class="number">   8</span><span class="s">&lt;source lang="c"&gt;</span>
<span class="number">   9</span><span class="s">#include &lt;stdio.h&gt;</span>
<span class="number">  10</span><span class="s">#include &lt;allegro5/allegro.h&gt;</span>
<span class="number">  11</span><span class="s"></span>
<span class="number">  12</span><span class="s">class DATA{</span>
<span class="number">  13</span><span class="s"></span>
<span class="number">  14</span><span class="s">   public:</span>
<span class="number">  15</span><span class="s"></span>
<span class="number">  16</span><span class="s">      ALLEGRO_MUTEX *mutex;</span>
<span class="number">  17</span><span class="s">      ALLEGRO_COND  *cond;</span>
<span class="number">  18</span><span class="s">      float          posiX;</span>
<span class="number">  19</span><span class="s">      float          posiY;</span>
<span class="number">  20</span><span class="s">      bool           modi_X;</span>
<span class="number">  21</span><span class="s">      bool           ready;</span>
<span class="number">  22</span><span class="s"></span>
<span class="number">  23</span><span class="s">   DATA() : mutex(al_create_mutex()),</span>
<span class="number">  24</span><span class="s">            cond(al_create_cond()),</span>
<span class="number">  25</span><span class="s">            posiX (0),</span>
<span class="number">  26</span><span class="s">            posiY (0),</span>
<span class="number">  27</span><span class="s">            modi_X(false),</span>
<span class="number">  28</span><span class="s">            ready (false) {}</span>
<span class="number">  29</span><span class="s"></span>
<span class="number">  30</span><span class="s">   ~DATA(){</span>
<span class="number">  31</span><span class="s"></span>
<span class="number">  32</span><span class="s">      al_destroy_mutex(mutex);</span>
<span class="number">  33</span><span class="s">      al_destroy_cond(cond);</span>
<span class="number">  34</span><span class="s"></span>
<span class="number">  35</span><span class="s">   }</span>
<span class="number">  36</span><span class="s"></span>
<span class="number">  37</span><span class="s">};</span>
<span class="number">  38</span><span class="s"></span>
<span class="number">  39</span><span class="s">const float FPS        = 30;</span>
<span class="number">  40</span><span class="s">const int SCREEN_W     = 640;</span>
<span class="number">  41</span><span class="s">const int SCREEN_H     = 480;</span>
<span class="number">  42</span><span class="s">const int BOUNCER_SIZE = 32;</span>
<span class="number">  43</span><span class="s"></span>
<span class="number">  44</span><span class="s">static void *Func_Thread(ALLEGRO_THREAD *thr, void *arg);</span>
<span class="number">  45</span><span class="s"></span>
<span class="number">  46</span><span class="s">int main(int argc, char **argv)</span>
<span class="number">  47</span><span class="s">{</span>
<span class="number">  48</span><span class="s">   ALLEGRO_DISPLAY     *display     = NULL;</span>
<span class="number">  49</span><span class="s">   ALLEGRO_EVENT_QUEUE *event_queue = NULL;</span>
<span class="number">  50</span><span class="s">   ALLEGRO_TIMER       *timer       = NULL;</span>
<span class="number">  51</span><span class="s">   ALLEGRO_BITMAP      *bouncer     = NULL;</span>
<span class="number">  52</span><span class="s">   ALLEGRO_THREAD      *thread_1    = NULL;</span>
<span class="number">  53</span><span class="s">   ALLEGRO_THREAD      *thread_2    = NULL;</span>
<span class="number">  54</span><span class="s"></span>
<span class="number">  55</span><span class="s">   bool redraw = true;</span>
<span class="number">  56</span><span class="s"></span>
<span class="number">  57</span><span class="s">   if(!al_init()) {</span>
<span class="number">  58</span><span class="s">      fprintf(stderr, "failed to initialize allegro!\n");</span>
<span class="number">  59</span><span class="s">      return -1;</span>
<span class="number">  60</span><span class="s">   }</span>
<span class="number">  61</span><span class="s"></span>
<span class="number">  62</span><span class="s">   if(!al_install_mouse()) {</span>
<span class="number">  63</span><span class="s">      fprintf(stderr, "failed to initialize the mouse!\n");</span>
<span class="number">  64</span><span class="s">      return -1;</span>
<span class="number">  65</span><span class="s">   }</span>
<span class="number">  66</span><span class="s"></span>
<span class="number">  67</span><span class="s">   timer = al_create_timer(1.0 / FPS);</span>
<span class="number">  68</span><span class="s">   if(!timer) {</span>
<span class="number">  69</span><span class="s">      fprintf(stderr, "failed to create timer!\n");</span>
<span class="number">  70</span><span class="s">      return -1;</span>
<span class="number">  71</span><span class="s">   }</span>
<span class="number">  72</span><span class="s"></span>
<span class="number">  73</span><span class="s">   display = al_create_display(SCREEN_W, SCREEN_H);</span>
<span class="number">  74</span><span class="s">   if(!display) {</span>
<span class="number">  75</span><span class="s">      fprintf(stderr, "failed to create display!\n");</span>
<span class="number">  76</span><span class="s">      al_destroy_timer(timer);</span>
<span class="number">  77</span><span class="s">      return -1;</span>
<span class="number">  78</span><span class="s">   }</span>
<span class="number">  79</span><span class="s"></span>
<span class="number">  80</span><span class="s">   bouncer = al_create_bitmap(BOUNCER_SIZE, BOUNCER_SIZE);</span>
<span class="number">  81</span><span class="s">   if(!bouncer) {</span>
<span class="number">  82</span><span class="s">      fprintf(stderr, "failed to create bouncer bitmap!\n");</span>
<span class="number">  83</span><span class="s">      al_destroy_display(display);</span>
<span class="number">  84</span><span class="s">      al_destroy_timer(timer);</span>
<span class="number">  85</span><span class="s">      return -1;</span>
<span class="number">  86</span><span class="s">   }</span>
<span class="number">  87</span><span class="s"></span>
<span class="number">  88</span><span class="s">   al_set_target_bitmap(bouncer);</span>
<span class="number">  89</span><span class="s">   al_clear_to_color(al_map_rgb(255, 0, 255));</span>
<span class="number">  90</span><span class="s">   al_set_target_bitmap(al_get_backbuffer(display));</span>
<span class="number">  91</span><span class="s">   event_queue = al_create_event_queue();</span>
<span class="number">  92</span><span class="s"></span>
<span class="number">  93</span><span class="s">   if(!event_queue) {</span>
<span class="number">  94</span><span class="s">      fprintf(stderr, "failed to create event_queue!\n");</span>
<span class="number">  95</span><span class="s">      al_destroy_bitmap(bouncer);</span>
<span class="number">  96</span><span class="s">      al_destroy_display(display);</span>
<span class="number">  97</span><span class="s">      al_destroy_timer(timer);</span>
<span class="number">  98</span><span class="s">      return -1;</span>
<span class="number">  99</span><span class="s">   }</span>
<span class="number"> 100</span><span class="s"></span>
<span class="number"> 101</span><span class="s">   al_register_event_source(event_queue, al_get_display_event_source(display));</span>
<span class="number"> 102</span><span class="s">   al_register_event_source(event_queue, al_get_timer_event_source(timer));</span>
<span class="number"> 103</span><span class="s">   al_register_event_source(event_queue, al_get_mouse_event_source());</span>
<span class="number"> 104</span><span class="s">   al_clear_to_color(al_map_rgb(0,0,0));</span>
<span class="number"> 105</span><span class="s">   al_flip_display();</span>
<span class="number"> 106</span><span class="s">   al_start_timer(timer);</span>
<span class="number"> 107</span><span class="s"></span>
<span class="number"> 108</span><span class="s">   DATA data;</span>
<span class="number"> 109</span><span class="s"></span>
<span class="number"> 110</span><span class="s">   thread_1 = al_create_thread(Func_Thread, &amp;data);</span>
<span class="number"> 111</span><span class="s">   al_start_thread(thread_1);</span>
<span class="number"> 112</span><span class="s"></span>
<span class="number"> 113</span><span class="s">   al_lock_mutex(data.mutex);</span>
<span class="number"> 114</span><span class="s">   while (!data.ready){</span>
<span class="number"> 115</span><span class="s"></span>
<span class="number"> 116</span><span class="s">      al_wait_cond(data.cond, data.mutex);</span>
<span class="number"> 117</span><span class="s"></span>
<span class="number"> 118</span><span class="s">   }</span>
<span class="number"> 119</span><span class="s">   al_unlock_mutex(data.mutex);</span>
<span class="number"> 120</span><span class="s"></span>
<span class="number"> 121</span><span class="s">   al_lock_mutex(data.mutex);</span>
<span class="number"> 122</span><span class="s">   data.modi_X = true;</span>
<span class="number"> 123</span><span class="s">   data.ready  = false;</span>
<span class="number"> 124</span><span class="s">   al_unlock_mutex(data.mutex);</span>
<span class="number"> 125</span><span class="s"></span>
<span class="number"> 126</span><span class="s">   thread_2 = al_create_thread(Func_Thread, &amp;data);</span>
<span class="number"> 127</span><span class="s">   al_start_thread(thread_2);</span>
<span class="number"> 128</span><span class="s"></span>
<span class="number"> 129</span><span class="s">   al_lock_mutex(data.mutex);</span>
<span class="number"> 130</span><span class="s">   while (!data.ready){</span>
<span class="number"> 131</span><span class="s"></span>
<span class="number"> 132</span><span class="s">      al_wait_cond(data.cond, data.mutex);</span>
<span class="number"> 133</span><span class="s"></span>
<span class="number"> 134</span><span class="s">   }</span>
<span class="number"> 135</span><span class="s">   al_unlock_mutex(data.mutex);</span>
<span class="number"> 136</span><span class="s"></span>
<span class="number"> 137</span><span class="s"></span>
<span class="number"> 138</span><span class="s">   while(1)</span>
<span class="number"> 139</span><span class="s">   {</span>
<span class="number"> 140</span><span class="s">      ALLEGRO_EVENT ev;</span>
<span class="number"> 141</span><span class="s">      al_wait_for_event(event_queue, &amp;ev);</span>
<span class="number"> 142</span><span class="s"></span>
<span class="number"> 143</span><span class="s">      if(ev.type == ALLEGRO_EVENT_TIMER) {</span>
<span class="number"> 144</span><span class="s">         redraw = true;</span>
<span class="number"> 145</span><span class="s">      }</span>
<span class="number"> 146</span><span class="s">      else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {</span>
<span class="number"> 147</span><span class="s">         break;</span>
<span class="number"> 148</span><span class="s">      }</span>
<span class="number"> 149</span><span class="s">      else if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) {</span>
<span class="number"> 150</span><span class="s">         break;</span>
<span class="number"> 151</span><span class="s">      }</span>
<span class="number"> 152</span><span class="s">      if(redraw &amp;&amp; al_is_event_queue_empty(event_queue)) {</span>
<span class="number"> 153</span><span class="s">         redraw = false;</span>
<span class="number"> 154</span><span class="s"></span>
<span class="number"> 155</span><span class="s">         al_lock_mutex(data.mutex);</span>
<span class="number"> 156</span><span class="s">         data.modi_X = true;</span>
<span class="number"> 157</span><span class="s">         data.ready  = false;</span>
<span class="number"> 158</span><span class="s">         al_unlock_mutex(data.mutex);</span>
<span class="number"> 159</span><span class="s"></span>
<span class="number"> 160</span><span class="s">         al_draw_bitmap(bouncer, data.posiX, data.posiY, 0);</span>
<span class="number"> 161</span><span class="s"></span>
<span class="number"> 162</span><span class="s"></span>
<span class="number"> 163</span><span class="s">         al_flip_display();</span>
<span class="number"> 164</span><span class="s">      }</span>
<span class="number"> 165</span><span class="s">   }</span>
<span class="number"> 166</span><span class="s">   al_destroy_thread(thread_1);</span>
<span class="number"> 167</span><span class="s">   al_destroy_thread(thread_2);</span>
<span class="number"> 168</span><span class="s"></span>
<span class="number"> 169</span><span class="s">   al_destroy_bitmap(bouncer);</span>
<span class="number"> 170</span><span class="s">   al_destroy_timer(timer);</span>
<span class="number"> 171</span><span class="s">   al_destroy_display(display);</span>
<span class="number"> 172</span><span class="s">   al_destroy_event_queue(event_queue);</span>
<span class="number"> 173</span><span class="s"></span>
<span class="number"> 174</span><span class="s">   return 0;</span>
<span class="number"> 175</span><span class="s">}</span>
<span class="number"> 176</span><span class="s"></span>
<span class="number"> 177</span><span class="s">   static void *Func_Thread(ALLEGRO_THREAD *thr, void *arg){</span>
<span class="number"> 178</span><span class="s"></span>
<span class="number"> 179</span><span class="s">   DATA *data  = (DATA*) arg;</span>
<span class="number"> 180</span><span class="s">   float num   = 0.1;</span>
<span class="number"> 181</span><span class="s"></span>
<span class="number"> 182</span><span class="s">   al_lock_mutex(data-&gt;mutex);</span>
<span class="number"> 183</span><span class="s"></span>
<span class="number"> 184</span><span class="s">   bool modi_X = data-&gt;modi_X;</span>
<span class="number"> 185</span><span class="s">   data-&gt;ready = true;</span>
<span class="number"> 186</span><span class="s">   al_broadcast_cond(data-&gt;cond);</span>
<span class="number"> 187</span><span class="s"></span>
<span class="number"> 188</span><span class="s">   al_unlock_mutex(data-&gt;mutex);</span>
<span class="number"> 189</span><span class="s"></span>
<span class="number"> 190</span><span class="s">   while(!al_get_thread_should_stop(thr)){</span>
<span class="number"> 191</span><span class="s"></span>
<span class="number"> 192</span><span class="s">      al_lock_mutex(data-&gt;mutex);</span>
<span class="number"> 193</span><span class="s">      if(modi_X)</span>
<span class="number"> 194</span><span class="s">         data-&gt;posiX += num;</span>
<span class="number"> 195</span><span class="s">      else</span>
<span class="number"> 196</span><span class="s">         data-&gt;posiY += num;</span>
<span class="number"> 197</span><span class="s">      al_unlock_mutex(data-&gt;mutex);</span>
<span class="number"> 198</span><span class="s"></span>
<span class="number"> 199</span><span class="s">      al_rest(0.01);</span>
<span class="number"> 200</span><span class="s"></span>
<span class="number"> 201</span><span class="s">   }</span>
<span class="number"> 202</span><span class="s"></span>
<span class="number"> 203</span><span class="s"></span>
<span class="number"> 204</span><span class="s">   return NULL;</span>
<span class="number"> 205</span><span class="s">   }</span>
<span class="number"> 206</span><span class="s">&lt;/source&gt;</span>
<span class="number"> 207</span><span class="s"></span>
<span class="number"> 208</span><span class="s">=== Let'</span>s get started <span class="k3">=</span><span class="k3">=</span><span class="k3">=</span>
<span class="number"> 209</span>
<span class="number"> 210</span>
<span class="number"> 211</span><span class="k3">&lt;</span>source lang<span class="k3">=</span><span class="s">"c"</span><span class="k3">&gt;</span>   
<span class="number"> 212</span><span class="k1">class</span> DATA<span class="k2">{</span>
<span class="number"> 213</span>
<span class="number"> 214</span>   public:
<span class="number"> 215</span>
<span class="number"> 216</span>      <a href="http://www.allegro.cc/manual/ALLEGRO_MUTEX"><span class="a">ALLEGRO_MUTEX</span></a> <span class="k3">*</span>mutex<span class="k2">;</span>
<span class="number"> 217</span>      <a href="http://www.allegro.cc/manual/ALLEGRO_COND"><span class="a">ALLEGRO_COND</span></a>  <span class="k3">*</span>cond<span class="k2">;</span>
<span class="number"> 218</span>      <span class="k1">float</span>          posiX<span class="k2">;</span>
<span class="number"> 219</span>      <span class="k1">float</span>          posiY<span class="k2">;</span>
<span class="number"> 220</span>      <span class="k1">bool</span>           modi_X<span class="k2">;</span>
<span class="number"> 221</span>      <span class="k1">bool</span>           ready<span class="k2">;</span>
<span class="number"> 222</span>
<span class="number"> 223</span>   DATA<span class="k2">(</span><span class="k2">)</span> <span class="k2">:</span> mutex<span class="k2">(</span><a href="http://www.allegro.cc/manual/al_create_mutex"><span class="a">al_create_mutex</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">)</span>,
<span class="number"> 224</span>            cond<span class="k2">(</span><a href="http://www.allegro.cc/manual/al_create_cond"><span class="a">al_create_cond</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">)</span>,
<span class="number"> 225</span>            posiX <span class="k2">(</span><span class="n">0</span><span class="k2">)</span>,
<span class="number"> 226</span>            posiY <span class="k2">(</span><span class="n">0</span><span class="k2">)</span>,
<span class="number"> 227</span>            modi_X<span class="k2">(</span><span class="k1">false</span><span class="k2">)</span>,
<span class="number"> 228</span>            ready <span class="k2">(</span><span class="k1">false</span><span class="k2">)</span> <span class="k2">{</span><span class="k2">}</span>
<span class="number"> 229</span>
<span class="number"> 230</span>   ~DATA<span class="k2">(</span><span class="k2">)</span><span class="k2">{</span>
<span class="number"> 231</span>
<span class="number"> 232</span>      <a href="http://www.allegro.cc/manual/al_destroy_mutex"><span class="a">al_destroy_mutex</span></a><span class="k2">(</span>mutex<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 233</span>      <a href="http://www.allegro.cc/manual/al_destroy_cond"><span class="a">al_destroy_cond</span></a><span class="k2">(</span>cond<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 234</span>
<span class="number"> 235</span>   <span class="k2">}</span>
<span class="number"> 236</span>
<span class="number"> 237</span><span class="k2">}</span><span class="k2">;</span>
<span class="number"> 238</span><span class="k3">&lt;</span><span class="k3">/</span>source&gt;
<span class="number"> 239</span>
<span class="number"> 240</span>First we create a <span class="k1">class</span>, which is going to contain the data we want to exchange between threads.
<span class="number"> 241</span>
<span class="number"> 242</span><span class="k3">&lt;</span>source lang<span class="k3">=</span><span class="s">"c"</span><span class="k3">&gt;</span><a href="http://www.allegro.cc/manual/ALLEGRO_MUTEX"><span class="a">ALLEGRO_MUTEX</span></a> <span class="k3">*</span>mutex<span class="k3">&lt;</span><span class="k3">/</span>source&gt;
<span class="number"> 243</span>
<span class="number"> 244</span>Here we declare a <span class="k3">/</span>mutex<span class="k3">/</span> <span class="k2">(</span>mutual exclusion<span class="k2">)</span>. In essence it<span class="s">'s a flag that'</span>s supposed to <a href="http://www.delorie.com/djgpp/doc/libc/libc_813.html" target="_blank">tell</a> other threads to leave some data alone. You can<span class="s">'t set it directly, though. This should become clear why.</span>
<span class="number"> 245</span><span class="s"></span>
<span class="number"> 246</span><span class="s">&lt;source lang="c"&gt;ALLEGRO_COND  *cond;&lt;/source&gt;</span>
<span class="number"> 247</span><span class="s"></span>
<span class="number"> 248</span><span class="s">Here we declare a /condition/. It is sort of a sign that can asynchrously be picked up by other threads. Again you'</span>ll have to use functions to use it.
<span class="number"> 249</span>
<span class="number"> 250</span><span class="k3">&lt;</span>source lang<span class="k3">=</span><span class="s">"c"</span><span class="k3">&gt;</span>
<span class="number"> 251</span>      <span class="k1">float</span>          posiX<span class="k2">;</span>
<span class="number"> 252</span>      <span class="k1">float</span>          posiY<span class="k2">;</span>
<span class="number"> 253</span>      <span class="k1">bool</span>           modi_X<span class="k2">;</span>
<span class="number"> 254</span>      <span class="k1">bool</span>           ready<span class="k2">;</span><span class="k3">&lt;</span><span class="k3">/</span>source&gt;
<span class="number"> 255</span>
<span class="number"> 256</span><span class="k3">&lt;</span>code&gt;posiX<span class="k3">&lt;</span><span class="k3">/</span>code&gt;, <span class="k1">and</span> <span class="k3">&lt;</span>code&gt;posiY<span class="k3">&lt;</span><span class="k3">/</span>code&gt; are the X, <span class="k1">and</span> Y coordinates of our bitmap, <span class="k3">&lt;</span>code&gt;modi_X<span class="k3">&lt;</span><span class="k3">/</span>code&gt; <span class="k1">and</span> <span class="k3">&lt;</span>code&gt;ready<span class="k3">&lt;</span><span class="k3">/</span>code&gt; are two flags that we<span class="s">'re going to use later on.</span>
<span class="number"> 257</span><span class="s"></span>
<span class="number"> 258</span><span class="s">&lt;source lang="c"&gt;</span>
<span class="number"> 259</span><span class="s"></span>
<span class="number"> 260</span><span class="s">   DATA() : mutex(al_create_mutex()),</span>
<span class="number"> 261</span><span class="s">            cond(al_create_cond()),</span>
<span class="number"> 262</span><span class="s">            posiX (0),</span>
<span class="number"> 263</span><span class="s">            posiY (0),</span>
<span class="number"> 264</span><span class="s">            modi_X(false),</span>
<span class="number"> 265</span><span class="s">            ready (false) {}</span>
<span class="number"> 266</span><span class="s"> </span>
<span class="number"> 267</span><span class="s">   ~DATA(){</span>
<span class="number"> 268</span><span class="s"> </span>
<span class="number"> 269</span><span class="s">      al_destroy_mutex(mutex);</span>
<span class="number"> 270</span><span class="s">      al_destroy_cond(cond);</span>
<span class="number"> 271</span><span class="s"> </span>
<span class="number"> 272</span><span class="s">   }</span>
<span class="number"> 273</span><span class="s"></span>
<span class="number"> 274</span><span class="s">&lt;/source&gt;</span>
<span class="number"> 275</span><span class="s"></span>
<span class="number"> 276</span><span class="s">Class'</span>s constructor, <span class="k1">using</span> a initialization list. Followed by the destructor. <span class="s">''</span><span class="s">'Note:'</span><span class="s">''</span> you cannot make an instance of <span class="k1">this</span> object on global scope, because <span class="k3">&lt;</span>code&gt;al_create_mutex<span class="k3">&lt;</span><span class="k3">/</span>code&gt; <span class="k1">and</span> <span class="k3">&lt;</span>code&gt;al_create_cond<span class="k3">&lt;</span><span class="k3">/</span>code&gt; would be called before <span class="k3">&lt;</span>code&gt;al_init<span class="k3">&lt;</span><span class="k3">/</span>code&gt;.
<span class="number"> 277</span>
<span class="number"> 278</span><span class="k3">&lt;</span>source lang<span class="k3">=</span><span class="s">"c"</span><span class="k3">&gt;</span>   <a href="http://www.allegro.cc/manual/ALLEGRO_THREAD"><span class="a">ALLEGRO_THREAD</span></a>      <span class="k3">*</span>thread_1    <span class="k3">=</span> NULL<span class="k2">;</span>
<span class="number"> 279</span>   <a href="http://www.allegro.cc/manual/ALLEGRO_THREAD"><span class="a">ALLEGRO_THREAD</span></a>      <span class="k3">*</span>thread_2    <span class="k3">=</span> NULL<span class="k2">;</span> <span class="k3">&lt;</span><span class="k3">/</span>source&gt;
<span class="number"> 280</span>
<span class="number"> 281</span>A <span class="k3">/</span>thread<span class="k3">/</span> is like a program running _separately_. Separately means you have no idea how far it has run, <span class="k1">and</span> neither <span class="k1">do</span> they know about eachothers globals???.
<span class="number"> 282</span>
<span class="number"> 283</span><span class="k3">&lt;</span>source lang<span class="k3">=</span><span class="s">"c"</span><span class="k3">&gt;</span>
<span class="number"> 284</span>
<span class="number"> 285</span>   DATA data<span class="k2">;</span>
<span class="number"> 286</span> 
<span class="number"> 287</span>   thread_1 <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_create_thread"><span class="a">al_create_thread</span></a><span class="k2">(</span>Func_Thread, <span class="k3">&amp;</span>data<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 288</span><span class="k3">&lt;</span><span class="k3">/</span>source&gt;   
<span class="number"> 289</span><span class="k3">&lt;</span>code&gt;data<span class="k3">&lt;</span><span class="k3">/</span>code&gt; is neatly created after <span class="k3">&lt;</span>code&gt;al_init<span class="k3">&lt;</span><span class="k3">/</span>code&gt;. <span class="k3">&lt;</span>code&gt;thread_1<span class="k3">&lt;</span><span class="k3">/</span>code&gt; is allocated. Don<span class="s">'t forget to deallocate it afterwards.</span>
<span class="number"> 290</span><span class="s">???Shouldn'</span>t you check it<span class="s">'s value? The thread will be running the function &lt;code&gt;Func_thread&lt;/code&gt; and getting the pointer &lt;code&gt;*data&lt;/code&gt; as its argument when it starts. ???(Or only after it started it head hurts) Because this thread holds all the control information of &lt;code&gt;thread_1&lt;/code&gt;, this thread is called the /parent/ thread and &lt;code&gt;thread_1&lt;/code&gt; is called a /child/ thread.</span>
<span class="number"> 291</span><span class="s">&lt;source lang="c"&gt;</span>
<span class="number"> 292</span><span class="s">   al_start_thread(thread_1);</span>
<span class="number"> 293</span><span class="s">&lt;/source&gt;</span>
<span class="number"> 294</span><span class="s">Now, after god knows how much time Func_Thread will be called god knows how fast, under the nominator of &lt;code&gt;thread_1&lt;/code&gt;.</span>
<span class="number"> 295</span><span class="s">Next lines get technical, but can be seen as 1 unit:</span>
<span class="number"> 296</span><span class="s">&lt;source lang="c"&gt;</span>
<span class="number"> 297</span><span class="s">   al_lock_mutex(data.mutex);</span>
<span class="number"> 298</span><span class="s">   while (!data.ready){</span>
<span class="number"> 299</span><span class="s"> </span>
<span class="number"> 300</span><span class="s">      al_wait_cond(data.cond, data.mutex);</span>
<span class="number"> 301</span><span class="s"> </span>
<span class="number"> 302</span><span class="s">   }</span>
<span class="number"> 303</span><span class="s">   al_unlock_mutex(data.mutex);</span>
<span class="number"> 304</span><span class="s">&lt;\source&gt;</span>
<span class="number"> 305</span><span class="s">Firstly, we /lock/ a /mutex/. An analogy would be shouting "it'</span>s my turn now<span class="k3">!</span><span class="s">". If this thread is the first one to shout, it gets the mutex. If an other thread /locked/ the /mutex/ first, this thread will have to wait until that particular thread /unlocks/ it.</span>
<span class="number"> 306</span><span class="s">&lt;code&gt;al_wait_cond&lt;/code&gt; takes a /locked mutex/ as an argument??? and then unlocks it. Meanwhile it pauses this thread until the /condition/ is /signaled/. There are two reasons you can't use this /condition/ directly to signal something has happened. Number one is: multiple threads could have been waiting for the same condition and have responded to that condition, before you get the chance to do anything.??? Number two is: the thread can also continue whenever the OS feels like kicking it.</span>
<span class="number"> 307</span><span class="s">Now you should understand the reason a &lt;code&gt;while&lt;/code&gt; loop was put around &lt;code&gt;al_wait_cond&lt;/code&gt;; and a variable named &lt;code&gt;ready&lt;/code&gt; was put into the &lt;code&gt;data&lt;/code&gt; structure.</span>
<span class="number"> 308</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt; </span>
<span class="number"> 309</span><span class="s">   al_lock_mutex(data.mutex);</span>
<span class="number"> 310</span><span class="s">   data.modi_X = true;       //???Don't you actually want to run these lines before the previous al_unlock_mutex</span>
<span class="number"> 311</span><span class="s">   data.ready  = false;      //???Don't you actually want to run these lines before the previous al_unlock_mutex</span>
<span class="number"> 312</span><span class="s">   al_unlock_mutex(data.mutex);</span>
<span class="number"> 313</span><span class="s"> </span>
<span class="number"> 314</span><span class="s">   thread_2 = al_create_thread(Func_Thread, &amp;data);</span>
<span class="number"> 315</span><span class="s">   al_start_thread(thread_2);</span>
<span class="number"> 316</span><span class="s"> </span>
<span class="number"> 317</span><span class="s">   al_lock_mutex(data.mutex);</span>
<span class="number"> 318</span><span class="s">   while (!data.ready){</span>
<span class="number"> 319</span><span class="s"> </span>
<span class="number"> 320</span><span class="s">      al_wait_cond(data.cond, data.mutex);</span>
<span class="number"> 321</span><span class="s"> </span>
<span class="number"> 322</span><span class="s">   }</span>
<span class="number"> 323</span><span class="s">   al_unlock_mutex(data.mutex);</span>
<span class="number"> 324</span><span class="s"></span>
<span class="number"> 325</span><span class="s">&lt;/source&gt;</span>
<span class="number"> 326</span><span class="s"></span>
<span class="number"> 327</span><span class="s">Everything until here should be already clear.</span>
<span class="number"> 328</span><span class="s"></span>
<span class="number"> 329</span><span class="s"># ??? In what order are you discussing the file? In what order was I discussing the file? I already discussed this???</span>
<span class="number"> 330</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt;DATA data;&lt;/source&gt;</span>
<span class="number"> 331</span><span class="s"></span>
<span class="number"> 332</span><span class="s">Very obvious, we create our object '''after''' initializing allegro since it's using some allegro functions.</span>
<span class="number"> 333</span><span class="s"></span>
<span class="number"> 334</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt;thread_1 = al_create_thread(Func_Thread, &amp;data);</span>
<span class="number"> 335</span><span class="s">al_start_thread(thread_1);&lt;/source&gt;</span>
<span class="number"> 336</span><span class="s"></span>
<span class="number"> 337</span><span class="s">Here we create our thread and immediately the data is sent. &lt;code&gt;Func_Thread&lt;/code&gt; it's a pointer to a function and &lt;code&gt;&amp;data&lt;/code&gt; it's the address of our recently created object. And since when a thread is created, it is initially in a suspended state, we need to call &lt;code&gt;al_start_thread(thread_1)&lt;/code&gt; to call its actual execution.</span>
<span class="number"> 338</span><span class="s"></span>
<span class="number"> 339</span><span class="s">So, you write your own function that matches this prototype:</span>
<span class="number"> 340</span><span class="s"></span>
<span class="number"> 341</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt; static void *Func_Thread(ALLEGRO_THREAD *thr, void *arg) &lt;/source&gt;</span>
<span class="number"> 342</span><span class="s"></span>
<span class="number"> 343</span><span class="s">Whatever you do inside this functions it's going to be running on a different thread.</span>
<span class="number"> 344</span><span class="s"></span>
<span class="number"> 345</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt; </span>
<span class="number"> 346</span><span class="s"></span>
<span class="number"> 347</span><span class="s">static void *Func_Thread(ALLEGRO_THREAD *thr, void *arg){</span>
<span class="number"> 348</span><span class="s"> </span>
<span class="number"> 349</span><span class="s">   DATA *data  = (DATA*) arg;</span>
<span class="number"> 350</span><span class="s">   float num   = 0.1;</span>
<span class="number"> 351</span><span class="s"> </span>
<span class="number"> 352</span><span class="s">   al_lock_mutex(data-&gt;mutex);</span>
<span class="number"> 353</span><span class="s"> </span>
<span class="number"> 354</span><span class="s">   bool modi_X = data-&gt;modi_X;</span>
<span class="number"> 355</span><span class="s">   data-&gt;ready = true;</span>
<span class="number"> 356</span><span class="s">   al_broadcast_cond(data-&gt;cond);</span>
<span class="number"> 357</span><span class="s"> </span>
<span class="number"> 358</span><span class="s">   al_unlock_mutex(data-&gt;mutex);</span>
<span class="number"> 359</span><span class="s"> </span>
<span class="number"> 360</span><span class="s">   while(!al_get_thread_should_stop(thr)){</span>
<span class="number"> 361</span><span class="s"> </span>
<span class="number"> 362</span><span class="s">      al_lock_mutex(data-&gt;mutex);</span>
<span class="number"> 363</span><span class="s">      if(modi_X)</span>
<span class="number"> 364</span><span class="s">         data-&gt;posiX += num;</span>
<span class="number"> 365</span><span class="s">      else</span>
<span class="number"> 366</span><span class="s">         data-&gt;posiY += num;</span>
<span class="number"> 367</span><span class="s">      al_unlock_mutex(data-&gt;mutex);</span>
<span class="number"> 368</span><span class="s"> </span>
<span class="number"> 369</span><span class="s">      al_rest(0.01);</span>
<span class="number"> 370</span><span class="s"> </span>
<span class="number"> 371</span><span class="s">   }</span>
<span class="number"> 372</span><span class="s"> </span>
<span class="number"> 373</span><span class="s"> </span>
<span class="number"> 374</span><span class="s">   return NULL;</span>
<span class="number"> 375</span><span class="s">   }</span>
<span class="number"> 376</span><span class="s">&lt;/source&gt;</span>
<span class="number"> 377</span><span class="s"></span>
<span class="number"> 378</span><span class="s">The data you sent using &lt;code&gt;al_create_thread()&lt;/code&gt; it's received by this function as a void pointer data type &lt;code&gt;(void *arg)&lt;/code&gt;. So the first thing we need to do here inside, is convert our object back to a DATA data type, which is our original class. </span>
<span class="number"> 379</span><span class="s"></span>
<span class="number"> 380</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt; DATA *data  = (DATA*) arg; &lt;/source&gt;</span>
<span class="number"> 381</span><span class="s"></span>
<span class="number"> 382</span><span class="s">With some typecasting it's done. Remember that data now it's a pointer to a DATA object so we'll use &lt;code&gt;data-&gt;example&lt;/code&gt; instead of &lt;code&gt;data.example&lt;/code&gt;.</span>
<span class="number"> 383</span><span class="s"></span>
<span class="number"> 384</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt; float num   = 0.1; &lt;/source&gt;</span>
<span class="number"> 385</span><span class="s"></span>
<span class="number"> 386</span><span class="s">This is the value we're going to add to our X or Y axis.</span>
<span class="number"> 387</span><span class="s"></span>
<span class="number"> 388</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt; al_lock_mutex(data-&gt;mutex); &lt;/source&gt;</span>
<span class="number"> 389</span><span class="s"></span>
<span class="number"> 390</span><span class="s">And WTH is this?, well, this is how we tell allegro that one of our many threads it's going to use a shared resource. Our data object is also available to our main thread, and it will be available to two more threads. Remember: whichever thread shouts: "</span>My turn<span class="k3">!</span><span class="s">" first, should get sole access to this sort of shared data... for as long as its turn lasts.</span>
<span class="number"> 391</span><span class="s"></span>
<span class="number"> 392</span><span class="s">So for that reason each time we use our data in each thread we need to lock it first. And when we're done we can unlock it.</span>
<span class="number"> 393</span><span class="s"></span>
<span class="number"> 394</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt; bool modi_X = data-&gt;modi_X;</span>
<span class="number"> 395</span><span class="s">   data-&gt;ready = true;</span>
<span class="number"> 396</span><span class="s">   al_broadcast_cond(data-&gt;cond); &lt;/source&gt;</span>
<span class="number"> 397</span><span class="s"></span>
<span class="number"> 398</span><span class="s">So, here we're creating a bool variable , and assign it a value, as you can see when we created our DATA object this value is initialized as false, so the &lt;code&gt;bool modi_X&lt;/code&gt; variable of this thread the first time it is run, is going to be false. We're doing this because we need to tell the parent thread to modified the X value and the other to modified the Y value, so the thread which receive &lt;code&gt;modi_X&lt;/code&gt; (Modify X) as true, is going to do exactly that, modified the X Axi, and the thread which receive &lt;code&gt;modi_X&lt;/code&gt; as false, is going to modified the Y axis.</span>
<span class="number"> 399</span><span class="s"></span>
<span class="number"> 400</span><span class="s">And since this is the first thread ???true but actually not very generic case:(we haven't create/started the second thread) it's going to recive the &lt;code&gt;modi_X&lt;/code&gt; value as false.</span>
<span class="number"> 401</span><span class="s"></span>
<span class="number"> 402</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt; data-&gt;ready = true; &lt;/source&gt;</span>
<span class="number"> 403</span><span class="s"></span>
<span class="number"> 404</span><span class="s">This is the second flag of our data object, we need to use this, because our parent thread needs to wait until we have assigned the &lt;code&gt;modi_X&lt;/code&gt; value. Since we're working with threads we can never assume the order or speed in which two things in parallel happen. So this flag along with the cond struct, allow us to tell our parent thread, when it can move on.</span>
<span class="number"> 405</span><span class="s"></span>
<span class="number"> 406</span><span class="s"></span>
<span class="number"> 407</span><span class="s"></span>
<span class="number"> 408</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt;al_lock_mutex(data.mutex);</span>
<span class="number"> 409</span><span class="s">   if (!data.ready)</span>
<span class="number"> 410</span><span class="s">      al_wait_cond(data.cond, data.mutex);</span>
<span class="number"> 411</span><span class="s"> </span>
<span class="number"> 412</span><span class="s">   al_unlock_mutex(data.mutex)</span>
<span class="number"> 413</span><span class="s"> &lt;/source&gt;</span>
<span class="number"> 414</span><span class="s"></span>
<span class="number"> 415</span><span class="s">This is what we have in our parent thread, basically if data.ready isn't true that means that the second tread haven't initialized the modi_X variable, so we need to wait. and how do we know when the second thread it's done?, how much do we need to wait? here is where conditions come in.</span>
<span class="number"> 416</span><span class="s"></span>
<span class="number"> 417</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt;al_wait_cond(data.cond, data.mutex);&lt;/source&gt;</span>
<span class="number"> 418</span><span class="s"></span>
<span class="number"> 419</span><span class="s">&lt;code&gt;al_wait_cond&lt;/code&gt; it's waiting until a signal, a broadcast signal it's sent, and as you can see:</span>
<span class="number"> 420</span><span class="s"></span>
<span class="number"> 421</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt; al_broadcast_cond(data-&gt;cond) &lt;/source&gt;</span>
<span class="number"> 422</span><span class="s"></span>
<span class="number"> 423</span><span class="s">Our thread function (&lt;code&gt;Func_Thread()&lt;/code&gt;) 6th line does exactly that.</span>
<span class="number"> 424</span><span class="s"></span>
<span class="number"> 425</span><span class="s">So if for some reason our parent thread arrives to:</span>
<span class="number"> 426</span><span class="s"></span>
<span class="number"> 427</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt;while (!data.ready){&lt;/source&gt;</span>
<span class="number"> 428</span><span class="s"></span>
<span class="number"> 429</span><span class="s">and ready isn't true, that means we need to wait, so we enter to the loop, and immediately &lt;code&gt;al_wait_cond(data.cond, data.mutex)&lt;/code&gt; is called.</span>
<span class="number"> 430</span><span class="s"></span>
<span class="number"> 431</span><span class="s">On the other hand if when the parent thread arrives to:</span>
<span class="number"> 432</span><span class="s"></span>
<span class="number"> 433</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt;while (!data.ready){&lt;/source&gt;</span>
<span class="number"> 434</span><span class="s"></span>
<span class="number"> 435</span><span class="s">and ready is true, that means that we can move on, so we're not going to wait for any condition.</span>
<span class="number"> 436</span><span class="s"></span>
<span class="number"> 437</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt;al_broadcast_cond(data-&gt;cond); &lt;/source&gt;</span>
<span class="number"> 438</span><span class="s"></span>
<span class="number"> 439</span><span class="s">So for that reason, after assign the threads modi_X to false, we change the ready flag to true, to tell to the parent thread that he doesn't need to wait, because the first thread it's ready, but in case he is waiting, we also broadcast our condition so he can move on with this line.</span>
<span class="number"> 440</span><span class="s"></span>
<span class="number"> 441</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt;  al_unlock_mutex(data-&gt;mutex); &lt;/source&gt;</span>
<span class="number"> 442</span><span class="s"></span>
<span class="number"> 443</span><span class="s">Finally we unlock our mutex to tell Allegro that we're not going to be using the data object anymore so other threads can start using it.</span>
<span class="number"> 444</span><span class="s"></span>
<span class="number"> 445</span><span class="s">Ok, we need to go back to our parent thread, and make a little review:</span>
<span class="number"> 446</span><span class="s"></span>
<span class="number"> 447</span><span class="s"></span>
<span class="number"> 448</span><span class="s"></span>
<span class="number"> 449</span><span class="s">&lt;source lang="</span>c<span class="s">" line start=0&gt;</span>
<span class="number"> 450</span><span class="s">   thread_1 = al_create_thread(Func_Thread, &amp;data);</span>
<span class="number"> 451</span><span class="s">   al_start_thread(thread_1);</span>
<span class="number"> 452</span><span class="s"> </span>
<span class="number"> 453</span><span class="s">   al_lock_mutex(data.mutex);</span>
<span class="number"> 454</span><span class="s">   if (!data.ready)</span>
<span class="number"> 455</span><span class="s"> </span>
<span class="number"> 456</span><span class="s">      al_wait_cond(data.cond, data.mutex);</span>
<span class="number"> 457</span><span class="s"> </span>
<span class="number"> 458</span><span class="s">   al_unlock_mutex(data.mutex);</span>
<span class="number"> 459</span><span class="s"> </span>
<span class="number"> 460</span><span class="s">   al_lock_mutex(data.mutex);</span>
<span class="number"> 461</span><span class="s">   data.modi_X = true;</span>
<span class="number"> 462</span><span class="s">   data.ready  = false;</span>
<span class="number"> 463</span><span class="s">   al_unlock_mutex(data.mutex);</span>
<span class="number"> 464</span><span class="s"> </span>
<span class="number"> 465</span><span class="s">   thread_2 = al_create_thread(Func_Thread, &amp;data);</span>
<span class="number"> 466</span><span class="s">   al_start_thread(thread_2);</span>
<span class="number"> 467</span><span class="s"> </span>
<span class="number"> 468</span><span class="s">   al_lock_mutex(data.mutex);</span>
<span class="number"> 469</span><span class="s">   if (!data.ready)</span>
<span class="number"> 470</span><span class="s"> </span>
<span class="number"> 471</span><span class="s">      al_wait_cond(data.cond, data.mutex);</span>
<span class="number"> 472</span><span class="s"> </span>
<span class="number"> 473</span><span class="s">   al_unlock_mutex(data.mutex);</span>
<span class="number"> 474</span><span class="s"></span>
<span class="number"> 475</span><span class="s">&lt;/source&gt;</span>
<span class="number"> 476</span><span class="s"></span>
<span class="number"> 477</span><span class="s">=== Quick Review ===</span>
<span class="number"> 478</span><span class="s"></span>
<span class="number"> 479</span><span class="s">* In line 1 we create the thread.</span>
<span class="number"> 480</span><span class="s">* In line 2 we start the thread.</span>
<span class="number"> 481</span><span class="s">* in line 4 we lock our mutex because we're going to check if &lt;code&gt;ready&lt;/code&gt; it's true</span>
<span class="number"> 482</span><span class="s">* In case it's true that means our second tread for some reason haven't initialized its &lt;code&gt;mosi_X&lt;/code&gt;  bool variable, so we need to wait.</span>
<span class="number"> 483</span><span class="s">* In line 6 we start waiting.</span>
<span class="number"> 484</span><span class="s">* Ok our second thread has broadcast the conditional that means he is ready.</span>
<span class="number"> 485</span><span class="s">* In line 8 we unlock the mutex because we're not going to use it anymore.</span>
<span class="number"> 486</span><span class="s">* In line 10 we lock the mutex again, we need to change our variables because we're about to create another thread, and if we don't change the flags the second thread would be a complete mess.</span>
<span class="number"> 487</span><span class="s">* In line 11 we change our &lt;code&gt;modi_X&lt;/code&gt; variable to true, that way our second thread it's going to modified the X value of our bitmap.</span>
<span class="number"> 488</span><span class="s">* In line 12 we change back our ready variable to false again, because now we need to do the same with the second thread, we need to know when it's ready.</span>
<span class="number"> 489</span><span class="s">* In line 13 we unlock everything again.</span>
<span class="number"> 490</span><span class="s"></span>
<span class="number"> 491</span><span class="s">And the next lines does everything again, but for the second thread.</span>
<span class="number"> 492</span><span class="s">=== Two Threads Running===</span>
<span class="number"> 493</span><span class="s">At this point we have two threads running!</span>
<span class="number"> 494</span><span class="s"></span>
<span class="number"> 495</span><span class="s">Now what?</span>
<span class="number"> 496</span><span class="s"></span>
<span class="number"> 497</span><span class="s">Well those threas are changing the posi_X and posi_Y variables, so if you don't hurry up and draw the bitmap you're not going to see anything.</span>
<span class="number"> 498</span><span class="s"></span>
<span class="number"> 499</span><span class="s">But before drawing anything let's see how these threads are changing these variables:</span>
<span class="number"> 500</span><span class="s"></span>
<span class="number"> 501</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt;</span>
<span class="number"> 502</span><span class="s"></span>
<span class="number"> 503</span><span class="s">   while(!al_get_thread_should_stop(thr)){</span>
<span class="number"> 504</span><span class="s"> </span>
<span class="number"> 505</span><span class="s">      al_lock_mutex(data-&gt;mutex);</span>
<span class="number"> 506</span><span class="s">      if(modi_X)</span>
<span class="number"> 507</span><span class="s">         data-&gt;posiX += num;</span>
<span class="number"> 508</span><span class="s">      else</span>
<span class="number"> 509</span><span class="s">         data-&gt;posiY += num;</span>
<span class="number"> 510</span><span class="s">      al_unlock_mutex(data-&gt;mutex);</span>
<span class="number"> 511</span><span class="s"> </span>
<span class="number"> 512</span><span class="s">      al_rest(0.01);</span>
<span class="number"> 513</span><span class="s"> </span>
<span class="number"> 514</span><span class="s">   }</span>
<span class="number"> 515</span><span class="s"> </span>
<span class="number"> 516</span><span class="s"> </span>
<span class="number"> 517</span><span class="s">   return NULL;</span>
<span class="number"> 518</span><span class="s"></span>
<span class="number"> 519</span><span class="s"> &lt;/source&gt;</span>
<span class="number"> 520</span><span class="s"></span>
<span class="number"> 521</span><span class="s">We're back to our &lt;code&gt;Func_Thread()&lt;/code&gt; function.</span>
<span class="number"> 522</span><span class="s"></span>
<span class="number"> 523</span><span class="s">After initializing some values and telling to our parent thread that we're ready, the thread enter in a loop. A very simple loop that you should understand very well. To keep it simple we're not going to create another timer but just use &lt;code&gt;al_rest()&lt;/code&gt; which allow us to rest the thread some seconds, otherwise this loop would run so fast that we wouldn't be able to see our bitmap on the screen.</span>
<span class="number"> 524</span><span class="s"></span>
<span class="number"> 525</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt;while(!al_get_thread_should_stop(thr)) &lt;/source&gt;</span>
<span class="number"> 526</span><span class="s"></span>
<span class="number"> 527</span><span class="s">The same way this thread talked with the parent thread to tell it was ready, this function &lt;code&gt;&lt;/code&gt; allows the parent thread to talk with this thread, but this time we use it to tell our thread that must stop.</span>
<span class="number"> 528</span><span class="s"></span>
<span class="number"> 529</span><span class="s">As you can see each time we modified the data object in all threads we need to lock it and unlock it using  &lt;code&gt;al_luck_mutex()&lt;/code&gt; and &lt;code&gt;al_luck_mutex()&lt;/code&gt; respectively.</span>
<span class="number"> 530</span><span class="s"></span>
<span class="number"> 531</span><span class="s">If &lt;code&gt;al_get_thread_should_stop(thr)&lt;/code&gt; returns true, the thread will stop. &lt;code&gt;thr&lt;/code&gt; it's the other value that &lt;code&gt;Func_Thread&lt;/code&gt; receives. It's nothing more than a pointer to the current thread.</span>
<span class="number"> 532</span><span class="s"></span>
<span class="number"> 533</span><span class="s">So we're done with the thread function. Now let's advance in our parent thread.</span>
<span class="number"> 534</span><span class="s"></span>
<span class="number"> 535</span><span class="s"></span>
<span class="number"> 536</span><span class="s"></span>
<span class="number"> 537</span><span class="s"></span>
<span class="number"> 538</span><span class="s">&lt;source lang="</span>c<span class="s">" line start="</span><span class="n">0</span><span class="s">"&gt;    while(1)</span>
<span class="number"> 539</span><span class="s">   {</span>
<span class="number"> 540</span><span class="s">      ALLEGRO_EVENT ev;</span>
<span class="number"> 541</span><span class="s">      al_wait_for_event(event_queue, &amp;ev);</span>
<span class="number"> 542</span><span class="s"> </span>
<span class="number"> 543</span><span class="s">      if(ev.type == ALLEGRO_EVENT_TIMER) {</span>
<span class="number"> 544</span><span class="s">         redraw = true;</span>
<span class="number"> 545</span><span class="s">      }</span>
<span class="number"> 546</span><span class="s">      else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {</span>
<span class="number"> 547</span><span class="s">         break;</span>
<span class="number"> 548</span><span class="s">      }</span>
<span class="number"> 549</span><span class="s">      else if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) {</span>
<span class="number"> 550</span><span class="s">         break;</span>
<span class="number"> 551</span><span class="s">      }</span>
<span class="number"> 552</span><span class="s">      if(redraw &amp;&amp; al_is_event_queue_empty(event_queue)) {</span>
<span class="number"> 553</span><span class="s">         redraw = false;</span>
<span class="number"> 554</span><span class="s">         </span>
<span class="number"> 555</span><span class="s">         al_lock_mutex(data.mutex);</span>
<span class="number"> 556</span><span class="s">         float X = data.posiX;</span>
<span class="number"> 557</span><span class="s">         float Y = data.posiY;</span>
<span class="number"> 558</span><span class="s">         al_unlock_mutex(data.mutex);</span>
<span class="number"> 559</span><span class="s">         </span>
<span class="number"> 560</span><span class="s">         al_draw_bitmap(bouncer, X, Y, 0);</span>
<span class="number"> 561</span><span class="s"> </span>
<span class="number"> 562</span><span class="s">         al_flip_display();</span>
<span class="number"> 563</span><span class="s">      }</span>
<span class="number"> 564</span><span class="s">   }</span>
<span class="number"> 565</span><span class="s">   al_destroy_thread(thread_1);</span>
<span class="number"> 566</span><span class="s">   al_destroy_thread(thread_2);</span>
<span class="number"> 567</span><span class="s"> </span>
<span class="number"> 568</span><span class="s">   al_destroy_bitmap(bouncer);</span>
<span class="number"> 569</span><span class="s">   al_destroy_timer(timer);</span>
<span class="number"> 570</span><span class="s">   al_destroy_display(display);</span>
<span class="number"> 571</span><span class="s">   al_destroy_event_queue(event_queue);</span>
<span class="number"> 572</span><span class="s"></span>
<span class="number"> 573</span><span class="s">&lt;/source&gt;</span>
<span class="number"> 574</span><span class="s"></span>
<span class="number"> 575</span><span class="s">This shouldn't be nothing new. As you can see in line 17, 18, 19 and 20, we are creating two variables and initializing them with the corresponding value, this is to clarify, that you should keep locked the mutex of determined object the less posible.</span>
<span class="number"> 576</span><span class="s"></span>
<span class="number"> 577</span><span class="s">&lt;source lang="</span>c<span class="s">"&gt; al_destroy_thread(thread_1);</span>
<span class="number"> 578</span><span class="s">   al_destroy_thread(thread_2) &lt;/source&gt;</span>
<span class="number"> 579</span><span class="s"></span>
<span class="number"> 580</span><span class="s">And finally we're destroying the threads when we exit the program. This implicitly performs &lt;code&gt;al_join_thread&lt;/code&gt; which at the same time implicitly calls &lt;code&gt;al_set_thread_should_stop&lt;/code&gt; first, so the while that is running in our threads are going to stop.</span>
<span class="number"> 581</span><span class="s"></span>
<span class="number"> 582</span><span class="s">The End.</span>
</div></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (weapon_S)</author>
		<pubDate>Mon, 30 May 2011 22:55:50 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Didn&#39;t I read somewhere or other today about the evils that beset video bitmaps and threads?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Neil Walker)</author>
		<pubDate>Tue, 31 May 2011 04:48:02 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>It should be in C, since Allegro is a C library.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (CosmicR)</author>
		<pubDate>Tue, 31 May 2011 08:38:51 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/607455/919553#target">Neil Walker</a> said:</div><div class="quote"><p>Didn&#39;t I read somewhere or other today about the evils that beset video bitmaps and threads?</p></div></div><p>You shouldn&#39;t touch a GL/DX context from more than one thread at a time. Bad things can, and WILL happen.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Tue, 31 May 2011 08:49:23 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Somebody willing to post my blerp of text to the wiki and maybe give it a critical look?<br />(Shouldn&#39;t this topic b moved out of the depot?)
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (weapon_S)</author>
		<pubDate>Wed, 01 Jun 2011 01:35:36 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;ll update the tut when I get the time. <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /> all this thing about threads it&#39;s incredible. </p><p><b>Edit:</b> <br />I have uploaded the weapon_S tut.</p><p>Why are you using those // and _ _ like if you were writting on allegro.cc? <img src="http://www.allegro.cc/forums/smileys/grin.gif" alt=";D" /> On the Wiki that doesn&#39;t work.</p><p>ok we have some questions:</p><p>1 - A <i>thread</i> is like a program running <u>separately</u>. Separately means you have no idea how far it has run, and neither <b>do they know about each others globals</b>?.</p><p>2 -thread_1 is allocated. Don&#39;t forget to deallocate it afterwards. Shouldn&#39;t you check <s>it&#39;s</s> its value? </p><p>Neither <span class="source-code"><a href="http://www.allegro.cc/manual/al_start_thread"><span class="a">al_start_thread</span></a></span> and <span class="source-code"><a href="http://www.allegro.cc/manual/al_create_thread"><span class="a">al_create_thread</span></a></span> returns a value so how could I check it?</p><p>3 - The thread will be running the function Func_thread and getting the pointer *data as its argument when it starts. <img src="http://www.allegro.cc/forums/smileys/huh.gif" alt="???" />(Or only after it started it head hurts) </p><p>To be honest I don&#39;t understand the question.</p><p>4 - al_wait_cond takes a <i>locked mutex</i> as an argument???</p><p>On entering this function, mutex must be locked by the calling thread. The function will atomically release mutex and block on cond. That is what the manual says, I don&#39;t know if you was referring to another thing.</p><p>5 -  In what order are you discussing the file? In what order was I discussing the file? I already discussed this???</p><p>When I said &quot;Everything until here should be already clear&quot; I was referring to the rest of the code the initialization of allegro, mouse etc, I guess I can remove it, though.</p><p>Here:
</p><div class="source-code snippet"><div class="inner"><pre><a href="http://www.allegro.cc/manual/al_lock_mutex"><span class="a">al_lock_mutex</span></a><span class="k2">(</span>data.mutex<span class="k2">)</span><span class="k2">;</span>
   <span class="k1">while</span> <span class="k2">(</span><span class="k3">!</span>data.ready<span class="k2">)</span><span class="k2">{</span>
 
      <a href="http://www.allegro.cc/manual/al_wait_cond"><span class="a">al_wait_cond</span></a><span class="k2">(</span>data.cond, data.mutex<span class="k2">)</span><span class="k2">;</span>
 
   <span class="k2">}</span>
   <a href="http://www.allegro.cc/manual/al_unlock_mutex"><span class="a">al_unlock_mutex</span></a><span class="k2">(</span>data.mutex<span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>

Instead of a while can&#39;t we use an <span class="source-code"><span class="k1">if</span></span>?</p><p>PS: the </p><pre>&lt;code&gt;&lt;/code&gt;</pre><p> tags shows the letters too small, can&#39;t be increased?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (AMCerasoli)</author>
		<pubDate>Sun, 05 Jun 2011 03:41:43 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/607455/919666#target">AMCerasoli</a> said:</div><div class="quote"><p>
Neither al_start_thread and al_create_thread returns a value so how could I check it?
</p></div></div><p>
Read <span class="source-code"><a href="http://www.allegro.cc/manual/al_create_thread"><span class="a">al_create_thread</span></a></span> again - it returns an ALLEGRO_THREAD*, 0 on failure.</p><div class="quote_container"><div class="title">AMCerasoli said:</div><div class="quote"><p>
Instead of a while can&#39;t we use an if?
</p></div></div><p>
No, because <span class="source-code"><a href="http://www.allegro.cc/manual/al_wait_cond"><span class="a">al_wait_cond</span></a></span> may return for reasons other than the condition becoming true. That&#39;s why you need to keep checking the variable.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Sun, 05 Jun 2011 06:51:02 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I thought // , ** and __ were called &quot;wiki-markup&quot; <img src="http://www.allegro.cc/forums/smileys/grin.gif" alt=";D" />
</p><ol><li><p>Woops, my bad. I was confused for a second. It is a very bad idea to use globals to communicate between threads, it is however not impossible.</p></li><li><p>What he ^ said.</p></li><li><p>When it starts. (?) I can&#39;t remember asking that. Should be obvious. Or you could say that <i>when it starts</i> and <i>after it starts</i> are indistinguishable, because in neither cases any code has run.</p></li><li><p>Yes, I was referring to the manual. So, maybe expand that to &quot;a <i>mutex</i> which is <i>locked</i>&quot;. I think it is very vital to understand such details.</p></li><li><p>Haven&#39;t looked yet at the new version. Removal sounds good.</p></li></ol><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (weapon_S)</author>
		<pubDate>Sun, 05 Jun 2011 10:49:48 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/607455/920154#target">weapon_S</a> said:</div><div class="quote"><p>Woops, my bad. I was confused for a second. It is a very bad idea to use globals to communicate between threads, it is however not impossible.</p></div></div><p>You can pass in an argument to <span class="source-code"><a href="http://www.allegro.cc/manual/al_create_thread"><span class="a">al_create_thread</span></a></span> just like you can with pthreads.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Sun, 05 Jun 2011 21:12:57 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I read somewhere that threads shouldn&#39;t be called &quot;parents&quot; or &quot;child&quot; I can&#39;t remember where, though. In the tutorial we&#39;re using those terms, should I keep it?.</p><p><b>Edit:</b></p><p>I have another question... why is useful a cond? if for example I have 
</p><div class="source-code snippet"><div class="inner"><pre><a href="http://www.allegro.cc/manual/al_lock_mutex"><span class="a">al_lock_mutex</span></a><span class="k2">(</span>data.mutex<span class="k2">)</span><span class="k2">;</span>
<span class="k1">while</span><span class="k2">(</span><span class="k3">!</span>data.ready<span class="k2">)</span><span class="k2">{</span><span class="k2">}</span>
<a href="http://www.allegro.cc/manual/al_unlock_mutex"><span class="a">al_unlock_mutex</span></a><span class="k2">(</span>data.mutex<span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p> and that&#39;s it? that would wait until ready is... ready.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (AMCerasoli)</author>
		<pubDate>Sat, 11 Jun 2011 18:26:46 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>That would wait forever. (Variable is locked.)
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (weapon_S)</author>
		<pubDate>Sat, 11 Jun 2011 19:03:17 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/607455/921018#target">AMCerasoli</a> said:</div><div class="quote"><p> I have another question... why is useful a cond? if for example I have
</p></div></div><p>It would never release the mutex. It would sit in there forever blocking the other threads that want the mutex in order to change the variable.</p><p>When you wait on a condition variable, it essentially goes like:</p><ol><li><p>lock mutex
</p></li><li><p>check variable, if ready go to step 6
</p></li><li><p>unlock mutex
</p></li><li><p>wait on condition
</p></li><li><p>repeat
</p></li><li><p>unlock mutex
</p></li></ol></div>]]>
		</description>
		<author>no-reply@allegro.cc (Matthew Leverton)</author>
		<pubDate>Sat, 11 Jun 2011 19:47:18 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I had to think for a sec before I saw that was correct. Slightly more elaborate steps written out. (You call this a &#39;diagram&#39;? <img src="http://www.allegro.cc/forums/smileys/huh.gif" alt="???" /> )
</p><ol><li><p>lock mutex</p></li><li><p>check variable, if ready go to step 6</p></li><li><p>al_wait_cond:</p><ul><li><p>unlock mutex</p></li><li><p>wait on condition</p></li><li><p>lock mutex</p></li></ul></li><li><p>goto 2</p></li><li><p>unlock mutex</p></li></ol><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (weapon_S)</author>
		<pubDate>Sat, 11 Jun 2011 21:00:44 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Ohhhh it&#39;s true... <img src="http://www.allegro.cc/forums/smileys/grin.gif" alt=";D" /> , know I think I understand it very well... <span class="source-code"><a href="http://www.allegro.cc/manual/al_wait_cond"><span class="a">al_wait_cond</span></a><span class="k2">(</span><span class="k2">)</span></span> unlock the mutex and block on the cond (the same that the manua says, I couldn&#39;t understand it the first time I read it <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /> ). I&#39;m thinking in many threads using the same data, it&#39;s a good idea having just one cond and many flag to check if all the threads have done their job? something like:</p><div class="source-code snippet"><div class="inner"><pre><a href="http://www.allegro.cc/manual/al_lock_mutex"><span class="a">al_lock_mutex</span></a><span class="k2">(</span>data.mutex<span class="k2">)</span><span class="k2">;</span>
<span class="k1">while</span><span class="k2">(</span><span class="k3">!</span>data.flag1 <span class="k3">|</span><span class="k3">|</span> <span class="k3">!</span>data.flag2 <span class="k3">|</span><span class="k3">|</span> <span class="k3">!</span>data.flag3<span class="k2">)</span><span class="k2">{</span>

<a href="http://www.allegro.cc/manual/al_wait_cond"><span class="a">al_wait_cond</span></a><span class="k2">(</span>cond, mutex<span class="k2">)</span><span class="k2">;</span>

<span class="k2">}</span>
<a href="http://www.allegro.cc/manual/al_unlock_mutex"><span class="a">al_unlock_mutex</span></a><span class="k2">(</span>data.mutex<span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>

I don&#39;t need more conds right?</p><p><b>Edit:</b> I have another question... What is the point of having multiple threads if I can&#39;t use them to load bitmaps, fonts since they&#39;re loaded as memory bitmaps? I guess I have no problem by loading sound on another thread right?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (AMCerasoli)</author>
		<pubDate>Mon, 13 Jun 2011 03:59:45 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The a wait condition also doesn&#39;t spin in a loop using 100% cpu. Where as a simple loop would.</p><p>One condition var should be fine so long as the stuff you&#39;re waiting for properly sets all flags (or you&#39;ll never fully wake up).
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Mon, 13 Jun 2011 04:02:44 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I have another question: If the object that I sent to the thread has a function, when I call the function from the main thread do I need to lock the mutex too?</p><div class="source-code snippet"><div class="inner"><pre>
data.cout_this<span class="k2">(</span><span class="s">"Hello Thread"</span><span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>

Yes it&#39;s possible, if someone wants more info read this: <a href="http://www.thinkingparallel.com/2006/10/15/a-short-guide-to-mastering-thread-safety/">http://www.thinkingparallel.com/2006/10/15/a-short-guide-to-mastering-thread-safety/</a></p><p>BTW I didn&#39;t know that rand() wasn&#39;t thread-safe...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (AMCerasoli)</author>
		<pubDate>Thu, 16 Jun 2011 23:26:01 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You need to lock the mutex no matter what (unless you <b>know</b> you&#39;ve already locked it earlier, otherwise you&#39;ll deadlock) for critical sections.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (BAF)</author>
		<pubDate>Fri, 17 Jun 2011 04:24:35 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Yhea it&#39;s done... Someone has some ideas to create another simple one? I thought in one which multiple threads load a lot of images and make the comparison between using or not threads... But I don&#39;t want to load all those images to the wiki, I was thinking if there would be another idea like that, which shows the difference between multi-thread and just one thread very clear.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (AMCerasoli)</author>
		<pubDate>Thu, 23 Jun 2011 02:52:02 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/607455/921702#target">AMCerasoli</a> said:</div><div class="quote"><p>
BTW I didn&#39;t know that rand() wasn&#39;t thread-safe...
</p></div></div><p>
The C standard doesn&#39;t impose thread safety. So it&#39;s implementation specific. It&#39;s thread safe in MSVC if you compile with the multithreaded C runtime (all C functions are thread safe in that case), but IIRC it isn&#39;t in gcc.</p><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/607455/922376#target">AMCerasoli</a> said:</div><div class="quote"><p>
I thought in one which multiple threads load a lot of images and make the comparison between using or not threads...
</p></div></div><p>
The only benefit in loading data from another thread is so that the main thread doesn&#39;t block, so you can for example display a small animation in the load screen so the user sees his computer still works <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" />. The loading speed is going to be limited by the HDD speed (even if it&#39;s an SSD), not by the CPU.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Oscar Giner)</author>
		<pubDate>Thu, 23 Jun 2011 05:44:32 +0000</pubDate>
	</item>
</rss>
