OOSMOS Thread Example
1. Introduction
2. Thread on Various Platforms

1. Introduction

This is a comprehensive example of OOSMOS's 'state threads'. In order to include all the different thread call types, we use the threadtest class which tests them all.
Because Thread calls must be made from within an oosmos_POLL event and because the tests are granular, we test a little bit in each state. See Figure 1 that shows the state machine — a test per state.
Figure 1. threadtest State Chart
This is the threadtest source code:
1
22
23
24
25
26
27
28
29
30
[GPLv2]
 
#ifndef _threadtest_h
#define _threadtest_h
 
typedef struct threadtestTag threadtest;
 
extern threadtest * threadtestNew(void);
 
#endif
threadtest.h
1
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
58
59
60
61
62
63
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
350
351
352
353
354
355
356
357
372
373
374
375
376
[GPLv2]
 
#include "oosmos.h"
#include "prt.h"
#include "threadtest.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
 
//
// Adjust this in order to preallocate all 'threadtest' objects.
// Use 1 for a memory constrained environment.
//
#ifndef MAX_THREADTEST
#define MAX_THREADTEST 10
#endif
 
//>>>EVENTS
[Code generated by OOSMOS]
} uEvents;
 
struct threadtestTag
{
//>>>DECL
[Code generated by OOSMOS]
//<<<DECL
unsigned m_WC_Timeout_Successes;
unsigned m_WE_Timeout_Successes;
 
unsigned m_ThreadExitCount;
};
 
static bool ConditionRandom(int Range)
{
return rand() % Range == 0;
}
 
static bool ConditionTrue(void)
{
return true;
}
 
static bool ConditionFalse(void)
{
return false;
}
 
static void DelayMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
{
oosmos_UNUSED(pThreadTest);
 
oosmos_ThreadBegin();
prtFormatted("ThreadDelayMS...\n");
oosmos_ThreadDelayMS(3000);
prtFormatted("ThreadDelayMS SUCCESS\n\n");
oosmos_ThreadEnd();
}
 
static void WaitCond_Thread(threadtest * pThreadTest, oosmos_sState * pState)
{
oosmos_ThreadBegin();
prtFormatted("ThreadWaitCond...\n");
oosmos_ThreadWaitCond(ConditionRandom(2));
prtFormatted("ThreadWaitCond SUCCESS\n\n");
oosmos_UNUSED(pThreadTest);
oosmos_ThreadEnd();
}
 
static void WaitCond_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
{
oosmos_ThreadBegin();
bool TimedOut = false;
pThreadTest->m_WC_Timeout_Successes = 0;
 
prtFormatted("ThreadWaitCond_TimeoutMS...\n");
 
oosmos_ThreadWaitCond_TimeoutMS(ConditionTrue(), 100, &TimedOut);
pThreadTest->m_WC_Timeout_Successes += (TimedOut == false);
 
oosmos_ThreadWaitCond_TimeoutMS(ConditionFalse(), 100, &TimedOut);
pThreadTest->m_WC_Timeout_Successes += (TimedOut == true);
prtFormatted("ThreadWaitCond_TimeoutMS %s\n\n", pThreadTest->m_WC_Timeout_Successes == 2 ? "SUCCESS" : "FAILURE");
oosmos_ThreadEnd();
}
 
static void WaitEvent_Thread(threadtest * pThreadTest, oosmos_sState * pState)
{
oosmos_ThreadBegin();
prtFormatted("ThreadWaitEvent...\n");
 
oosmos_PushEventCode(pThreadTest, evPrint);
oosmos_ThreadWaitEvent(evDone);
prtFormatted("ThreadWaitEvent SUCCESS\n\n");
oosmos_ThreadEnd();
}
 
static void WaitEvent_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
{
oosmos_ThreadBegin();
bool TimedOut = false;
pThreadTest->m_WE_Timeout_Successes = 0;
 
prtFormatted("ThreadWaitEvent_TimeoutMS...\n");
 
oosmos_PushEventCode(pThreadTest, evPrint);
oosmos_ThreadWaitEvent_TimeoutMS(evPrint, 100, &TimedOut);
pThreadTest->m_WE_Timeout_Successes += (TimedOut == false);
 
oosmos_ThreadWaitEvent_TimeoutMS(evPrint, 100, &TimedOut);
pThreadTest->m_WE_Timeout_Successes += (TimedOut == true);
prtFormatted("ThreadWaitEvent_TimeoutMS %s\n\n", pThreadTest->m_WE_Timeout_Successes == 2 ? "SUCCESS" : "FAILURE");
oosmos_ThreadEnd();
}
 
static void ThreadExit_Thread(threadtest * pThreadTest, oosmos_sState * pState)
{
oosmos_ThreadBegin();
pThreadTest->m_ThreadExitCount = 0;
oosmos_ThreadYield();
pThreadTest->m_ThreadExitCount++;
prtFormatted("ThreadExit SUCCESS\n");
oosmos_ThreadExit();
oosmos_ThreadEnd();
}
 
static void ThreadExitFinally_Thread(threadtest * pThreadTest, oosmos_sState * pState)
{
oosmos_ThreadBegin();
pThreadTest->m_ThreadExitCount = 0;
oosmos_ThreadYield();
pThreadTest->m_ThreadExitCount++;
oosmos_ThreadExit();
oosmos_ThreadFinally();
pThreadTest->m_ThreadExitCount++;
 
if (pThreadTest->m_ThreadExitCount == 2) {
prtFormatted("ThreadExitFinally SUCCESS\n");
} else {
prtFormatted("ThreadExitFinally FAILURE\n");
}
oosmos_ThreadEnd();
}
 
[Code generated by OOSMOS]
}
//<<<CODE
 
extern threadtest * threadtestNew(void)
{
oosmos_Allocate(pThreadTest, threadtest, MAX_THREADTEST, NULL);
 
[Code generated by OOSMOS]
oosmos_Debug(pThreadTest, OOSMOS_EventNames);
//<<<INIT
 
return pThreadTest;
}
threadtest.c

2. Thread on Various Platforms

The Thread example will run on any platform but we have only packaged the Examples directory with PIC32 and Windows implementations.

2.1 Thread on PIC32

1
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
[GPLv2]
 
#include "oosmos.h"
#include "threadtest.h"
 
#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
#pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1
 
#define THREAD_TESTS 1
 
extern int main(void)
{
oosmos_ClockSpeedInMHz(80);
 
for (iunsignednt I = 1; I <= THREAD_TESTS; I++) {
(void) threadtestNew();
}
 
for (;;) {
oosmos_RunStateMachines();
}
}
main.c - Thread for PIC32

2.2 Thread on Windows

On Windows, we create all the threadtest objects and then drop into the conventional Windows oosmos_RunStateMachines loop.
Change THREADTESTS to whatever you like but it's easier to step through with a source level debugger when it is set to 1.
1
22
23
25
26
27
28
29
30
31
32
33
34
35
36
37
38
[GPLv2]
 
#includes...
 
#define THREAD_TESTS 1
 
extern int main(void)
{
for (unsigned I = 1; I <= THREAD_TESTS; I++) {
(void) threadtestNew();
}
 
for (;;) {
oosmos_RunStateMachines();
oosmos_DelayMS(1);
}
}
main.c - Thread for Windows
Copyright © 2014-2021  OOSMOS, LLC