Mercurial > flash_v2
annotate packages/kernel/current/tests/stress_threads.c @ 22:53104bbd5f99 ecos-sw-1999-07-09
Merge from eCos master repository on 1999-07-09-05:47:06-BST
| author | jlarmour |
|---|---|
| date | Fri, 09 Jul 1999 07:15:07 +0000 |
| parents | d3fbcdfa1b2f |
| children | 306eee292492 |
| 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 | |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
72 #include <cyg/kernel/test/stackmon.h> |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
73 |
| 2 | 74 #if defined(CYGFUN_KERNEL_THREADS_TIMER) |
| 75 #if defined(CYGPKG_LIBC_MALLOC) | |
| 76 | |
| 77 /* if TIME_LIMIT is defined, it represents the number of seconds this | |
| 78 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
|
79 #define DEATH_TIME_LIMIT 20 |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
80 /* #undef DEATH_TIME_LIMIT */ |
| 2 | 81 |
|
22
53104bbd5f99
Merge from eCos master repository on 1999-07-09-05:47:06-BST
jlarmour
parents:
10
diff
changeset
|
82 // STACK_SIZE is typical +2kB for printf family calls which use big |
|
53104bbd5f99
Merge from eCos master repository on 1999-07-09-05:47:06-BST
jlarmour
parents:
10
diff
changeset
|
83 // auto variables. |
|
53104bbd5f99
Merge from eCos master repository on 1999-07-09-05:47:06-BST
jlarmour
parents:
10
diff
changeset
|
84 #define STACK_SIZE (2*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL) |
| 2 | 85 #define STACK_SIZE2 (8*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL) |
| 86 | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
87 /* 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
|
88 (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
|
89 complete their tasks. */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
90 #define N_MAIN 1 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
91 #define MAX_HANDLERS 19 |
| 2 | 92 #define N_LISTENERS 4 |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
93 #define N_CLIENTS 4 |
| 2 | 94 |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
95 #if (CYGNUM_KERNEL_SCHED_PRIORITIES >= (N_MAIN+MAX_HANDLERS+N_LISTENERS+N_CLIENTS)) |
| 2 | 96 |
| 97 /* if we use the bitmap scheduler we must make sure we don't use the | |
| 98 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
|
99 static volatile char priority_in_use[N_MAIN+MAX_HANDLERS+N_LISTENERS+N_CLIENTS]; |
| 2 | 100 |
| 101 /* now declare (and allocate space for) some kernel objects, like the | |
| 102 threads we will use */ | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
103 cyg_thread main_thread_s; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
104 cyg_thread handler_thread_s[MAX_HANDLERS]; |
| 2 | 105 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
|
106 cyg_thread client_thread_s[N_CLIENTS]; |
| 2 | 107 |
| 108 /* 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
|
109 char main_stack[STACK_SIZE]; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
110 char handler_stack[MAX_HANDLERS][STACK_SIZE2]; |
| 2 | 111 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
|
112 char client_stack[N_CLIENTS][STACK_SIZE]; |
| 2 | 113 |
| 114 /* 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
|
115 cyg_handle_t mainH; |
| 2 | 116 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
|
117 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
|
118 cyg_handle_t clientH[N_CLIENTS]; |
| 2 | 119 |
| 120 /* 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
|
121 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
|
122 handler_program; |
| 2 | 123 |
| 124 /* 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
|
125 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
|
126 free_handler_lock; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
127 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
128 /* 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
|
129 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
|
130 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
|
131 that the variables are empty. */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
132 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
|
133 volatile int free_handler_id = -1; |
| 2 | 134 |
| 135 /* a global variable with which the client and server coordinate */ | |
| 136 int client_makes_request = 0; | |
| 137 | |
| 138 /* indicates that it's time to print out a report */ | |
| 139 int time_to_report = 0; | |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
140 /* print status after a delay of this many secs. */ |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
141 int time_report_delay; |
| 2 | 142 |
| 143 /*** now application-specific variables ***/ | |
| 144 /* an array that stores whether the handler threads are in use */ | |
| 145 int handler_thread_in_use[MAX_HANDLERS]; | |
| 146 | |
| 147 /***** statistics-gathering variables *****/ | |
| 148 struct s_statistics { | |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
149 /* store the number of times each handler has been invoked */ |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
150 unsigned long handler_invocation_histogram[MAX_HANDLERS]; |
| 2 | 151 |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
152 /* store how many times malloc has been attempted and how many times |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
153 it has failed */ |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
154 unsigned long malloc_tries, malloc_failures; |
| 2 | 155 |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
156 /* how many threads have been created */ |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
157 unsigned long thread_creations, thread_exits; |
| 2 | 158 }; |
| 159 | |
| 160 struct s_statistics statistics; | |
| 161 | |
| 162 /* some function prototypes; those with the sc_ prefix are | |
| 163 "statistics-collecting" versions of the cyg_ primitives */ | |
| 164 void sc_thread_create( | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
165 cyg_addrword_t sched_info, /* scheduling info (eg pri) */ |
| 2 | 166 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
|
167 cyg_addrword_t entry_data, /* entry data */ |
| 2 | 168 char *name, /* optional thread name */ |
| 169 void *stack_base, /* stack base, NULL = alloc */ | |
| 170 cyg_ucount32 stack_size, /* stack size, 0 = default */ | |
| 171 cyg_handle_t *handle, /* returned thread handle */ | |
| 172 cyg_thread *thread /* put thread here */ | |
| 173 ); | |
| 174 | |
| 175 int get_handler_slot(cyg_handle_t current_threadH); | |
| 176 void perform_stressful_tasks(void); | |
| 177 void permute_array(char a[], int size, int seed); | |
| 178 void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp, | |
| 179 cyg_alarm *death_alarm_p, int *killed_p); | |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
180 void print_statistics(int print_full); |
| 2 | 181 |
| 182 /* we need to declare the alarm handling function (which is defined | |
| 183 below), so that we can pass it to cyg_alarm_initialize() */ | |
| 184 cyg_alarm_t report_alarm_func, death_alarm_func; | |
| 185 | |
| 186 /* handle and alarm for the report alarm */ | |
| 187 cyg_handle_t report_alarmH, counterH, system_clockH; | |
| 188 cyg_alarm report_alarm; | |
| 189 | |
|
22
53104bbd5f99
Merge from eCos master repository on 1999-07-09-05:47:06-BST
jlarmour
parents:
10
diff
changeset
|
190 /* main launches all the threads of the test */ |
|
53104bbd5f99
Merge from eCos master repository on 1999-07-09-05:47:06-BST
jlarmour
parents:
10
diff
changeset
|
191 int |
|
53104bbd5f99
Merge from eCos master repository on 1999-07-09-05:47:06-BST
jlarmour
parents:
10
diff
changeset
|
192 main(void) |
| 2 | 193 { |
| 194 int i; | |
| 195 | |
| 196 CYG_TEST_INIT(); | |
| 197 CYG_TEST_INFO("# Entering stress's cyg_user_start() function"); | |
| 198 | |
| 199 cyg_mutex_init(&client_request_lock); | |
| 200 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
|
201 cyg_mutex_init(&free_handler_lock); |
| 2 | 202 |
| 203 /* initialize statistics */ | |
| 204 memset(&statistics, 0, sizeof(statistics)); | |
| 205 | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
206 /* clear priority table */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
207 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
|
208 priority_in_use[i] = 0; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
209 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
210 /* initialize main thread */ |
|
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 char thread_name[] = "main"; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
213 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
214 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
|
215 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
|
216 &mainH, &main_thread_s); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
217 priority_in_use[0]++; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
218 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
219 |
| 2 | 220 /* initialize all handler threads to not be in use */ |
| 221 for (i = 0; i < MAX_HANDLERS; ++i) { | |
| 222 handler_thread_in_use[i] = 0; | |
| 223 } | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
224 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
|
225 int prio; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
226 char thread_name[20]; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
227 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
|
228 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
|
229 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
|
230 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
|
231 &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
|
232 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
|
233 priority_in_use[prio]++; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
234 } |
| 2 | 235 for (i = 0; i < N_CLIENTS; ++i) { |
| 236 int prio; | |
| 237 char thread_name[20]; | |
| 238 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
|
239 prio = N_MAIN + MAX_HANDLERS + N_LISTENERS + i; |
| 2 | 240 sc_thread_create(prio, client_program, (cyg_addrword_t) i, |
| 241 thread_name, (void *) client_stack[i], STACK_SIZE, | |
| 242 &(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
|
243 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
|
244 priority_in_use[prio]++; |
| 2 | 245 } |
| 246 | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
247 cyg_thread_resume(mainH); |
| 2 | 248 for (i = 0; i < N_CLIENTS; ++i) { |
| 249 cyg_thread_resume(clientH[i]); | |
| 250 } | |
| 251 for (i = 0; i < N_LISTENERS; ++i) { | |
| 252 cyg_thread_resume(listenerH[i]); | |
| 253 } | |
| 254 | |
| 255 /* set up the alarm which gives periodic wakeups to say "time to | |
| 256 print a report */ | |
| 257 system_clockH = cyg_real_time_clock(); | |
| 258 cyg_clock_to_counter(system_clockH, &counterH); | |
| 259 | |
| 260 cyg_alarm_create(counterH, report_alarm_func, | |
| 261 (cyg_addrword_t) 4000, | |
| 262 &report_alarmH, &report_alarm); | |
| 263 if (cyg_test_is_simulator) { | |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
264 time_report_delay = 2; |
| 2 | 265 } else { |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
266 time_report_delay = 30; |
| 2 | 267 } |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
268 |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
269 cyg_alarm_initialize(report_alarmH, cyg_current_time()+200, |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
270 time_report_delay*100); |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
271 } |
| 2 | 272 |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
273 /* 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
|
274 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
|
275 { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
276 #ifdef DEATH_TIME_LIMIT |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
277 cyg_handle_t deathH; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
278 cyg_alarm death_alarm; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
279 int is_dead = 0; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
280 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
281 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
|
282 #endif /* DEATH_TIME_LIMIT */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
283 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
284 printf("# Starting main\n"); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
285 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
286 for (;;) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
287 int handler_id = -1; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
288 int handler_pri = 0; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
289 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
290 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
|
291 // 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
|
292 // 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
|
293 // global communication variables again. |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
294 if (-1 != free_handler_id) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
295 handler_id = free_handler_id; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
296 handler_pri = free_handler_pri; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
297 free_handler_id = -1; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
298 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
299 } 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
|
300 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
301 if (-1 != handler_id) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
302 // 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
|
303 // 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
|
304 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
|
305 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
|
306 "Priority not in use!"); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
307 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
|
308 "Handler not in use!"); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
309 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
|
310 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
|
311 |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
4
diff
changeset
|
312 // 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
|
313 // 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
|
314 // 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
|
315 // 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
|
316 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
|
317 cyg_thread_delay(2); |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
318 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
319 } 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
|
320 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
321 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
322 // Print status if time. |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
323 if (time_to_report) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
324 time_to_report = 0; |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
325 print_statistics(0); |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
326 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
327 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
328 #ifdef DEATH_TIME_LIMIT |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
329 // Stop test if time. |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
330 if (is_dead) { |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
331 print_statistics(1); |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
332 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
|
333 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
334 #endif /* DEATH_TIME_LIMIT */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
335 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
336 cyg_thread_delay(3); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
337 } |
| 2 | 338 } |
| 339 | |
| 340 /* client_program() -- an obnoxious client which makes a lot of requests */ | |
| 341 void client_program(cyg_addrword_t data) | |
| 342 { | |
| 343 int delay; | |
| 344 | |
| 345 printf("# Starting client-%d\n", (int) data); | |
| 346 | |
| 347 system_clockH = cyg_real_time_clock(); | |
| 348 cyg_clock_to_counter(system_clockH, &counterH); | |
| 349 | |
| 350 for (;;) { | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
351 delay = (rand() % 20); |
| 2 | 352 |
| 353 /* now send a request to the server */ | |
| 354 cyg_mutex_lock(&client_request_lock); { | |
| 355 ++client_makes_request; | |
| 356 /* printf("client_makes_request %d\n", client_makes_request); */ | |
| 357 } cyg_mutex_unlock(&client_request_lock); | |
| 358 | |
| 359 cyg_thread_delay(10+delay); | |
| 360 /* cyg_thread_delay(0); */ | |
| 361 } | |
| 362 } | |
| 363 | |
| 364 /* listener_program() -- listens for a request and spawns a handler to | |
| 365 take care of the request */ | |
| 366 void listener_program(cyg_addrword_t data) | |
| 367 { | |
| 368 /* int message = (int) data; */ | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
369 int handler_slot; |
| 2 | 370 |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
371 printf("# Beginning execution; thread data is %d\n", (int) data); |
| 2 | 372 |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
373 for (;;) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
374 int make_request = 0; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
375 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
|
376 if (client_makes_request > 0) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
377 --client_makes_request; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
378 make_request = 1; |
|
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_mutex_unlock(&client_request_lock); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
381 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
382 if (make_request) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
383 int prio; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
384 /* 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
|
385 /* client_makes_request); */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
386 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
387 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
|
388 prio = N_MAIN+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 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
|
391 priority_in_use[prio]++; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
392 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
|
393 (cyg_addrword_t) handler_slot, |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
394 "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
|
395 STACK_SIZE2, &handlerH[handler_slot], |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
396 &handler_thread_s[handler_slot]); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
397 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
|
398 ++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
|
399 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
400 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
401 cyg_thread_delay(2 + (rand() % 10)); |
| 2 | 402 } |
| 403 } | |
| 404 | |
| 405 /* handler_program() -- is spawned to handle each incoming request */ | |
| 406 void handler_program(cyg_addrword_t data) | |
| 407 { | |
| 408 /* here is where we perform specific stressful tasks */ | |
| 409 perform_stressful_tasks(); | |
| 410 | |
| 411 cyg_thread_delay(4 + (int) (0.5*log(1.0 + fabs((rand() % 1000000))))); | |
| 412 /* cyg_thread_delay(0); */ | |
| 413 | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
414 ++statistics.thread_exits; |
|
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 // 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
|
417 // the main_program. |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
418 int freed = 0; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
419 do { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
420 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
|
421 if (-1 == free_handler_id) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
422 free_handler_id = data; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
423 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
|
424 freed = 1; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
425 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
426 } 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
|
427 if (!freed) |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
428 cyg_thread_delay(2); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
429 } while (!freed); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
430 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
431 |
|
8
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
4
diff
changeset
|
432 // Then exit. |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
4
diff
changeset
|
433 cyg_thread_exit(); |
| 2 | 434 } |
| 435 | |
| 436 /* look for an available handler thread */ | |
| 437 int get_handler_slot(cyg_handle_t current_threadH) | |
| 438 { | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
439 int i; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
440 int found = 0; |
| 2 | 441 |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
442 while (!found) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
443 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
|
444 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
|
445 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
|
446 found = 1; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
447 handler_thread_in_use[i]++; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
448 break; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
449 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
450 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
451 } 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
|
452 if (!found) |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
453 cyg_thread_delay(1); |
| 2 | 454 } |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
455 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
456 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
|
457 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
458 return i; |
| 2 | 459 } |
| 460 | |
| 461 /* do things which will stress the system */ | |
| 462 void perform_stressful_tasks() | |
| 463 { | |
| 464 #define MAX_MALLOCED_SPACES 100 /* do this many mallocs at most */ | |
| 465 #define MALLOCED_BASE_SIZE 1 /* basic size in bytes */ | |
| 466 char *spaces[MAX_MALLOCED_SPACES]; | |
| 467 unsigned int i; | |
| 468 | |
| 469 cyg_mutex_t tmp_lock; | |
| 470 | |
| 471 cyg_uint8 pool_space[10][100]; | |
| 472 cyg_handle_t mempool_handles[10]; | |
| 473 cyg_mempool_fix mempool_objects[10]; | |
| 474 | |
| 475 cyg_mutex_init(&tmp_lock); | |
| 476 | |
| 477 /* here I use malloc, which uses the kernel's variable memory pools. | |
| 478 note that malloc/free is a bit simple-minded here: it does not | |
| 479 try to really fragment things, and it does not try to make the | |
| 480 allocation/deallocation concurrent with other thread execution | |
| 481 (although I'm about to throw in a yield()) */ | |
| 482 for (i = 0; i < MAX_MALLOCED_SPACES; ++i) { | |
| 483 ++statistics.malloc_tries; | |
| 484 /* spaces[i] = (char *) malloc(((int)(sqrt(i*2.0))+1)*MALLOCED_BASE_SIZE); */ | |
| 485 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
|
486 if (i % (MAX_MALLOCED_SPACES/10) == 0) { |
| 2 | 487 cyg_thread_yield(); |
| 488 } | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
489 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
|
490 cyg_thread_delay(i % 5); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
491 } |
| 2 | 492 } |
| 493 | |
| 494 /* now free it all up */ | |
| 495 for (i = 0; i < MAX_MALLOCED_SPACES; ++i) { | |
| 496 if (spaces[i] != NULL) { | |
| 497 unsigned int j; | |
| 498 for (j = 0; j < (i*2+1)*MALLOCED_BASE_SIZE; ++j) { | |
| 499 spaces[i][j] = 0xAA; /* write a bit pattern */ | |
| 500 } | |
| 501 free(spaces[i]); | |
| 502 } else { | |
| 503 ++statistics.malloc_failures; | |
| 504 } | |
| 505 } | |
| 506 /* now allocate and then free some fixed-size memory pools; for | |
| 507 now this is simple-minded because it does not have many threads | |
| 508 sharing the memory pools and racing for memory. */ | |
| 509 for (i = 0; i < 10; ++i) { | |
| 510 cyg_mempool_fix_create(pool_space[i], 100, (i+1)*3, | |
| 511 &mempool_handles[i], &mempool_objects[i]); | |
| 512 } | |
| 513 | |
| 514 for (i = 0; i < 10; ++i) { | |
| 515 spaces[i] = cyg_mempool_fix_try_alloc(mempool_handles[i]); | |
| 516 } | |
| 517 | |
| 518 for (i = 0; i < 10; ++i) { | |
| 519 if (spaces[i]) { | |
| 520 cyg_mempool_fix_delete(mempool_handles[i]); | |
| 521 } | |
| 522 } | |
| 523 | |
| 524 cyg_mutex_destroy(&tmp_lock); | |
| 525 } | |
| 526 | |
| 527 /* report_alarm_func() is invoked as an alarm handler, so it should be | |
| 528 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
|
529 checked by main_program. */ |
| 2 | 530 void report_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data) |
| 531 { | |
| 532 time_to_report = 1; | |
| 533 } | |
| 534 | |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
535 #ifdef DEATH_TIME_LIMIT |
| 2 | 536 /* this sets up death alarms. it gets the handle and alarm from the |
| 537 caller, since they must persist for the life of the alarm */ | |
| 538 void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp, | |
| 539 cyg_alarm *death_alarm_p, int *killed_p) | |
| 540 { | |
| 541 cyg_handle_t system_clockH, counterH; | |
| 542 cyg_resolution_t rtc_res; | |
| 543 | |
| 544 system_clockH = cyg_real_time_clock(); | |
| 545 cyg_clock_to_counter(system_clockH, &counterH); | |
| 546 | |
| 547 cyg_alarm_create(counterH, death_alarm_func, | |
| 548 (cyg_addrword_t) killed_p, | |
| 549 deathHp, death_alarm_p); | |
| 550 rtc_res = cyg_clock_get_resolution(system_clockH); | |
| 551 { | |
| 552 cyg_tick_count_t tick_delay; | |
| 553 tick_delay = (long long) | |
| 554 ((1000000000.0*rtc_res.divisor) | |
| 555 *((double)DEATH_TIME_LIMIT)/((double)rtc_res.dividend)); | |
| 556 if ( cyg_test_is_simulator ) | |
| 557 tick_delay /= 10; | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
558 #ifdef CYGPKG_HAL_I386_LINUX |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
559 // 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
|
560 // 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
|
561 tick_delay /= 2; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
562 #endif |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
563 |
| 2 | 564 cyg_alarm_initialize(*deathHp, cyg_current_time() + tick_delay, 0); |
| 565 } | |
| 566 } | |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
567 #endif |
| 2 | 568 |
| 569 /* death_alarm_func() is the alarm handler that kills the current | |
| 570 thread after a specified timeout. It does so by setting a flag the | |
| 571 thread is constantly checking. */ | |
| 572 void death_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data) | |
| 573 { | |
| 574 int *killed_p; | |
| 575 killed_p = (int *) data; | |
| 576 *killed_p = 1; | |
| 577 } | |
| 578 | |
| 579 /* now I write the sc_ versions of the cyg_functions */ | |
| 580 void sc_thread_create( | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
581 cyg_addrword_t sched_info, /* scheduling info (eg pri) */ |
| 2 | 582 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
|
583 cyg_addrword_t entry_data, /* entry data */ |
| 2 | 584 char *name, /* optional thread name */ |
| 585 void *stack_base, /* stack base, NULL = alloc */ | |
| 586 cyg_ucount32 stack_size, /* stack size, 0 = default */ | |
| 587 cyg_handle_t *handle, /* returned thread handle */ | |
| 588 cyg_thread *thread /* put thread here */ | |
| 589 ) | |
| 590 { | |
| 591 /*printf("Creating a thread -- priority is %lu\n", (unsigned long) sched_info);*/ | |
| 592 /* fflush(stdout); */ | |
| 593 ++statistics.thread_creations; | |
| 594 cyg_thread_create(sched_info, entry, entry_data, name, | |
| 595 stack_base, stack_size, handle, thread); | |
| 596 } | |
| 597 | |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
598 |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
599 void print_statistics(int print_full) |
| 2 | 600 { |
| 601 int i; | |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
602 static int print_count = 0; |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
603 |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
604 printf("State dump %d (time %02d.%02d.%02d)\n", |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
605 print_count, |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
606 print_count*time_report_delay / (60*60), // hours |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
607 (print_count*time_report_delay / 60) % 60, // minutes |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
608 (print_count*time_report_delay ) % 60); // seconds |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
609 print_count++; |
| 2 | 610 |
| 611 cyg_mutex_lock(&statistics_print_lock); { | |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
612 printf(" Handler-invocations: "); |
| 2 | 613 for (i = 0; i < MAX_HANDLERS; ++i) { |
| 614 printf("%4lu ", statistics.handler_invocation_histogram[i]); | |
| 615 } | |
| 616 printf("\n"); | |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
617 printf(" malloc()-tries/failures: -- %7lu %7lu\n", |
| 2 | 618 statistics.malloc_tries, statistics.malloc_failures); |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
619 printf(" client_makes_request: %d\n", client_makes_request); |
| 2 | 620 } cyg_mutex_unlock(&statistics_print_lock); |
|
10
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
621 |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
622 // Add: Also occasionally dump individual threads' stack status. |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
623 if (0 == print_count % 5 || print_full) { |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
624 cyg_test_dump_interrupt_stack_stats( " Status" ); |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
625 cyg_test_dump_idlethread_stack_stats( " Status" ); |
|
d3fbcdfa1b2f
Merge from eCos master repository on 1999-05-29-00:13:11-BST
jlarmour
parents:
8
diff
changeset
|
626 } |
| 2 | 627 } |
| 628 | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
629 #else /* (CYGNUM_KERNEL_SCHED_PRIORITIES >= */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
630 /* (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
|
631 #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
|
632 #endif /* (CYGNUM_KERNEL_SCHED_PRIORITIES >= */ |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
633 /* (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
|
634 |
| 2 | 635 #else /* CYGSEM_LIBC_MALLOC */ |
| 636 # define N_A_MSG "this test needs malloc" | |
| 637 #endif /* CYGSEM_LIBC_MALLOC */ | |
| 638 | |
| 639 #else /* CYGFUN_KERNEL_THREADS_TIMER */ | |
| 640 # define N_A_MSG "this test needs kernel threads timer" | |
| 641 #endif /* CYGFUN_KERNEL_THREADS_TIMER */ | |
| 642 | |
| 643 #else /* CYGPKG_LIBM */ | |
| 644 # define N_A_MSG "this test needs libm" | |
| 645 #endif /* CYGPKG_LIBM */ | |
| 646 | |
| 647 #else /* CYGSEM_LIBC_STDIO */ | |
| 648 # define N_A_MSG "this test needs stdio" | |
| 649 #endif /* CYGSEM_LIBC_STDIO */ | |
| 650 | |
| 651 #else // def CYGFUN_KERNEL_API_C | |
| 652 # define N_A_MSG "this test needs Kernel C API" | |
| 653 #endif | |
| 654 | |
| 655 #else // def CYGPKG_KERNEL && CYGPKG_IO && CYGPKG_LIBC | |
| 656 # define N_A_MSG "this tests needs Kernel, libc and IO" | |
| 657 #endif | |
| 658 | |
| 659 #ifdef N_A_MSG | |
| 660 externC void | |
| 661 cyg_start( void ) | |
| 662 { | |
| 663 CYG_TEST_INIT(); | |
| 664 CYG_TEST_NA( N_A_MSG); | |
| 665 } | |
| 666 #endif // N_A_MSG |
