]> pd.if.org Git - liblfds/blob - liblfds/liblfds7.1.0/test_and_benchmark/libbenchmark/src/libbenchmark_datastructures_btree_au/libbenchmark_datastructure_btree_au_pthread_rwlock.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds7.1.0 / test_and_benchmark / libbenchmark / src / libbenchmark_datastructures_btree_au / libbenchmark_datastructure_btree_au_pthread_rwlock.c
1 /***** includes *****/
2 #include "libbenchmark_datastructure_btree_au_internal.h"
3
4 /***** private prototypes *****/
5 static void libbenchmark_datastructure_btree_au_internal_inorder_walk_from_largest_get_next_smallest_element( struct libbenchmark_datastructure_btree_au_pthread_rwlock_state *baus, struct libbenchmark_datastructure_btree_au_pthread_rwlock_element **baue );
6 static void libbenchmark_datastructure_btree_au_internal_inorder_walk_from_smallest_get_next_largest_element( struct libbenchmark_datastructure_btree_au_pthread_rwlock_state *baus, struct libbenchmark_datastructure_btree_au_pthread_rwlock_element **baue );
7
8
9
10
11
12 /****************************************************************************/
13 void libbenchmark_datastructure_btree_au_pthread_rwlock_init( struct libbenchmark_datastructure_btree_au_pthread_rwlock_state *baus,
14                                                               int (*key_compare_function)(void const *new_key, void const *existing_key),
15                                                               enum libbenchmark_datastructure_btree_au_pthread_rwlock_existing_key existing_key,
16                                                               void *user_state )
17 {
18   LFDS710_PAL_ASSERT( baus != NULL );
19   LFDS710_PAL_ASSERT( key_compare_function != NULL );
20   // TRD : existing_key can be any value in its range
21   // TRD : user_state can be NULL
22
23   baus->root = NULL;
24   baus->key_compare_function = key_compare_function;
25   baus->existing_key = existing_key;
26   baus->user_state = user_state;
27
28   LIBBENCHMARK_PAL_LOCK_PTHREAD_RWLOCK_CREATE( baus->lock );
29
30   LFDS710_MISC_BARRIER_STORE;
31
32   lfds710_misc_force_store();
33
34   return;
35 }
36
37
38
39
40
41 /****************************************************************************/
42 void libbenchmark_datastructure_btree_au_pthread_rwlock_cleanup( struct libbenchmark_datastructure_btree_au_pthread_rwlock_state *baus,
43                                                                  void (*element_cleanup_callback)(struct libbenchmark_datastructure_btree_au_pthread_rwlock_state *baus, struct libbenchmark_datastructure_btree_au_pthread_rwlock_element *baue) )
44 {
45   enum libbenchmark_datastructure_btree_au_delete_action
46     delete_action = LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_DELETE_SELF; // TRD : to remove compiler warning
47
48   struct libbenchmark_datastructure_btree_au_pthread_rwlock_element
49     *baue,
50     *temp;
51
52   LFDS710_PAL_ASSERT( baus != NULL );
53   // TRD : element_delete_function can be NULL
54
55   if( element_cleanup_callback != NULL )
56   {
57     libbenchmark_datastructure_btree_au_pthread_rwlock_get_by_absolute_position_for_read( baus, &baue, LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_ABSOLUTE_POSITION_ROOT );
58
59     while( baue != NULL )
60     {
61       if( baue->left == NULL and baue->right == NULL )
62         delete_action = LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_DELETE_SELF;
63
64       if( baue->left != NULL and baue->right == NULL )
65         delete_action = LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_DELETE_SELF_REPLACE_WITH_LEFT_CHILD;
66
67       if( baue->left == NULL and baue->right != NULL )
68         delete_action = LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_DELETE_SELF_REPLACE_WITH_RIGHT_CHILD;
69
70       if( baue->left != NULL and baue->right != NULL )
71         delete_action = LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_DELETE_MOVE_LEFT;
72
73       switch( delete_action )
74       {
75         case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_DELETE_SELF:
76           // TRD : if we have a parent (we could be root) set his point to us to NULL
77           if( baue->up != NULL )
78           {
79             if( baue->up->left == baue )
80               baue->up->left = NULL;
81             if( baue->up->right == baue )
82               baue->up->right = NULL;
83           }
84
85           temp = baue;
86           libbenchmark_datastructure_btree_au_pthread_rwlock_get_by_relative_position_for_read( baus, &baue, LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_RELATIVE_POSITION_UP );
87           element_cleanup_callback( baus, temp );
88         break;
89
90         case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_DELETE_SELF_REPLACE_WITH_LEFT_CHILD:
91           baue->left->up = baue->up;
92           if( baue->up != NULL )
93           {
94             if( baue->up->left == baue )
95               baue->up->left = baue->left;
96             if( baue->up->right == baue )
97               baue->up->right = baue->left;
98           }
99
100           temp = baue;
101           libbenchmark_datastructure_btree_au_pthread_rwlock_get_by_relative_position_for_read( baus, &baue, LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_RELATIVE_POSITION_LEFT );
102           element_cleanup_callback( baus, temp );
103         break;
104
105         case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_DELETE_SELF_REPLACE_WITH_RIGHT_CHILD:
106           baue->right->up = baue->up;
107           if( baue->up != NULL )
108           {
109             if( baue->up->left == baue )
110               baue->up->left = baue->right;
111             if( baue->up->right == baue )
112               baue->up->right = baue->right;
113           }
114
115           temp = baue;
116           libbenchmark_datastructure_btree_au_pthread_rwlock_get_by_relative_position_for_read( baus, &baue, LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_RELATIVE_POSITION_RIGHT );
117           element_cleanup_callback( baus, temp );
118         break;
119
120         case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_DELETE_MOVE_LEFT:
121           libbenchmark_datastructure_btree_au_pthread_rwlock_get_by_relative_position_for_read( baus, &baue, LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_RELATIVE_POSITION_LEFT );
122         break;
123       }
124     }
125   }
126
127   LIBBENCHMARK_PAL_LOCK_PTHREAD_RWLOCK_DESTROY( baus->lock );
128
129   return;
130 }
131
132
133
134
135
136 /****************************************************************************/
137 enum libbenchmark_datastructure_btree_au_pthread_rwlock_insert_result libbenchmark_datastructure_btree_au_pthread_rwlock_insert( struct libbenchmark_datastructure_btree_au_pthread_rwlock_state *baus,
138                                                                                                                                  struct libbenchmark_datastructure_btree_au_pthread_rwlock_element *baue,
139                                                                                                                                  struct libbenchmark_datastructure_btree_au_pthread_rwlock_element **existing_baue )
140 {
141   int
142     compare_result = 0;
143
144   struct libbenchmark_datastructure_btree_au_pthread_rwlock_element
145     *baue_next = NULL,
146     *baue_parent = NULL,
147     *baue_temp;
148
149   LFDS710_PAL_ASSERT( baus != NULL );
150   LFDS710_PAL_ASSERT( baue != NULL );
151   // TRD : existing_baue can be NULL
152
153   LIBBENCHMARK_PAL_LOCK_PTHREAD_RWLOCK_GET_WRITE( baus->lock );
154
155   baue->up = baue->left = baue->right = NULL;
156
157   baue_temp = baus->root;
158
159   while( baue_temp != NULL )
160   {
161     compare_result = baus->key_compare_function( baue->key, baue_temp->key );
162
163     if( compare_result == 0 )
164     {
165       if( existing_baue != NULL )
166         *existing_baue = baue_temp;
167
168       switch( baus->existing_key )
169       {
170         case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_EXISTING_KEY_OVERWRITE:
171           LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_SET_VALUE_IN_ELEMENT( *baus, *baue_temp, baue->value );
172           return LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_INSERT_RESULT_SUCCESS_OVERWRITE;
173         break;
174
175         case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_EXISTING_KEY_FAIL:
176           return LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_INSERT_RESULT_FAILURE_EXISTING_KEY;
177         break;
178       }
179     }
180
181     if( compare_result < 0 )
182       baue_next = baue_temp->left;
183
184     if( compare_result > 0 )
185       baue_next = baue_temp->right;
186
187     baue_parent = baue_temp;
188     baue_temp = baue_next;
189   }
190
191   if( baue_parent == NULL )
192   {
193     baue->up = baus->root;
194     baus->root = baue;  }
195
196   if( baue_parent != NULL )
197   {
198     if( compare_result <= 0 )
199     {
200       baue->up = baue_parent;
201       baue_parent->left = baue;
202     }
203
204     if( compare_result > 0 )
205     {
206       baue->up = baue_parent;
207       baue_parent->right = baue;
208     }
209   }
210
211   LIBBENCHMARK_PAL_LOCK_PTHREAD_RWLOCK_RELEASE( baus->lock );
212
213   // TRD : if we get to here, we added (not failed or overwrite on exist) a new element
214   if( existing_baue != NULL )
215     *existing_baue = NULL;
216
217   return LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_INSERT_RESULT_SUCCESS;
218 }
219
220
221
222
223
224 /****************************************************************************/
225 int libbenchmark_datastructure_btree_au_pthread_rwlock_get_by_key_for_read( struct libbenchmark_datastructure_btree_au_pthread_rwlock_state *baus,
226                                                                             int (*key_compare_function)(void const *new_key, void const *existing_key),
227                                                                             void *key,
228                                                                             struct libbenchmark_datastructure_btree_au_pthread_rwlock_element **baue )
229 {
230   int
231     compare_result = !0,
232     rv = 1;
233
234   LFDS710_PAL_ASSERT( baus != NULL );
235   // TRD : key_compare_function can be NULL
236   // TRD : key can be NULL
237   LFDS710_PAL_ASSERT( baue != NULL );
238
239   if( key_compare_function == NULL )
240     key_compare_function = baus->key_compare_function;
241
242   LIBBENCHMARK_PAL_LOCK_PTHREAD_RWLOCK_GET_READ( baus->lock );
243
244   *baue = baus->root;
245
246   while( *baue != NULL and compare_result != 0 )
247   {
248     compare_result = key_compare_function( key, (*baue)->key );
249
250     if( compare_result < 0 )
251       *baue = (*baue)->left;
252
253     if( compare_result > 0 )
254       *baue = (*baue)->right;
255   }
256
257   LIBBENCHMARK_PAL_LOCK_PTHREAD_RWLOCK_RELEASE( baus->lock );
258
259   if( *baue == NULL )
260     rv = 0;
261
262   return rv;
263 }
264
265
266
267
268
269 /****************************************************************************/
270 int libbenchmark_datastructure_btree_au_pthread_rwlock_get_by_key_for_write( struct libbenchmark_datastructure_btree_au_pthread_rwlock_state *baus,
271                                                                              int (*key_compare_function)(void const *new_key, void const *existing_key),
272                                                                              void *key,
273                                                                              struct libbenchmark_datastructure_btree_au_pthread_rwlock_element **baue )
274 {
275   int
276     compare_result = !0,
277     rv = 1;
278
279   LFDS710_PAL_ASSERT( baus != NULL );
280   // TRD : key_compare_function can be NULL
281   // TRD : key can be NULL
282   LFDS710_PAL_ASSERT( baue != NULL );
283
284   if( key_compare_function == NULL )
285     key_compare_function = baus->key_compare_function;
286
287   LIBBENCHMARK_PAL_LOCK_PTHREAD_RWLOCK_GET_WRITE( baus->lock );
288
289   *baue = baus->root;
290
291   while( *baue != NULL and compare_result != 0 )
292   {
293     compare_result = key_compare_function( key, (*baue)->key );
294
295     if( compare_result < 0 )
296       *baue = (*baue)->left;
297
298     if( compare_result > 0 )
299       *baue = (*baue)->right;
300   }
301
302   LIBBENCHMARK_PAL_LOCK_PTHREAD_RWLOCK_RELEASE( baus->lock );
303
304   if( *baue == NULL )
305     rv = 0;
306
307   return rv;
308 }
309
310
311
312
313
314 /****************************************************************************/
315 int libbenchmark_datastructure_btree_au_pthread_rwlock_get_by_absolute_position_for_read( struct libbenchmark_datastructure_btree_au_pthread_rwlock_state *baus, struct libbenchmark_datastructure_btree_au_pthread_rwlock_element **baue, enum libbenchmark_datastructure_btree_au_pthread_rwlock_absolute_position absolute_position )
316 {
317   int
318     rv = 1;
319
320   LFDS710_PAL_ASSERT( baus != NULL );
321   LFDS710_PAL_ASSERT( baue != NULL );
322   // TRD : absolute_position can be any value in its range
323
324   LIBBENCHMARK_PAL_LOCK_PTHREAD_RWLOCK_GET_READ( baus->lock );
325
326   *baue = baus->root;
327
328   switch( absolute_position )
329   {
330     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_ABSOLUTE_POSITION_ROOT:
331     break;
332
333     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_ABSOLUTE_POSITION_LARGEST_IN_TREE:
334       if( *baue != NULL )
335         while( (*baue)->right != NULL )
336           *baue = (*baue)->right;
337     break;
338
339     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_ABSOLUTE_POSITION_SMALLEST_IN_TREE:
340       if( *baue != NULL )
341         while( (*baue)->left != NULL )
342           *baue = (*baue)->left;
343     break;
344   }
345
346   LIBBENCHMARK_PAL_LOCK_PTHREAD_RWLOCK_RELEASE( baus->lock );
347
348   if( *baue == NULL )
349     rv = 0;
350
351   return rv;
352 }
353
354
355
356
357
358 /****************************************************************************/
359 int libbenchmark_datastructure_btree_au_pthread_rwlock_get_by_relative_position_for_read( struct libbenchmark_datastructure_btree_au_pthread_rwlock_state *baus, struct libbenchmark_datastructure_btree_au_pthread_rwlock_element **baue, enum libbenchmark_datastructure_btree_au_pthread_rwlock_relative_position relative_position )
360 {
361   int
362     rv = 1;
363
364   LFDS710_PAL_ASSERT( baus != NULL );
365   LFDS710_PAL_ASSERT( baue != NULL );
366   // TRD : relative_position can baue any value in its range
367
368   if( *baue == NULL )
369     return 0;
370
371   LIBBENCHMARK_PAL_LOCK_PTHREAD_RWLOCK_GET_READ( baus->lock );
372
373   switch( relative_position )
374   {
375     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_RELATIVE_POSITION_UP:
376       *baue = (*baue)->up;
377     break;
378
379     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_RELATIVE_POSITION_LEFT:
380       *baue = (*baue)->left;
381     break;
382
383     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_RELATIVE_POSITION_RIGHT:
384       *baue = (*baue)->right;
385     break;
386
387     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_RELATIVE_POSITION_SMALLEST_ELEMENT_BELOW_CURRENT_ELEMENT:
388       *baue = (*baue)->left;
389       if( *baue != NULL )
390         while( (*baue)->right != NULL )
391           *baue = (*baue)->right;
392     break;
393
394     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_RELATIVE_POSITION_LARGEST_ELEMENT_BELOW_CURRENT_ELEMENT:
395       *baue = (*baue)->right;
396       if( *baue != NULL )
397         while( (*baue)->left != NULL )
398           *baue = (*baue)->left;
399     break;
400
401     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_RELATIVE_POSITION_NEXT_SMALLER_ELEMENT_IN_ENTIRE_TREE:
402       libbenchmark_datastructure_btree_au_internal_inorder_walk_from_largest_get_next_smallest_element( baus, baue );
403     break;
404
405     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_PTHREAD_RWLOCK_RELATIVE_POSITION_NEXT_LARGER_ELEMENT_IN_ENTIRE_TREE:
406       libbenchmark_datastructure_btree_au_internal_inorder_walk_from_smallest_get_next_largest_element( baus, baue );
407     break;
408   }
409
410   LIBBENCHMARK_PAL_LOCK_PTHREAD_RWLOCK_RELEASE( baus->lock );
411
412   if( *baue == NULL )
413     rv = 0;
414
415   return rv;
416 }
417
418
419
420
421
422 /****************************************************************************/
423 #pragma warning( disable : 4100 )
424
425 static void libbenchmark_datastructure_btree_au_internal_inorder_walk_from_largest_get_next_smallest_element( struct libbenchmark_datastructure_btree_au_pthread_rwlock_state *baus, struct libbenchmark_datastructure_btree_au_pthread_rwlock_element **baue )
426 {
427   enum libbenchmark_datastructure_btree_au_move
428     action = LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_INVALID;
429
430   enum flag
431     finished_flag = LOWERED;
432
433   struct libbenchmark_datastructure_btree_au_pthread_rwlock_element
434     *left = NULL,
435     *up = NULL,
436     *up_left = NULL,
437     *up_right = NULL;
438
439   LFDS710_PAL_ASSERT( baus != NULL );
440   LFDS710_PAL_ASSERT( baue != NULL );
441
442   /* TRD : from any given element, the next smallest element is;
443            1. if we have a left, it's the largest element on the right branch of our left child
444            2. if we don't have a left, and we're on the right of our parent, then it's our parent
445            3. if we don't have a left, and we're on the left of our parent or we have no parent,
446               iterative up the tree until we find the first child who is on the right of its parent; then it's the parent
447   */
448
449   left = (*baue)->left;
450   up = (*baue)->up;
451   if( up != NULL )
452   {
453     up_left = (*baue)->up->left;
454     up_right = (*baue)->up->right;
455   }
456
457   if( left != NULL )
458     action = LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_LARGEST_FROM_LEFT_CHILD;
459
460   if( left == NULL and up != NULL and up_right == *baue )
461     action = LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_GET_PARENT;
462
463   if( (left == NULL and up == NULL) or (up != NULL and up_left == *baue and left == NULL) )
464     action = LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_MOVE_UP_TREE;
465
466   switch( action )
467   {
468     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_INVALID:
469     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_SMALLEST_FROM_RIGHT_CHILD:
470       // TRD : eliminates a compiler warning
471     break;
472
473     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_LARGEST_FROM_LEFT_CHILD:
474       *baue = left;
475       if( *baue != NULL )
476         while( (*baue)->right != NULL )
477           *baue = (*baue)->right;
478     break;
479
480     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_GET_PARENT:
481       *baue = up;
482     break;
483
484     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_MOVE_UP_TREE:
485       while( finished_flag == LOWERED )
486       {
487         up = (*baue)->up;
488         if( up != NULL )
489           up_left = (*baue)->up->left;
490
491         if( *baue != NULL and up != NULL and *baue == up_left )
492           *baue = up;
493         else
494           finished_flag = RAISED;
495       }
496
497       *baue = up;
498     break;
499   }
500
501   return;
502 }
503
504 #pragma warning( default : 4100 )
505
506
507
508
509
510 /****************************************************************************/
511 #pragma warning( disable : 4100 )
512
513 static void libbenchmark_datastructure_btree_au_internal_inorder_walk_from_smallest_get_next_largest_element( struct libbenchmark_datastructure_btree_au_pthread_rwlock_state *baus, struct libbenchmark_datastructure_btree_au_pthread_rwlock_element **baue )
514 {
515   enum libbenchmark_datastructure_btree_au_move
516     action = LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_INVALID;
517
518   enum flag
519     finished_flag = LOWERED;
520
521   struct libbenchmark_datastructure_btree_au_pthread_rwlock_element
522     *right = NULL,
523     *up = NULL,
524     *up_left = NULL,
525     *up_right = NULL;
526
527   LFDS710_PAL_ASSERT( baus != NULL );
528   LFDS710_PAL_ASSERT( baue != NULL );
529
530   right = (*baue)->right;
531   up = (*baue)->up;
532   if( up != NULL )
533   {
534     up_left = (*baue)->up->left;
535     up_right = (*baue)->up->right;
536   }
537
538   if( right != NULL )
539     action = LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_SMALLEST_FROM_RIGHT_CHILD;
540
541   if( right == NULL and up != NULL and up_left == *baue )
542     action = LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_GET_PARENT;
543
544   if( (right == NULL and up == NULL) or (up != NULL and up_right == *baue and right == NULL) )
545     action = LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_MOVE_UP_TREE;
546
547   switch( action )
548   {
549     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_INVALID:
550     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_LARGEST_FROM_LEFT_CHILD:
551       // TRD : remove compiler warning
552     break;
553
554     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_SMALLEST_FROM_RIGHT_CHILD:
555       *baue = right;
556       if( *baue != NULL )
557         while( (*baue)->left != NULL )
558           *baue = (*baue)->left;
559     break;
560
561     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_GET_PARENT:
562       *baue = up;
563     break;
564
565     case LIBBENCHMARK_DATASTRUCTURE_BTREE_AU_MOVE_MOVE_UP_TREE:
566       while( finished_flag == LOWERED )
567       {
568         up = (*baue)->up;
569         if( up != NULL )
570           up_right = (*baue)->up->right;
571
572         if( *baue != NULL and up != NULL and *baue == up_right )
573           *baue = up;
574         else
575           finished_flag = RAISED;
576       }
577
578       *baue = up;
579     break;
580   }
581
582   return;
583 }
584
585 #pragma warning( default : 4100 )
586
587
588
589
590
591 /****************************************************************************/
592 int libbenchmark_datastructure_btree_au_pthread_rwlock_get_by_absolute_position_and_then_by_relative_position( struct libbenchmark_datastructure_btree_au_pthread_rwlock_state *baus, struct libbenchmark_datastructure_btree_au_pthread_rwlock_element **baue, enum libbenchmark_datastructure_btree_au_pthread_rwlock_absolute_position absolute_position, enum libbenchmark_datastructure_btree_au_pthread_rwlock_relative_position relative_position )
593 {
594   int
595     rv;
596
597   LFDS710_PAL_ASSERT( baus != NULL );
598   LFDS710_PAL_ASSERT( baue != NULL );
599   // TRD: absolute_position can be any value in its range
600   // TRD: relative_position can be any value in its range
601
602   if( *baue == NULL )
603     rv = libbenchmark_datastructure_btree_au_pthread_rwlock_get_by_absolute_position_for_read( baus, baue, absolute_position );
604   else
605     rv = libbenchmark_datastructure_btree_au_pthread_rwlock_get_by_relative_position_for_read( baus, baue, relative_position );
606
607   return rv;
608 }
609