]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - doc/html/user-guide/sample-twothreads.html
RedBoot TX53 Release 2012-02-15
[karo-tx-redboot.git] / doc / html / user-guide / sample-twothreads.html
1 <!-- Copyright (C) 2003 Red Hat, Inc.                                -->
2 <!-- This material may be distributed only subject to the terms      -->
3 <!-- and conditions set forth in the Open Publication License, v1.0  -->
4 <!-- or later (the latest version is presently available at          -->
5 <!-- http://www.opencontent.org/openpub/).                           -->
6 <!-- Distribution of the work or derivative of the work in any       -->
7 <!-- standard (paper) book form is prohibited unless prior           -->
8 <!-- permission is obtained from the copyright holder.               -->
9 <HTML
10 ><HEAD
11 ><TITLE
12 >A Sample Program with Two Threads</TITLE
13 ><meta name="MSSmartTagsPreventParsing" content="TRUE">
14 <META
15 NAME="GENERATOR"
16 CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
17 "><LINK
18 REL="HOME"
19 TITLE="eCos User Guide"
20 HREF="ecos-user-guide.html"><LINK
21 REL="UP"
22 TITLE="Building and Running Sample Applications"
23 HREF="building-and-running-sample-appliations.html"><LINK
24 REL="PREVIOUS"
25 TITLE="Building and Running Sample Applications"
26 HREF="building-and-running-sample-appliations.html"><LINK
27 REL="NEXT"
28 TITLE="More Features &#8212; Clocks and Alarm
29 Handlers"
30 HREF="clocks-and-alarm-handlers.html"></HEAD
31 ><BODY
32 CLASS="SECT1"
33 BGCOLOR="#FFFFFF"
34 TEXT="#000000"
35 LINK="#0000FF"
36 VLINK="#840084"
37 ALINK="#0000FF"
38 ><DIV
39 CLASS="NAVHEADER"
40 ><TABLE
41 SUMMARY="Header navigation table"
42 WIDTH="100%"
43 BORDER="0"
44 CELLPADDING="0"
45 CELLSPACING="0"
46 ><TR
47 ><TH
48 COLSPAN="3"
49 ALIGN="center"
50 >eCos User Guide</TH
51 ></TR
52 ><TR
53 ><TD
54 WIDTH="10%"
55 ALIGN="left"
56 VALIGN="bottom"
57 ><A
58 HREF="building-and-running-sample-appliations.html"
59 ACCESSKEY="P"
60 >Prev</A
61 ></TD
62 ><TD
63 WIDTH="80%"
64 ALIGN="center"
65 VALIGN="bottom"
66 >Chapter 13. Building and Running Sample Applications</TD
67 ><TD
68 WIDTH="10%"
69 ALIGN="right"
70 VALIGN="bottom"
71 ><A
72 HREF="clocks-and-alarm-handlers.html"
73 ACCESSKEY="N"
74 >Next</A
75 ></TD
76 ></TR
77 ></TABLE
78 ><HR
79 ALIGN="LEFT"
80 WIDTH="100%"></DIV
81 ><DIV
82 CLASS="SECT1"
83 ><H1
84 CLASS="SECT1"
85 ><A
86 NAME="SAMPLE-TWOTHREADS">A Sample Program with Two Threads</H1
87 ><P
88 >Below is a program that uses some of <SPAN
89 CLASS="PRODUCTNAME"
90 >eCos</SPAN
91 >' system calls. It
92 creates two threads, each of which goes into an infinite loop in which
93 it sleeps for a while (using cyg_thread_delay()).  This code is found
94 in the file <TT
95 CLASS="FILENAME"
96 >twothreads.c</TT
97 >
98 in the examples directory.</P
99 ><DIV
100 CLASS="SECT2"
101 ><H2
102 CLASS="SECT2"
103 ><A
104 NAME="AEN871"><SPAN
105 CLASS="PRODUCTNAME"
106 >eCos</SPAN
107 > two-threaded program listing</H2
108 ><TABLE
109 BORDER="5"
110 BGCOLOR="#E0E0F0"
111 WIDTH="70%"
112 ><TR
113 ><TD
114 ><PRE
115 CLASS="PROGRAMLISTING"
116 >#include &lt;cyg/kernel/kapi.h&#62;
117 #include &lt;stdio.h&#62;
118 #include &lt;math.h&#62;
119 #include &lt;stdlib.h&#62;
120
121 /* now declare (and allocate space for) some kernel objects,
122   like the two threads we will use */
123 cyg_thread thread_s[2]; /* space for two thread objects */
124
125 char stack[2][4096];    /* space for two 4K stacks */
126
127 /* now the handles for the threads */
128 cyg_handle_t simple_threadA, simple_threadB;
129
130 /* and now variables for the procedure which is the thread */
131 cyg_thread_entry_t simple_program;
132
133 /* and now a mutex to protect calls to the C library */
134 cyg_mutex_t cliblock;
135
136 /* we install our own startup routine which sets up threads */
137 void cyg_user_start(void)
138 {
139  printf("Entering twothreads' cyg_user_start() function\n");
140
141  cyg_mutex_init(&amp;cliblock);
142
143  cyg_thread_create(4, simple_program, (cyg_addrword_t) 0,
144         "Thread A", (void *) stack[0], 4096,
145         &amp;simple_threadA, &amp;thread_s[0]);
146  cyg_thread_create(4, simple_program, (cyg_addrword_t) 1,
147         "Thread B", (void *) stack[1], 4096,
148         &amp;simple_threadB, &amp;thread_s[1]);
149
150  cyg_thread_resume(simple_threadA);
151  cyg_thread_resume(simple_threadB);
152 }
153
154 /* this is a simple program which runs in a thread */
155 void simple_program(cyg_addrword_t data)
156 {
157  int message = (int) data;
158  int delay;
159
160  printf("Beginning execution; thread data is %d\n", message);
161
162  cyg_thread_delay(200);
163
164  for (;;) {
165  delay = 200 + (rand() % 50);
166
167  /* note: printf() must be protected by a
168  call to cyg_mutex_lock() */
169  cyg_mutex_lock(&amp;cliblock); {
170  printf("Thread %d: and now a delay of %d clock ticks\n",
171         message, delay);
172  }
173  cyg_mutex_unlock(&amp;cliblock);
174  cyg_thread_delay(delay);
175  }
176 }</PRE
177 ></TD
178 ></TR
179 ></TABLE
180 ><P
181 >When you run the program (by typing <B
182 CLASS="COMMAND"
183 >continue</B
184 > at
185 the (<SPAN
186 CLASS="emphasis"
187 ><I
188 CLASS="EMPHASIS"
189 >gdb</I
190 ></SPAN
191 >) prompt) the output should look like
192 this:</P
193 ><TABLE
194 BORDER="5"
195 BGCOLOR="#E0E0F0"
196 WIDTH="70%"
197 ><TR
198 ><TD
199 ><PRE
200 CLASS="PROGRAMLISTING"
201 >Starting program: <TT
202 CLASS="REPLACEABLE"
203 ><I
204 >BASE_DIR</I
205 ></TT
206 >/examples/twothreads.exe
207 Entering twothreads' cyg_user_start()
208 function
209 Beginning execution; thread data is 0
210 Beginning execution; thread data is 1
211 Thread 0: and now a delay of 240 clock ticks
212 Thread 1: and now a delay of 225 clock ticks
213 Thread 1: and now a delay of 234 clock ticks
214 Thread 0: and now a delay of 231 clock ticks
215 Thread 1: and now a delay of 224 clock ticks
216 Thread 0: and now a delay of 249 clock ticks
217 Thread 1: and now a delay of 202 clock ticks
218 Thread 0: and now a delay of 235 clock ticks</PRE
219 ></TD
220 ></TR
221 ></TABLE
222 ><DIV
223 CLASS="NOTE"
224 ><BLOCKQUOTE
225 CLASS="NOTE"
226 ><P
227 ><B
228 >Note: </B
229 >When running in a simulator the 
230 delays might be quite long. On a hardware board (where the clock
231 speed is 100 ticks/second) the delays should average to
232 about 2.25 seconds. In simulation, the delay will depend on the
233 speed of the host processor and will almost always be much slower than
234 the actual board. You might want to reduce the delay parameter when running
235 in simulation.</P
236 ></BLOCKQUOTE
237 ></DIV
238 ><P
239 ><A
240 HREF="sample-twothreads.html#FIGURE-TWOTHREADS-WITH-SIMPLE-PRINTS"
241 >Figure 13-1</A
242 > shows how this
243 multitasking program executes.  Note that apart from the thread
244 creation system calls, this program also creates and uses a
245 <SPAN
246 CLASS="emphasis"
247 ><I
248 CLASS="EMPHASIS"
249 >mutex</I
250 ></SPAN
251 > for synchronization
252 between the <TT
253 CLASS="FUNCTION"
254 >printf()</TT
255 > calls in the two
256 threads. This is because the C library standard I/O (by default) is
257 configured not to be thread-safe, which means that if more than one
258 thread is using standard I/O they might corrupt each other. This is
259 fixed by a mutual exclusion (or <SPAN
260 CLASS="emphasis"
261 ><I
262 CLASS="EMPHASIS"
263 >mutex</I
264 ></SPAN
265 >) lockout
266 mechanism: the threads do not call <TT
267 CLASS="FUNCTION"
268 >printf()</TT
269 > until
270 <TT
271 CLASS="FUNCTION"
272 >cyg_mutex_lock()</TT
273 > has returned, which only happens
274 when the other thread calls
275 <TT
276 CLASS="FUNCTION"
277 >cyg_mutex_unlock()</TT
278 >.</P
279 ><P
280 >You could avoid using the mutex by configuring the C library to
281 be thread-safe (by selecting the component
282 <TT
283 CLASS="LITERAL"
284 >CYGSEM_LIBC_STDIO_THREAD_SAFE_STREAMS</TT
285 >).</P
286 ><DIV
287 CLASS="FIGURE"
288 ><A
289 NAME="FIGURE-TWOTHREADS-WITH-SIMPLE-PRINTS"><P
290 ><B
291 >Figure 13-1. Two
292 threads with simple print statements after random delays</B
293 ></P
294 ><P
295 ><IMG
296 SRC="pix/twothreads2.png"></P
297 ></DIV
298 ></DIV
299 ></DIV
300 ><DIV
301 CLASS="NAVFOOTER"
302 ><HR
303 ALIGN="LEFT"
304 WIDTH="100%"><TABLE
305 SUMMARY="Footer navigation table"
306 WIDTH="100%"
307 BORDER="0"
308 CELLPADDING="0"
309 CELLSPACING="0"
310 ><TR
311 ><TD
312 WIDTH="33%"
313 ALIGN="left"
314 VALIGN="top"
315 ><A
316 HREF="building-and-running-sample-appliations.html"
317 ACCESSKEY="P"
318 >Prev</A
319 ></TD
320 ><TD
321 WIDTH="34%"
322 ALIGN="center"
323 VALIGN="top"
324 ><A
325 HREF="ecos-user-guide.html"
326 ACCESSKEY="H"
327 >Home</A
328 ></TD
329 ><TD
330 WIDTH="33%"
331 ALIGN="right"
332 VALIGN="top"
333 ><A
334 HREF="clocks-and-alarm-handlers.html"
335 ACCESSKEY="N"
336 >Next</A
337 ></TD
338 ></TR
339 ><TR
340 ><TD
341 WIDTH="33%"
342 ALIGN="left"
343 VALIGN="top"
344 >Building and Running Sample Applications</TD
345 ><TD
346 WIDTH="34%"
347 ALIGN="center"
348 VALIGN="top"
349 ><A
350 HREF="building-and-running-sample-appliations.html"
351 ACCESSKEY="U"
352 >Up</A
353 ></TD
354 ><TD
355 WIDTH="33%"
356 ALIGN="right"
357 VALIGN="top"
358 >More Features &#8212; Clocks and Alarm
359 Handlers</TD
360 ></TR
361 ></TABLE
362 ></DIV
363 ></BODY
364 ></HTML
365 >