1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
|
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
/* $Source: src/occ/thread/threadSch.c $ */
/* */
/* OpenPOWER OnChipController Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2011,2014 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
/* You may obtain a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
/* implied. See the License for the specific language governing */
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
#include <occ_common.h>
#include <threadSch.h>
#include "ssx.h"
#include "thread_service_codes.h"
#include "occ_service_codes.h"
#include <appletManager.h>
#include <trac.h>
#include <state.h>
#include "cmdh_snapshot.h"
// Numbers of threads to schedule
#define THREADS_TO_SCHEDULE (sizeof(G_scheduledThreads)/sizeof(SsxThread*))
#define THREAD_TIME_SLICE (SsxInterval) SSX_MILLISECONDS(10) // 10ms
// Thread Timer to reprioritize the threads
SsxTimer G_threadSchTimer;
// Index of highest priority thread in G_scheduledThreads
uint16_t G_threadSchedulerIndex = 0;
// Array that holds the threads that need scheduling
SsxThread* G_scheduledThreads[] =
{
&Main_thread,
&Cmd_Hndl_thread,
&App_thread,
&TestAppletThread,
&Dcom_thread,
};
// Error log counter for the callback so that only 1 error log is created
uint8_t G_threadSwapErrlCounter = 0;
// Global for the parameter to the applet thread routine
OCC_APLT_TYPE G_apltPdtType = APLT_TYPE_PRODUCT;
OCC_APLT_TYPE G_apltTestType = APLT_TYPE_TEST;
//Thread Stacks
uint8_t main_thread_stack[THREAD_STACK_SIZE];
uint8_t Cmd_hndl_thread_stack[THREAD_STACK_SIZE];
uint8_t App_thread_stack[THREAD_STACK_SIZE];
uint8_t testAppletThreadStack[THREAD_STACK_SIZE];
uint8_t dcomThreadStack[THREAD_STACK_SIZE];
// Our idle thread. See main_thread_routine
SsxThread Main_thread;
// Command handler thread
SsxThread Cmd_Hndl_thread;
// Application manager thread
SsxThread App_thread;
// Test applet thread
SsxThread TestAppletThread;
// Dcom thread
SsxThread Dcom_thread;
// Function Specification
//
// Name: createAndResumeThreadHelper
//
// Description: create and resume thread helper
//
// End Function Specification
int createAndResumeThreadHelper(SsxThread *io_thread,
SsxThreadRoutine i_thread_routine,
void *io_arg,
SsxAddress i_stack,
size_t i_stack_size,
THREAD_PRIORITY i_priority)
{
// Locals
int l_rc = SSX_OK;
// Thread creation
l_rc = ssx_thread_create(io_thread,
i_thread_routine,
io_arg,
i_stack,
i_stack_size,
(SsxThreadPriority)i_priority);
//check for errors creating a thread
if(l_rc != SSX_OK)
{
TRAC_ERR("Failure creating thread. rc: 0x%x", -l_rc);
}
else
{
//resume thread once created
l_rc = ssx_thread_resume(io_thread);
}
return l_rc;
}
// Function Specification
//
// Name: initThreadScheduler
//
// Description: Init the threads in the scheduler and start the
// timer.
//
// End Function Specification
void initThreadScheduler(void)
{
// Locals
int l_appThreadRc = SSX_OK;
int l_cmdThreadRc = SSX_OK;
int l_timerRc = SSX_OK;
int l_testAppletThreadRc = SSX_OK;
int l_dcomThreadRc = SSX_OK;
int l_snapshotTimerRc = SSX_OK;
// Creating threads that need to be scheduled
// Thread priority range should match scheduled
// threads in G_scheduledThreads ie highest priority thread should be
// index 0 of G_scheduledThreads
l_cmdThreadRc = createAndResumeThreadHelper(&Cmd_Hndl_thread,
Cmd_Hndl_thread_routine,
(void *)0,
(SsxAddress)Cmd_hndl_thread_stack,
THREAD_STACK_SIZE,
THREAD_PRIORITY_3);
l_appThreadRc = createAndResumeThreadHelper(&App_thread,
App_thread_routine,
(void *)&G_apltPdtType,
(SsxAddress)App_thread_stack,
THREAD_STACK_SIZE,
THREAD_PRIORITY_4);
l_testAppletThreadRc = createAndResumeThreadHelper(&TestAppletThread,
App_thread_routine,
(void *)&G_apltTestType,
(SsxAddress)testAppletThreadStack,
THREAD_STACK_SIZE,
THREAD_PRIORITY_5);
l_dcomThreadRc = createAndResumeThreadHelper(&Dcom_thread,
Dcom_thread_routine,
(void *)0,
(SsxAddress)dcomThreadStack,
THREAD_STACK_SIZE,
THREAD_PRIORITY_6);
// Create the thread scheduler timer
l_timerRc = ssx_timer_create(&G_threadSchTimer, threadSwapcallback, 0);
// Check for errors creating the timer
if(l_timerRc == SSX_OK)
{
TRAC_INFO("timer created and scheduled");
//schedule the timer so that it runs every THREAD_TIME_SLICE
l_timerRc = ssx_timer_schedule(&G_threadSchTimer, 1, THREAD_TIME_SLICE);
}
else
{
TRAC_INFO("Error creating timer: RC: %d", l_timerRc);
}
// Create snapshot timer
l_snapshotTimerRc = ssx_timer_create(&G_snapshotTimer, cmdh_snapshot_callback, 0);
// Check for errors creating the timer
if(l_snapshotTimerRc == SSX_OK)
{
// Schedule the timer so that it runs every 30 seconds.
l_snapshotTimerRc = ssx_timer_schedule(&G_snapshotTimer, 0, SSX_SECONDS(30));
if (l_snapshotTimerRc != SSX_OK)
{
TRAC_ERR("cmdh_snapshot_sync: reseting the snapshot timer failed.");
}
}
else
{
TRAC_INFO("Error creating timer: RC: %d", l_snapshotTimerRc);
}
// If there are any errors creating the threads or starting the
// timer create an error log to pass back.
if( l_appThreadRc
|| l_testAppletThreadRc
|| l_cmdThreadRc
|| l_dcomThreadRc
|| l_timerRc
|| l_snapshotTimerRc )
{
TRAC_ERR("Error creating thread: l_appThreadRc: %d, "
"l_testAppletThreadRc: %d, l_cmdThreadRc: %d, "
"l_dcomThreadRc: %d", l_appThreadRc,l_testAppletThreadRc,
l_timerRc,l_cmdThreadRc,l_dcomThreadRc);
TRAC_ERR("Error starting timers: timerRc: %d, snapshotTimerRc: %d.",
l_timerRc, l_snapshotTimerRc);
// Create error log and log it
// TODO use correct trace
tracDesc_t l_trace = NULL;
/* @
* @errortype
* @moduleid THRD_MID_INIT_THREAD_SCHDLR
* @reasoncode SSX_GENERIC_FAILURE
* @userdata1 Schedule timer return code
* @userdata2 Snapshot timer return code
* @userdata4 OCC_NO_EXTENDED_RC
* @devdesc SSX thread related failure
*/
errlHndl_t l_rc = createErrl(THRD_MID_INIT_THREAD_SCHDLR, // ModId
SSX_GENERIC_FAILURE, // Reasoncode
OCC_NO_EXTENDED_RC, // Extended reasoncode
ERRL_SEV_UNRECOVERABLE, // Severity
l_trace, // Trace Buf
DEFAULT_TRACE_SIZE, // Trace Size
l_timerRc, // Userdata1
l_snapshotTimerRc); // Userdata2
REQUEST_RESET(l_rc);
}
}
// Function Specification
//
// Name: threadSwapcallback
//
// Description: a periodic timer callback to swap prorities of scheduled threads
//
// End Function Specification
void threadSwapcallback(void * arg)
{
// Locals
int l_rc = SSX_OK;
// Current location of index in scheduled thread array
int l_threadAIndex = G_threadSchedulerIndex;
// If global index == last item swap priorities with 1st
int l_threadBIndex = (G_threadSchedulerIndex == (THREADS_TO_SCHEDULE-1)) ? 0 : ++G_threadSchedulerIndex;
// Swap priorities with global index +1
l_rc = ssx_thread_priority_swap(G_scheduledThreads[l_threadAIndex],G_scheduledThreads[l_threadBIndex]);
if(l_rc != SSX_OK)
{
// TODO trace error
// Create and commit error log
if(G_threadSwapErrlCounter == 0)
{
// TODO use correct trace
tracDesc_t l_trace = NULL;
/*
* @errortype
* @moduleid THRD_MID_THREAD_SWAP_CALLBACK
* @reasoncode SSX_GENERIC_FAILURE
* @userdata1 Return code of thread priority swap
* @userdata2 Current location of index in scheduled thread array
* @userdata4 OCC_NO_EXTENDED_RC
* @devdesc SSX thread related failure
*/
errlHndl_t l_err = createErrl(
THRD_MID_THREAD_SWAP_CALLBACK, // ModId
SSX_GENERIC_FAILURE, // Reasoncode
OCC_NO_EXTENDED_RC, // Extended reasoncode
ERRL_SEV_PREDICTIVE, // Severity
l_trace, // Trace Buf
DEFAULT_TRACE_SIZE, // Trace Size
l_rc, // Userdata1
l_threadAIndex // Userdata2
);
// Commit log
// NOTE: Log should be deleted by reader mechanism
commitErrl( &l_err );
// Increment errl counter
G_threadSwapErrlCounter++;
}// End thread swap counter if
}
else
{
// Reset counter since it started working again
G_threadSwapErrlCounter = 0;
// Set the global to the new location of the highest priority thread
G_threadSchedulerIndex = l_threadBIndex;
}
}
|