win-pvdrivers

view liblfds.6/test/src/test_queue.c @ 1025:aa2e51f67f7c

Fix hibernate under Win8. Change debugprints.
author James Harper <james.harper@bendigoit.com.au>
date Tue Feb 19 15:14:53 2013 +1100 (2013-02-19)
parents 6300617040e0
children
line source
1 #include "internal.h"
7 /****************************************************************************/
8 void test_queue( void )
9 {
10 printf( "\n"
11 "Queue Tests\n"
12 "===========\n" );
14 queue_test_enqueuing();
15 queue_test_dequeuing();
16 queue_test_enqueuing_and_dequeuing();
17 queue_test_rapid_enqueuing_and_dequeuing();
19 return;
20 }
26 /****************************************************************************/
27 void queue_test_enqueuing( void )
28 {
29 unsigned int
30 loop,
31 cpu_count;
33 thread_state_t
34 *thread_handles;
36 struct queue_state
37 *qs;
39 struct queue_test_enqueuing_state
40 *qtes;
42 atom_t
43 user_data,
44 thread,
45 count,
46 *per_thread_counters;
48 struct validation_info
49 vi = { 1000000, 1000000 };
51 enum data_structure_validity
52 dvs[2];
54 /* TRD : create an empty queue with 1,000,000 elements in its freelist
55 then run one thread per CPU
56 where each thread busy-works, enqueuing elements (until there are no more elements)
57 each element's void pointer of user data is (thread number | element number)
58 where element_number is a thread-local counter starting at 0
59 where the thread_number occupies the top byte
61 when we're done, we check that all the elements are present
62 and increment on a per-thread basis
63 */
65 internal_display_test_name( "Enqueuing" );
67 cpu_count = abstraction_cpu_count();
69 queue_new( &qs, 1000000 );
71 qtes = malloc( sizeof(struct queue_test_enqueuing_state) * cpu_count );
73 for( loop = 0 ; loop < cpu_count ; loop++ )
74 {
75 (qtes+loop)->qs = qs;
76 (qtes+loop)->counter = (atom_t) loop << (sizeof(atom_t)*8-8);
77 }
79 thread_handles = malloc( sizeof(thread_state_t) * cpu_count );
81 for( loop = 0 ; loop < cpu_count ; loop++ )
82 abstraction_thread_start( &thread_handles[loop], loop, queue_test_internal_thread_simple_enqueuer, qtes+loop );
84 for( loop = 0 ; loop < cpu_count ; loop++ )
85 abstraction_thread_wait( thread_handles[loop] );
87 free( thread_handles );
89 free( qtes );
91 /* TRD : first, validate the queue
93 then dequeue
94 we expect to find element numbers increment on a per thread basis
95 */
97 queue_query( qs, QUEUE_QUERY_VALIDATE, &vi, dvs );
99 per_thread_counters = malloc( sizeof(atom_t) * cpu_count );
101 for( loop = 0 ; loop < cpu_count ; loop++ )
102 *(per_thread_counters+loop) = 0;
104 while( dvs[0] == VALIDITY_VALID and dvs[1] == VALIDITY_VALID and queue_dequeue(qs, (void *) &user_data) )
105 {
106 thread = user_data >> (sizeof(atom_t)*8-8);
107 count = (user_data << 8) >> 8;
109 if( thread >= cpu_count )
110 {
111 dvs[0] = VALIDITY_INVALID_TEST_DATA;
112 break;
113 }
115 if( count < per_thread_counters[thread] )
116 dvs[0] = VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
118 if( count > per_thread_counters[thread] )
119 dvs[0] = VALIDITY_INVALID_MISSING_ELEMENTS;
121 if( count == per_thread_counters[thread] )
122 per_thread_counters[thread]++;
123 }
125 free( per_thread_counters );
127 queue_delete( qs, NULL, NULL );
129 internal_display_test_result( 2, "queue", dvs[0], "queue freelist", dvs[1] );
131 return;
132 }
138 /****************************************************************************/
139 thread_return_t CALLING_CONVENTION queue_test_internal_thread_simple_enqueuer( void *queue_test_enqueuing_state )
140 {
141 struct queue_test_enqueuing_state
142 *qtes;
144 assert( queue_test_enqueuing_state != NULL );
146 qtes = (struct queue_test_enqueuing_state *) queue_test_enqueuing_state;
148 // TRD : top byte of counter is already our thread number
149 while( queue_enqueue(qtes->qs, (void *) qtes->counter++) );
151 return( (thread_return_t) EXIT_SUCCESS );
152 }
158 /****************************************************************************/
159 void queue_test_dequeuing( void )
160 {
161 unsigned int
162 loop,
163 cpu_count;
165 thread_state_t
166 *thread_handles;
168 struct queue_state
169 *qs;
171 struct queue_test_dequeuing_state
172 *qtds;
174 struct validation_info
175 vi = { 0, 0 };
177 enum data_structure_validity
178 dvs[2];
180 /* TRD : create a queue with 1,000,000 elements
182 use a single thread to enqueue every element
183 each elements user data is an incrementing counter
185 then run one thread per CPU
186 where each busy-works dequeuing
188 when an element is dequeued, we check (on a per-thread basis) the
189 value deqeued is greater than the element previously dequeued
190 */
192 internal_display_test_name( "Dequeuing" );
194 cpu_count = abstraction_cpu_count();
196 queue_new( &qs, 1000000 );
198 for( loop = 0 ; loop < 1000000 ; loop++ )
199 queue_enqueue( qs, (void *) (atom_t) loop );
201 qtds = malloc( sizeof(struct queue_test_dequeuing_state) * cpu_count );
203 for( loop = 0 ; loop < cpu_count ; loop++ )
204 {
205 (qtds+loop)->qs = qs;
206 (qtds+loop)->error_flag = LOWERED;
207 }
209 thread_handles = malloc( sizeof(thread_state_t) * cpu_count );
211 for( loop = 0 ; loop < cpu_count ; loop++ )
212 abstraction_thread_start( &thread_handles[loop], loop, queue_test_internal_thread_simple_dequeuer, qtds+loop );
214 for( loop = 0 ; loop < cpu_count ; loop++ )
215 abstraction_thread_wait( thread_handles[loop] );
217 free( thread_handles );
219 // TRD : check queue is empty
220 queue_query( qs, QUEUE_QUERY_VALIDATE, (void *) &vi, (void *) dvs );
222 // TRD : check for raised error flags
223 for( loop = 0 ; loop < cpu_count ; loop++ )
224 if( (qtds+loop)->error_flag == RAISED )
225 dvs[0] = VALIDITY_INVALID_TEST_DATA;
227 free( qtds );
229 queue_delete( qs, NULL, NULL );
231 internal_display_test_result( 2, "queue", dvs[0], "queue freelist", dvs[1] );
233 return;
234 }
240 /****************************************************************************/
241 thread_return_t CALLING_CONVENTION queue_test_internal_thread_simple_dequeuer( void *queue_test_dequeuing_state )
242 {
243 struct queue_test_dequeuing_state
244 *qtds;
246 atom_t
247 *prev_user_data,
248 *user_data;
250 assert( queue_test_dequeuing_state != NULL );
252 qtds = (struct queue_test_dequeuing_state *) queue_test_dequeuing_state;
254 queue_dequeue( qtds->qs, (void *) &prev_user_data );
256 while( queue_dequeue(qtds->qs, (void *) &user_data) )
257 {
258 if( user_data <= prev_user_data )
259 qtds->error_flag = RAISED;
261 prev_user_data = user_data;
262 }
264 return( (thread_return_t) EXIT_SUCCESS );
265 }
271 /****************************************************************************/
272 void queue_test_enqueuing_and_dequeuing( void )
273 {
274 unsigned int
275 loop,
276 subloop,
277 cpu_count;
279 thread_state_t
280 *thread_handles;
282 struct queue_state
283 *qs;
285 struct queue_test_enqueuing_and_dequeuing_state
286 *qteds;
288 struct validation_info
289 vi = { 0, 0 };
291 enum data_structure_validity
292 dvs[2];
294 internal_display_test_name( "Enqueuing and dequeuing (10 seconds)" );
296 cpu_count = abstraction_cpu_count();
298 queue_new( &qs, cpu_count );
300 qteds = malloc( sizeof(struct queue_test_enqueuing_and_dequeuing_state) * cpu_count );
302 for( loop = 0 ; loop < cpu_count ; loop++ )
303 {
304 (qteds+loop)->qs = qs;
305 (qteds+loop)->thread_number = loop;
306 (qteds+loop)->counter = (atom_t) loop << (sizeof(atom_t)*8-8);
307 (qteds+loop)->cpu_count = cpu_count;
308 (qteds+loop)->error_flag = LOWERED;
309 (qteds+loop)->per_thread_counters = malloc( sizeof(atom_t) * cpu_count );
311 for( subloop = 0 ; subloop < cpu_count ; subloop++ )
312 *((qteds+loop)->per_thread_counters+subloop) = 0;
313 }
315 thread_handles = malloc( sizeof(thread_state_t) * cpu_count );
317 for( loop = 0 ; loop < cpu_count ; loop++ )
318 abstraction_thread_start( &thread_handles[loop], loop, queue_test_internal_thread_enqueuer_and_dequeuer, qteds+loop );
320 for( loop = 0 ; loop < cpu_count ; loop++ )
321 abstraction_thread_wait( thread_handles[loop] );
323 free( thread_handles );
325 queue_query( qs, QUEUE_QUERY_VALIDATE, (void *) &vi, (void *) dvs );
327 for( loop = 0 ; loop < cpu_count ; loop++ )
328 if( (qteds+loop)->error_flag == RAISED )
329 dvs[0] = VALIDITY_INVALID_TEST_DATA;
331 for( loop = 0 ; loop < cpu_count ; loop++ )
332 free( (qteds+loop)->per_thread_counters );
334 free( qteds );
336 queue_delete( qs, NULL, NULL );
338 internal_display_test_result( 2, "queue", dvs[0], "queue freelist", dvs[1] );
340 return;
341 }
347 /****************************************************************************/
348 thread_return_t CALLING_CONVENTION queue_test_internal_thread_enqueuer_and_dequeuer( void *queue_test_enqueuing_and_dequeuing_state )
349 {
350 struct queue_test_enqueuing_and_dequeuing_state
351 *qteds;
353 time_t
354 start_time;
356 atom_t
357 thread,
358 count,
359 user_data;
361 assert( queue_test_enqueuing_and_dequeuing_state != NULL );
363 qteds = (struct queue_test_enqueuing_and_dequeuing_state *) queue_test_enqueuing_and_dequeuing_state;
365 time( &start_time );
367 while( time(NULL) < start_time + 10 )
368 {
369 queue_enqueue( qteds->qs, (void *) (qteds->counter++) );
370 queue_dequeue( qteds->qs, (void *) &user_data );
372 thread = user_data >> (sizeof(atom_t)*8-8);
373 count = (user_data << 8) >> 8;
375 if( thread >= qteds->cpu_count )
376 qteds->error_flag = RAISED;
377 else
378 {
379 if( count < qteds->per_thread_counters[thread] )
380 qteds->error_flag = RAISED;
382 if( count >= qteds->per_thread_counters[thread] )
383 qteds->per_thread_counters[thread] = count+1;
384 }
385 }
387 return( (thread_return_t) EXIT_SUCCESS );
388 }
394 /****************************************************************************/
395 void queue_test_rapid_enqueuing_and_dequeuing( void )
396 {
397 unsigned int
398 loop,
399 cpu_count;
401 thread_state_t
402 *thread_handles;
404 struct queue_state
405 *qs;
407 struct queue_test_rapid_enqueuing_and_dequeuing_state
408 *qtreds;
410 struct validation_info
411 vi = { 50000, 50000 };
413 atom_t
414 user_data,
415 thread,
416 count,
417 *per_thread_counters;
419 enum data_structure_validity
420 dvs[2];
422 internal_display_test_name( "Rapid enqueuing and dequeuing (10 seconds)" );
424 cpu_count = abstraction_cpu_count();
426 queue_new( &qs, 100000 );
428 for( loop = 0 ; loop < 50000 ; loop++ )
429 queue_enqueue( qs, NULL );
431 qtreds = malloc( sizeof(struct queue_test_rapid_enqueuing_and_dequeuing_state) * cpu_count );
433 for( loop = 0 ; loop < cpu_count ; loop++ )
434 {
435 (qtreds+loop)->qs = qs;
436 (qtreds+loop)->counter = (atom_t) loop << (sizeof(atom_t)*8-8);
437 }
439 thread_handles = malloc( sizeof(thread_state_t) * cpu_count );
441 for( loop = 0 ; loop < cpu_count ; loop++ )
442 abstraction_thread_start( &thread_handles[loop], loop, queue_test_internal_thread_rapid_enqueuer_and_dequeuer, qtreds+loop );
444 for( loop = 0 ; loop < cpu_count ; loop++ )
445 abstraction_thread_wait( thread_handles[loop] );
447 free( thread_handles );
449 queue_query( qs, QUEUE_QUERY_VALIDATE, (void *) &vi, (void *) dvs );
451 // TRD : now check results
452 per_thread_counters = malloc( sizeof(atom_t) * cpu_count );
454 for( loop = 0 ; loop < cpu_count ; loop++ )
455 *(per_thread_counters+loop) = 0;
457 while( dvs[0] == VALIDITY_VALID and dvs[1] == VALIDITY_VALID and queue_dequeue(qs, (void *) &user_data) )
458 {
459 thread = user_data >> (sizeof(atom_t)*8-8);
460 count = (user_data << 8) >> 8;
462 if( thread >= cpu_count )
463 {
464 dvs[0] = VALIDITY_INVALID_TEST_DATA;
465 break;
466 }
468 if( per_thread_counters[thread] == 0 )
469 per_thread_counters[thread] = count;
471 if( count < per_thread_counters[thread] )
472 dvs[0] = VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
474 if( count >= per_thread_counters[thread] )
475 per_thread_counters[thread] = count+1;
476 }
478 free( per_thread_counters );
480 free( qtreds );
482 queue_delete( qs, NULL, NULL );
484 internal_display_test_result( 2, "queue", dvs[0], "queue freelist", dvs[1] );
486 return;
487 }
493 /****************************************************************************/
494 thread_return_t CALLING_CONVENTION queue_test_internal_thread_rapid_enqueuer_and_dequeuer( void *queue_test_rapid_enqueuing_and_dequeuing_state )
495 {
496 struct queue_test_rapid_enqueuing_and_dequeuing_state
497 *qtreds;
499 time_t
500 start_time;
502 atom_t
503 user_data;
505 assert( queue_test_rapid_enqueuing_and_dequeuing_state != NULL );
507 qtreds = (struct queue_test_rapid_enqueuing_and_dequeuing_state *) queue_test_rapid_enqueuing_and_dequeuing_state;
509 time( &start_time );
511 while( time(NULL) < start_time + 10 )
512 {
513 queue_enqueue( qtreds->qs, (void *) (qtreds->counter++) );
514 queue_dequeue( qtreds->qs, (void *) &user_data );
515 }
517 return( (thread_return_t) EXIT_SUCCESS );
518 }