Mercurial > ecos
annotate packages/kernel/current/tests/stress_threads.c @ 8:ece80412419a ecos-sw-1999-05-21
Merge from eCos master repository on 1999-05-21-22:05:54-BST
| author | jlarmour |
|---|---|
| date | Fri, 21 May 1999 15:09:30 +0000 |
| parents | 1d7f19c9e4d1 |
| children | d3fbcdfa1b2f |
| rev | line source |
|---|---|
| 2 | 1 //========================================================================== |
| 2 // | |
| 3 // stress_threads.cxx | |
| 4 // | |
| 5 // Basic thread stress test | |
| 6 // | |
| 7 //========================================================================== | |
| 8 //####COPYRIGHTBEGIN#### | |
| 9 // | |
| 10 // ------------------------------------------- | |
| 11 // The contents of this file are subject to the Cygnus eCos Public License | |
| 12 // Version 1.0 (the "License"); you may not use this file except in | |
| 13 // compliance with the License. You may obtain a copy of the License at | |
| 14 // http://sourceware.cygnus.com/ecos | |
| 15 // | |
| 16 // Software distributed under the License is distributed on an "AS IS" | |
| 17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the | |
| 18 // License for the specific language governing rights and limitations under | |
| 19 // the License. | |
| 20 // | |
| 21 // The Original Code is eCos - Embedded Cygnus Operating System, released | |
| 22 // September 30, 1998. | |
| 23 // | |
| 24 // The Initial Developer of the Original Code is Cygnus. Portions created | |
| 25 // by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. | |
| 26 // ------------------------------------------- | |
| 27 // | |
| 28 //####COPYRIGHTEND#### | |
| 29 //========================================================================== | |
| 30 //#####DESCRIPTIONBEGIN#### | |
| 31 // | |
| 32 // Author(s): rosalia | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
33 // Contributors: rosalia, jskov |
| 2 | 34 // Date: 1999-04-13 |
| 35 // Description: Very simple thread stress test, with some memory | |
| 36 // allocation and alarm handling. | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
37 // |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
38 // Notes: |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
39 // If client_makes_request is big, it means that there are made many more |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
40 // client requests than can be serviced. Consequently, clients are wasting |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
41 // CPU time and should be sleeping more. |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
42 // |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
43 // The list of handler invocations show how many threads are running |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
44 // at the same time. The more powerful the CPU, the more the numbers |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
45 // should spread out. |
| 2 | 46 //####DESCRIPTIONEND#### |
| 47 | |
| 48 #include <pkgconf/system.h> | |
| 49 #include <cyg/infra/testcase.h> | |
| 50 | |
| 51 #include <cyg/hal/hal_arch.h> | |
| 52 | |
| 53 #if defined(CYGPKG_KERNEL) && defined(CYGPKG_IO) && defined(CYGPKG_LIBC) | |
| 54 | |
| 55 #include <pkgconf/kernel.h> | |
| 56 #include <pkgconf/libc.h> | |
| 57 | |
| 58 #if defined(CYGFUN_KERNEL_API_C) | |
| 59 | |
| 60 #include <cyg/kernel/kapi.h> | |
| 61 | |
| 62 #ifdef CYGPKG_LIBC_STDIO | |
| 63 | |
| 64 #include <stdio.h> | |
| 65 #include <stdlib.h> | |
| 66 | |
| 67 #if defined(CYGPKG_LIBM) | |
| 68 | |
| 69 #include <math.h> | |
| 70 #include <assert.h> | |
| 71 | |
| 72 #if defined(CYGFUN_KERNEL_THREADS_TIMER) | |
| 73 #if defined(CYGPKG_LIBC_MALLOC) | |
| 74 | |
| 75 /* if TIME_LIMIT is defined, it represents the number of seconds this | |
| 76 test should last; if it is undefined the test will go forever */ | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
77 #define DEATH_TIME_LIMIT 20 |
| 2 | 78 /* #undef DEATH_TIME_LIMIT */ |
| 79 | |
| 80 #define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL) | |
| 81 #define STACK_SIZE2 (8*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL) | |
| 82 | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
83 /* Allocate priorities in this order. This ensures that handlers |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
84 (which are the ones using the CPU) get enough CPU time to actually |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
85 complete their tasks. */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
86 #define N_MAIN 1 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
87 #define MAX_HANDLERS 19 |
| 2 | 88 #define N_LISTENERS 4 |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
89 #define N_CLIENTS 4 |
| 2 | 90 |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
91 #if (CYGNUM_KERNEL_SCHED_PRIORITIES >= (N_MAIN+MAX_HANDLERS+N_LISTENERS+N_CLIENTS)) |
| 2 | 92 |
| 93 /* if we use the bitmap scheduler we must make sure we don't use the | |
| 94 same priority more than once, so we must store those already in use */ | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
95 static volatile char priority_in_use[N_MAIN+MAX_HANDLERS+N_LISTENERS+N_CLIENTS]; |
| 2 | 96 |
| 97 /* now declare (and allocate space for) some kernel objects, like the | |
| 98 threads we will use */ | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
99 cyg_thread main_thread_s; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
100 cyg_thread handler_thread_s[MAX_HANDLERS]; |
| 2 | 101 cyg_thread listener_thread_s[N_LISTENERS]; |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
102 cyg_thread client_thread_s[N_CLIENTS]; |
| 2 | 103 |
| 104 /* space for stacks for all threads */ | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
105 char main_stack[STACK_SIZE]; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
106 char handler_stack[MAX_HANDLERS][STACK_SIZE2]; |
| 2 | 107 char listener_stack[N_LISTENERS][STACK_SIZE]; |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
108 char client_stack[N_CLIENTS][STACK_SIZE]; |
| 2 | 109 |
| 110 /* now the handles for the threads */ | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
111 cyg_handle_t mainH; |
| 2 | 112 cyg_handle_t handlerH[MAX_HANDLERS]; |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
113 cyg_handle_t listenerH[N_LISTENERS]; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
114 cyg_handle_t clientH[N_CLIENTS]; |
| 2 | 115 |
| 116 /* and now variables for the procedure which is the thread */ | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
117 cyg_thread_entry_t main_program, client_program, listener_program, |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
118 handler_program; |
| 2 | 119 |
| 120 /* a few mutexes used in the code */ | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
121 cyg_mutex_t client_request_lock, handler_slot_lock, statistics_print_lock, |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
122 free_handler_lock; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
123 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
124 /* global variables with which the handler IDs and thread priorities |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
125 to free are communicated from handlers to main_program. Access to |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
126 these are protected by free_handler_lock. An id of -1 means the |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
127 that the variables are empty. */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
128 volatile int free_handler_pri = 0; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
129 volatile int free_handler_id = -1; |
| 2 | 130 |
| 131 /* a global variable with which the client and server coordinate */ | |
| 132 int client_makes_request = 0; | |
| 133 | |
| 134 /* indicates that it's time to print out a report */ | |
| 135 int time_to_report = 0; | |
| 136 | |
| 137 /*** now application-specific variables ***/ | |
| 138 /* an array that stores whether the handler threads are in use */ | |
| 139 int handler_thread_in_use[MAX_HANDLERS]; | |
| 140 | |
| 141 /***** statistics-gathering variables *****/ | |
| 142 struct s_statistics { | |
| 143 /* store the number of times each handler has been invoked */ | |
| 144 unsigned long handler_invocation_histogram[MAX_HANDLERS]; | |
| 145 | |
| 146 /* store how many times malloc has been attempted and how many times | |
| 147 it has failed */ | |
| 148 unsigned long malloc_tries, malloc_failures; | |
| 149 | |
| 150 /* how many threads have been created */ | |
| 151 unsigned long thread_creations, thread_exits; | |
| 152 }; | |
| 153 | |
| 154 struct s_statistics statistics; | |
| 155 | |
| 156 /* some function prototypes; those with the sc_ prefix are | |
| 157 "statistics-collecting" versions of the cyg_ primitives */ | |
| 158 void sc_thread_create( | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
159 cyg_addrword_t sched_info, /* scheduling info (eg pri) */ |
| 2 | 160 cyg_thread_entry_t *entry, /* entry point function */ |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
161 cyg_addrword_t entry_data, /* entry data */ |
| 2 | 162 char *name, /* optional thread name */ |
| 163 void *stack_base, /* stack base, NULL = alloc */ | |
| 164 cyg_ucount32 stack_size, /* stack size, 0 = default */ | |
| 165 cyg_handle_t *handle, /* returned thread handle */ | |
| 166 cyg_thread *thread /* put thread here */ | |
| 167 ); | |
| 168 | |
| 169 int get_handler_slot(cyg_handle_t current_threadH); | |
| 170 void perform_stressful_tasks(void); | |
| 171 void permute_array(char a[], int size, int seed); | |
| 172 void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp, | |
| 173 cyg_alarm *death_alarm_p, int *killed_p); | |
| 174 void print_statistics(void); | |
| 175 | |
| 176 /* we need to declare the alarm handling function (which is defined | |
| 177 below), so that we can pass it to cyg_alarm_initialize() */ | |
| 178 cyg_alarm_t report_alarm_func, death_alarm_func; | |
| 179 | |
| 180 /* handle and alarm for the report alarm */ | |
| 181 cyg_handle_t report_alarmH, counterH, system_clockH; | |
| 182 cyg_alarm report_alarm; | |
| 183 | |
| 184 /* we install our own startup routine which sets up threads */ | |
| 185 void cyg_user_start(void) | |
| 186 { | |
| 187 int i; | |
| 188 | |
| 189 CYG_TEST_INIT(); | |
| 190 CYG_TEST_INFO("# Entering stress's cyg_user_start() function"); | |
| 191 | |
| 192 cyg_mutex_init(&client_request_lock); | |
| 193 cyg_mutex_init(&statistics_print_lock); | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
194 cyg_mutex_init(&free_handler_lock); |
| 2 | 195 |
| 196 /* initialize statistics */ | |
| 197 memset(&statistics, 0, sizeof(statistics)); | |
| 198 | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
199 /* clear priority table */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
200 for (i = 0; i < sizeof(priority_in_use); i++) |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
201 priority_in_use[i] = 0; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
202 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
203 /* initialize main thread */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
204 { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
205 char thread_name[] = "main"; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
206 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
207 sc_thread_create(0, main_program, (cyg_addrword_t) 0, |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
208 thread_name, (void *) main_stack, STACK_SIZE, |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
209 &mainH, &main_thread_s); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
210 priority_in_use[0]++; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
211 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
212 |
| 2 | 213 /* initialize all handler threads to not be in use */ |
| 214 for (i = 0; i < MAX_HANDLERS; ++i) { | |
| 215 handler_thread_in_use[i] = 0; | |
| 216 } | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
217 for (i = 0; i < N_LISTENERS; ++i) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
218 int prio; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
219 char thread_name[20]; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
220 sprintf(thread_name, "listener-%02d", i); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
221 prio = N_MAIN + MAX_HANDLERS + i; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
222 sc_thread_create(prio, listener_program, (cyg_addrword_t) i, |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
223 thread_name, (void *) listener_stack[i], STACK_SIZE, |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
224 &listenerH[i], &listener_thread_s[i]); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
225 CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!"); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
226 priority_in_use[prio]++; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
227 } |
| 2 | 228 for (i = 0; i < N_CLIENTS; ++i) { |
| 229 int prio; | |
| 230 char thread_name[20]; | |
| 231 sprintf(thread_name, "client-%02d", i); | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
232 prio = N_MAIN + MAX_HANDLERS + N_LISTENERS + i; |
| 2 | 233 sc_thread_create(prio, client_program, (cyg_addrword_t) i, |
| 234 thread_name, (void *) client_stack[i], STACK_SIZE, | |
| 235 &(clientH[i]), &client_thread_s[i]); | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
236 CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!"); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
237 priority_in_use[prio]++; |
| 2 | 238 } |
| 239 | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
240 cyg_thread_resume(mainH); |
| 2 | 241 for (i = 0; i < N_CLIENTS; ++i) { |
| 242 cyg_thread_resume(clientH[i]); | |
| 243 } | |
| 244 for (i = 0; i < N_LISTENERS; ++i) { | |
| 245 cyg_thread_resume(listenerH[i]); | |
| 246 } | |
| 247 | |
| 248 /* set up the alarm which gives periodic wakeups to say "time to | |
| 249 print a report */ | |
| 250 system_clockH = cyg_real_time_clock(); | |
| 251 cyg_clock_to_counter(system_clockH, &counterH); | |
| 252 | |
| 253 cyg_alarm_create(counterH, report_alarm_func, | |
| 254 (cyg_addrword_t) 4000, | |
| 255 &report_alarmH, &report_alarm); | |
| 256 if (cyg_test_is_simulator) { | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
257 cyg_alarm_initialize(report_alarmH, cyg_current_time()+200, 200); |
| 2 | 258 } else { |
| 259 cyg_alarm_initialize(report_alarmH, cyg_current_time()+300, 4000); | |
| 260 } | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
261 } |
| 2 | 262 |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
263 /* main_program() -- frees resources and prints status. */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
264 void main_program(cyg_addrword_t data) |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
265 { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
266 #ifdef DEATH_TIME_LIMIT |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
267 cyg_handle_t deathH; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
268 cyg_alarm death_alarm; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
269 int is_dead = 0; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
270 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
271 setup_death_alarm(0, &deathH, &death_alarm, &is_dead); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
272 #endif /* DEATH_TIME_LIMIT */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
273 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
274 printf("# Starting main\n"); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
275 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
276 for (;;) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
277 int handler_id = -1; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
278 int handler_pri = 0; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
279 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
280 cyg_mutex_lock(&free_handler_lock); { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
281 // If any handler has left its ID, copy the ID and |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
282 // priority values to local variables, and free up the |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
283 // global communication variables again. |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
284 if (-1 != free_handler_id) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
285 handler_id = free_handler_id; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
286 handler_pri = free_handler_pri; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
287 free_handler_id = -1; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
288 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
289 } cyg_mutex_unlock(&free_handler_lock); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
290 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
291 if (-1 != handler_id) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
292 // Free the handler resources. This is done outside of the |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
293 // free_handler_lock to avoid deadlocks. |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
294 cyg_mutex_lock(&handler_slot_lock); { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
295 CYG_ASSERT(1 == priority_in_use[handler_pri], |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
296 "Priority not in use!"); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
297 CYG_ASSERT(1 == handler_thread_in_use[handler_id], |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
298 "Handler not in use!"); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
299 handler_thread_in_use[handler_id]--; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
300 priority_in_use[handler_pri]--; |
|
8
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
4
diff
changeset
|
301 |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
4
diff
changeset
|
302 // Finally delete the handler thread. This must be done in a |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
4
diff
changeset
|
303 // loop, waiting for the call to return true. If it returns |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
4
diff
changeset
|
304 // false, go to sleep for a bit, so the killed thread gets a |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
4
diff
changeset
|
305 // chance to run and complete its business. |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
4
diff
changeset
|
306 while (!cyg_thread_delete(handlerH[handler_id])) { |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
4
diff
changeset
|
307 cyg_thread_delay(2); |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
308 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
309 } cyg_mutex_unlock(&handler_slot_lock); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
310 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
311 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
312 // Print status if time. |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
313 if (time_to_report) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
314 time_to_report = 0; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
315 print_statistics(); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
316 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
317 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
318 #ifdef DEATH_TIME_LIMIT |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
319 // Stop test if time. |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
320 if (is_dead) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
321 print_statistics(); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
322 CYG_TEST_PASS_FINISH("Kernel thread stress test OK"); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
323 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
324 #endif /* DEATH_TIME_LIMIT */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
325 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
326 cyg_thread_delay(3); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
327 } |
| 2 | 328 } |
| 329 | |
| 330 /* client_program() -- an obnoxious client which makes a lot of requests */ | |
| 331 void client_program(cyg_addrword_t data) | |
| 332 { | |
| 333 int delay; | |
| 334 | |
| 335 printf("# Starting client-%d\n", (int) data); | |
| 336 | |
| 337 system_clockH = cyg_real_time_clock(); | |
| 338 cyg_clock_to_counter(system_clockH, &counterH); | |
| 339 | |
| 340 for (;;) { | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
341 delay = (rand() % 20); |
| 2 | 342 |
| 343 /* now send a request to the server */ | |
| 344 cyg_mutex_lock(&client_request_lock); { | |
| 345 ++client_makes_request; | |
| 346 /* printf("client_makes_request %d\n", client_makes_request); */ | |
| 347 } cyg_mutex_unlock(&client_request_lock); | |
| 348 | |
| 349 cyg_thread_delay(10+delay); | |
| 350 /* cyg_thread_delay(0); */ | |
| 351 } | |
| 352 } | |
| 353 | |
| 354 /* listener_program() -- listens for a request and spawns a handler to | |
| 355 take care of the request */ | |
| 356 void listener_program(cyg_addrword_t data) | |
| 357 { | |
| 358 /* int message = (int) data; */ | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
359 int handler_slot; |
| 2 | 360 |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
361 printf("# Beginning execution; thread data is %d\n", (int) data); |
| 2 | 362 |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
363 for (;;) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
364 int make_request = 0; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
365 cyg_mutex_lock(&client_request_lock); { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
366 if (client_makes_request > 0) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
367 --client_makes_request; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
368 make_request = 1; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
369 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
370 } cyg_mutex_unlock(&client_request_lock); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
371 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
372 if (make_request) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
373 int prio; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
374 /* printf("just got a request from a client (count = %d)\n", */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
375 /* client_makes_request); */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
376 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
377 handler_slot = get_handler_slot(listenerH[(int) data]); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
378 prio = N_MAIN+handler_slot; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
379 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
380 CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!"); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
381 priority_in_use[prio]++; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
382 sc_thread_create(prio, handler_program, |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
383 (cyg_addrword_t) handler_slot, |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
384 "handler", (void *) handler_stack[handler_slot], |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
385 STACK_SIZE2, &handlerH[handler_slot], |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
386 &handler_thread_s[handler_slot]); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
387 cyg_thread_resume(handlerH[handler_slot]); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
388 ++statistics.handler_invocation_histogram[handler_slot]; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
389 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
390 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
391 cyg_thread_delay(2 + (rand() % 10)); |
| 2 | 392 } |
| 393 } | |
| 394 | |
| 395 /* handler_program() -- is spawned to handle each incoming request */ | |
| 396 void handler_program(cyg_addrword_t data) | |
| 397 { | |
| 398 /* here is where we perform specific stressful tasks */ | |
| 399 perform_stressful_tasks(); | |
| 400 | |
| 401 cyg_thread_delay(4 + (int) (0.5*log(1.0 + fabs((rand() % 1000000))))); | |
| 402 /* cyg_thread_delay(0); */ | |
| 403 | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
404 ++statistics.thread_exits; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
405 { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
406 // Loop until the handler id and priority can be communicated to |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
407 // the main_program. |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
408 int freed = 0; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
409 do { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
410 cyg_mutex_lock(&free_handler_lock); { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
411 if (-1 == free_handler_id) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
412 free_handler_id = data; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
413 free_handler_pri = N_MAIN+(int) data; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
414 freed = 1; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
415 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
416 } cyg_mutex_unlock(&free_handler_lock); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
417 if (!freed) |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
418 cyg_thread_delay(2); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
419 } while (!freed); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
420 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
421 |
|
8
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
4
diff
changeset
|
422 // Then exit. |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
4
diff
changeset
|
423 cyg_thread_exit(); |
| 2 | 424 } |
| 425 | |
| 426 /* look for an available handler thread */ | |
| 427 int get_handler_slot(cyg_handle_t current_threadH) | |
| 428 { | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
429 int i; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
430 int found = 0; |
| 2 | 431 |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
432 while (!found) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
433 cyg_mutex_lock(&handler_slot_lock); { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
434 for (i = 0; i < MAX_HANDLERS; ++i) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
435 if (!handler_thread_in_use[i]) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
436 found = 1; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
437 handler_thread_in_use[i]++; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
438 break; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
439 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
440 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
441 } cyg_mutex_unlock(&handler_slot_lock); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
442 if (!found) |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
443 cyg_thread_delay(1); |
| 2 | 444 } |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
445 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
446 CYG_ASSERT(1 == handler_thread_in_use[i], "Handler usage count wrong!"); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
447 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
448 return i; |
| 2 | 449 } |
| 450 | |
| 451 /* do things which will stress the system */ | |
| 452 void perform_stressful_tasks() | |
| 453 { | |
| 454 #define MAX_MALLOCED_SPACES 100 /* do this many mallocs at most */ | |
| 455 #define MALLOCED_BASE_SIZE 1 /* basic size in bytes */ | |
| 456 char *spaces[MAX_MALLOCED_SPACES]; | |
| 457 unsigned int i; | |
| 458 | |
| 459 cyg_mutex_t tmp_lock; | |
| 460 | |
| 461 cyg_uint8 pool_space[10][100]; | |
| 462 cyg_handle_t mempool_handles[10]; | |
| 463 cyg_mempool_fix mempool_objects[10]; | |
| 464 | |
| 465 cyg_mutex_init(&tmp_lock); | |
| 466 | |
| 467 /* here I use malloc, which uses the kernel's variable memory pools. | |
| 468 note that malloc/free is a bit simple-minded here: it does not | |
| 469 try to really fragment things, and it does not try to make the | |
| 470 allocation/deallocation concurrent with other thread execution | |
| 471 (although I'm about to throw in a yield()) */ | |
| 472 for (i = 0; i < MAX_MALLOCED_SPACES; ++i) { | |
| 473 ++statistics.malloc_tries; | |
| 474 /* spaces[i] = (char *) malloc(((int)(sqrt(i*2.0))+1)*MALLOCED_BASE_SIZE); */ | |
| 475 spaces[i] = (char *) malloc(((int)i*2.0+1)*MALLOCED_BASE_SIZE); | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
476 if (i % (MAX_MALLOCED_SPACES/10) == 0) { |
| 2 | 477 cyg_thread_yield(); |
| 478 } | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
479 if (i % (MAX_MALLOCED_SPACES/15) == 0) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
480 cyg_thread_delay(i % 5); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
481 } |
| 2 | 482 } |
| 483 | |
| 484 /* now free it all up */ | |
| 485 for (i = 0; i < MAX_MALLOCED_SPACES; ++i) { | |
| 486 if (spaces[i] != NULL) { | |
| 487 unsigned int j; | |
| 488 for (j = 0; j < (i*2+1)*MALLOCED_BASE_SIZE; ++j) { | |
| 489 spaces[i][j] = 0xAA; /* write a bit pattern */ | |
| 490 } | |
| 491 free(spaces[i]); | |
| 492 } else { | |
| 493 ++statistics.malloc_failures; | |
| 494 } | |
| 495 } | |
| 496 /* now allocate and then free some fixed-size memory pools; for | |
| 497 now this is simple-minded because it does not have many threads | |
| 498 sharing the memory pools and racing for memory. */ | |
| 499 for (i = 0; i < 10; ++i) { | |
| 500 cyg_mempool_fix_create(pool_space[i], 100, (i+1)*3, | |
| 501 &mempool_handles[i], &mempool_objects[i]); | |
| 502 } | |
| 503 | |
| 504 for (i = 0; i < 10; ++i) { | |
| 505 spaces[i] = cyg_mempool_fix_try_alloc(mempool_handles[i]); | |
| 506 } | |
| 507 | |
| 508 for (i = 0; i < 10; ++i) { | |
| 509 if (spaces[i]) { | |
| 510 cyg_mempool_fix_delete(mempool_handles[i]); | |
| 511 } | |
| 512 } | |
| 513 | |
| 514 cyg_mutex_destroy(&tmp_lock); | |
| 515 } | |
| 516 | |
| 517 /* report_alarm_func() is invoked as an alarm handler, so it should be | |
| 518 quick and simple. in this case it sets a global flag which is | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
519 checked by main_program. */ |
| 2 | 520 void report_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data) |
| 521 { | |
| 522 time_to_report = 1; | |
| 523 } | |
| 524 | |
| 525 /* this sets up death alarms. it gets the handle and alarm from the | |
| 526 caller, since they must persist for the life of the alarm */ | |
| 527 void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp, | |
| 528 cyg_alarm *death_alarm_p, int *killed_p) | |
| 529 { | |
| 530 cyg_handle_t system_clockH, counterH; | |
| 531 cyg_resolution_t rtc_res; | |
| 532 | |
| 533 system_clockH = cyg_real_time_clock(); | |
| 534 cyg_clock_to_counter(system_clockH, &counterH); | |
| 535 | |
| 536 cyg_alarm_create(counterH, death_alarm_func, | |
| 537 (cyg_addrword_t) killed_p, | |
| 538 deathHp, death_alarm_p); | |
| 539 rtc_res = cyg_clock_get_resolution(system_clockH); | |
| 540 { | |
| 541 cyg_tick_count_t tick_delay; | |
| 542 tick_delay = (long long) | |
| 543 ((1000000000.0*rtc_res.divisor) | |
| 544 *((double)DEATH_TIME_LIMIT)/((double)rtc_res.dividend)); | |
| 545 if ( cyg_test_is_simulator ) | |
| 546 tick_delay /= 10; | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
547 #ifdef CYGPKG_HAL_I386_LINUX |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
548 // 20 seconds is a long time compared to the run time of other tests. |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
549 // Reduce to 10 seconds, allowing more tests to get run. |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
550 tick_delay /= 2; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
551 #endif |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
552 |
| 2 | 553 cyg_alarm_initialize(*deathHp, cyg_current_time() + tick_delay, 0); |
| 554 } | |
| 555 } | |
| 556 | |
| 557 /* death_alarm_func() is the alarm handler that kills the current | |
| 558 thread after a specified timeout. It does so by setting a flag the | |
| 559 thread is constantly checking. */ | |
| 560 void death_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data) | |
| 561 { | |
| 562 int *killed_p; | |
| 563 killed_p = (int *) data; | |
| 564 *killed_p = 1; | |
| 565 } | |
| 566 | |
| 567 /* now I write the sc_ versions of the cyg_functions */ | |
| 568 void sc_thread_create( | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
569 cyg_addrword_t sched_info, /* scheduling info (eg pri) */ |
| 2 | 570 cyg_thread_entry_t *entry, /* entry point function */ |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
571 cyg_addrword_t entry_data, /* entry data */ |
| 2 | 572 char *name, /* optional thread name */ |
| 573 void *stack_base, /* stack base, NULL = alloc */ | |
| 574 cyg_ucount32 stack_size, /* stack size, 0 = default */ | |
| 575 cyg_handle_t *handle, /* returned thread handle */ | |
| 576 cyg_thread *thread /* put thread here */ | |
| 577 ) | |
| 578 { | |
| 579 /*printf("Creating a thread -- priority is %lu\n", (unsigned long) sched_info);*/ | |
| 580 /* fflush(stdout); */ | |
| 581 ++statistics.thread_creations; | |
| 582 cyg_thread_create(sched_info, entry, entry_data, name, | |
| 583 stack_base, stack_size, handle, thread); | |
| 584 } | |
| 585 | |
| 586 void print_statistics(void) | |
| 587 { | |
| 588 int i; | |
| 589 | |
| 590 cyg_mutex_lock(&statistics_print_lock); { | |
| 591 printf("Handler-invocations: "); | |
| 592 for (i = 0; i < MAX_HANDLERS; ++i) { | |
| 593 printf("%4lu ", statistics.handler_invocation_histogram[i]); | |
| 594 } | |
| 595 printf("\n"); | |
| 596 printf("malloc()-tries/failures: -- %7lu %7lu\n", | |
| 597 statistics.malloc_tries, statistics.malloc_failures); | |
| 598 printf("client_makes_request: %d\n", client_makes_request); | |
| 599 } cyg_mutex_unlock(&statistics_print_lock); | |
| 600 } | |
| 601 | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
602 #else /* (CYGNUM_KERNEL_SCHED_PRIORITIES >= */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
603 /* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
604 #define N_A_MSG "not enough priorities available" |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
605 #endif /* (CYGNUM_KERNEL_SCHED_PRIORITIES >= */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
606 /* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
607 |
| 2 | 608 #else /* CYGSEM_LIBC_MALLOC */ |
| 609 # define N_A_MSG "this test needs malloc" | |
| 610 #endif /* CYGSEM_LIBC_MALLOC */ | |
| 611 | |
| 612 #else /* CYGFUN_KERNEL_THREADS_TIMER */ | |
| 613 # define N_A_MSG "this test needs kernel threads timer" | |
| 614 #endif /* CYGFUN_KERNEL_THREADS_TIMER */ | |
| 615 | |
| 616 #else /* CYGPKG_LIBM */ | |
| 617 # define N_A_MSG "this test needs libm" | |
| 618 #endif /* CYGPKG_LIBM */ | |
| 619 | |
| 620 #else /* CYGSEM_LIBC_STDIO */ | |
| 621 # define N_A_MSG "this test needs stdio" | |
| 622 #endif /* CYGSEM_LIBC_STDIO */ | |
| 623 | |
| 624 #else // def CYGFUN_KERNEL_API_C | |
| 625 # define N_A_MSG "this test needs Kernel C API" | |
| 626 #endif | |
| 627 | |
| 628 #else // def CYGPKG_KERNEL && CYGPKG_IO && CYGPKG_LIBC | |
| 629 # define N_A_MSG "this tests needs Kernel, libc and IO" | |
| 630 #endif | |
| 631 | |
| 632 #ifdef N_A_MSG | |
| 633 externC void | |
| 634 cyg_start( void ) | |
| 635 { | |
| 636 CYG_TEST_INIT(); | |
| 637 CYG_TEST_NA( N_A_MSG); | |
| 638 } | |
| 639 #endif // N_A_MSG |
