source: rtems/testsuites/tmtests/tm26/task1.c @ 5611839

4.115
Last change on this file since 5611839 was 5611839, checked in by Sebastian Huber <sebastian.huber@…>, on 05/29/15 at 12:18:32

tmtests/tm26: Avoid NULL pointer access

  • Property mode set to 100644
File size: 17.3 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2013.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.org/license/LICENSE.
8 */
9
10#ifdef HAVE_CONFIG_H
11#include "config.h"
12#endif
13
14#define CONFIGURE_INIT
15#include <rtems.h>
16#include "system.h"
17#include "fptest.h"
18#include <coverhd.h>
19#include <tmacros.h>
20#include <timesys.h>
21
22#include <rtems/score/schedulerpriorityimpl.h>
23#include <rtems/rtems/semimpl.h>
24
25#if defined( RTEMS_SMP ) && defined( RTEMS_DEBUG )
26  #define PREVENT_SMP_ASSERT_FAILURES
27#endif
28
29const char rtems_test_name[] = "TIME TEST 26";
30
31/* TEST DATA */
32rtems_id Semaphore_id;
33
34Objects_Locations location;   /* uses internal RTEMS type */
35
36Thread_Control *Middle_tcb;   /* uses internal RTEMS type */
37
38Thread_Control *Low_tcb;      /* uses internal RTEMS type */
39
40/*
41 *  Variables to hold execution times until they are printed
42 *  at the end of the test.
43 */
44
45uint32_t   isr_disable_time;
46uint32_t   isr_flash_time;
47uint32_t   isr_enable_time;
48uint32_t   thread_disable_dispatch_time;
49uint32_t   thread_enable_dispatch_time;
50uint32_t   thread_set_state_time;
51uint32_t   thread_dispatch_no_fp_time;
52uint32_t   context_switch_no_fp_time;
53uint32_t   context_switch_self_time;
54uint32_t   context_switch_another_task_time;
55uint32_t   context_switch_restore_1st_fp_time;
56uint32_t   context_switch_save_idle_restore_initted_time;
57uint32_t   context_switch_save_restore_idle_time;
58uint32_t   context_switch_save_restore_initted_time;
59uint32_t   thread_resume_time;
60uint32_t   thread_unblock_time;
61uint32_t   thread_ready_time;
62uint32_t   thread_get_time;
63uint32_t   semaphore_get_time;
64uint32_t   thread_get_invalid_time;
65
66rtems_task null_task(
67  rtems_task_argument argument
68);
69
70rtems_task High_task(
71  rtems_task_argument argument
72);
73
74rtems_task Middle_task(
75  rtems_task_argument argument
76);
77
78rtems_task Low_task(
79  rtems_task_argument argument
80);
81
82rtems_task Floating_point_task_1(
83  rtems_task_argument argument
84);
85
86rtems_task Floating_point_task_2(
87  rtems_task_argument argument
88);
89
90void complete_test( void );
91
92static void set_thread_dispatch_necessary( bool dispatch_necessary )
93{
94#if defined( PREVENT_SMP_ASSERT_FAILURES )
95  ISR_Level level;
96
97  _ISR_Disable_without_giant( level );
98#endif
99
100  _Thread_Dispatch_necessary = dispatch_necessary;
101
102  if ( !dispatch_necessary ) {
103    _Thread_Heir = _Thread_Executing;
104  }
105
106#if defined( PREVENT_SMP_ASSERT_FAILURES )
107  _ISR_Enable_without_giant( level );
108#endif
109}
110
111static void set_thread_heir( Thread_Control *thread )
112{
113#if defined( PREVENT_SMP_ASSERT_FAILURES )
114  ISR_Level level;
115
116  _ISR_Disable_without_giant( level );
117#endif
118
119  _Thread_Heir = thread;
120
121#if defined( PREVENT_SMP_ASSERT_FAILURES )
122  _ISR_Enable_without_giant( level );
123#endif
124}
125
126static void set_thread_executing( Thread_Control *thread )
127{
128#if defined( PREVENT_SMP_ASSERT_FAILURES )
129  ISR_Level level;
130
131  _ISR_Disable_without_giant( level );
132#endif
133
134  _Thread_Executing = thread;
135
136#if defined( PREVENT_SMP_ASSERT_FAILURES )
137  _ISR_Enable_without_giant( level );
138#endif
139}
140
141static void thread_disable_dispatch( void )
142{
143/* Yes, RTEMS_SMP and not PREVENT_SMP_ASSERT_FAILURES */
144#if defined( RTEMS_SMP )
145  Per_CPU_Control *self_cpu;
146  ISR_Level level;
147
148  _ISR_Disable_without_giant( level );
149  ( void ) level;
150
151  self_cpu = _Per_CPU_Get();
152  self_cpu->thread_dispatch_disable_level = 1;
153#else
154  _Thread_Disable_dispatch();
155#endif
156}
157
158static void thread_set_state( Thread_Control *thread, States_Control state )
159{
160#if defined( PREVENT_SMP_ASSERT_FAILURES )
161  _Thread_Disable_dispatch();
162#endif
163
164  _Thread_Set_state( thread, state );
165
166#if defined( PREVENT_SMP_ASSERT_FAILURES )
167  _Thread_Unnest_dispatch();
168#endif
169}
170
171static void thread_resume( Thread_Control *thread )
172{
173#if defined( PREVENT_SMP_ASSERT_FAILURES )
174  _Thread_Disable_dispatch();
175#endif
176
177  _Thread_Clear_state( thread, STATES_SUSPENDED );
178
179#if defined( PREVENT_SMP_ASSERT_FAILURES )
180  _Thread_Unnest_dispatch();
181#endif
182}
183
184static void thread_unblock( Thread_Control *thread )
185{
186#if defined( PREVENT_SMP_ASSERT_FAILURES )
187  _Thread_Disable_dispatch();
188#endif
189
190  _Thread_Unblock( thread );
191
192#if defined( PREVENT_SMP_ASSERT_FAILURES )
193  _Thread_Unnest_dispatch();
194#endif
195}
196
197static void thread_ready( Thread_Control *thread )
198{
199#if defined( PREVENT_SMP_ASSERT_FAILURES )
200  _Thread_Disable_dispatch();
201#endif
202
203  _Thread_Ready( thread );
204
205#if defined( PREVENT_SMP_ASSERT_FAILURES )
206  _Thread_Unnest_dispatch();
207#endif
208}
209
210rtems_task null_task(
211  rtems_task_argument argument
212)
213{
214}
215
216rtems_task Init(
217  rtems_task_argument argument
218)
219{
220  uint32_t    index;
221  rtems_id          task_id;
222  rtems_status_code status;
223
224  Print_Warning();
225
226  TEST_BEGIN();
227
228  if (
229    _Scheduler_Table[ 0 ].Operations.initialize
230      != _Scheduler_priority_Initialize
231  ) {
232    puts("  Error ==> " );
233    puts("Test only supported for deterministic priority scheduler\n" );
234    TEST_END();
235    rtems_test_exit( 0 );
236  }
237
238#define FP1_PRIORITY (RTEMS_MAXIMUM_PRIORITY - 3u)      /* 201, */
239  status = rtems_task_create(
240    rtems_build_name( 'F', 'P', '1', ' ' ),
241    FP1_PRIORITY,
242    RTEMS_MINIMUM_STACK_SIZE,
243    RTEMS_DEFAULT_MODES,
244    RTEMS_FLOATING_POINT,
245    &task_id
246  );
247  directive_failed( status, "rtems_task_create of FP1" );
248
249  status = rtems_task_start( task_id, Floating_point_task_1, 0 );
250  directive_failed( status, "rtems_task_start of FP1" );
251
252#define FP2_PRIORITY (RTEMS_MAXIMUM_PRIORITY - 2u)      /* 202, */
253  status = rtems_task_create(
254    rtems_build_name( 'F', 'P', '2', ' ' ),
255    FP2_PRIORITY,
256    RTEMS_MINIMUM_STACK_SIZE,
257    RTEMS_DEFAULT_MODES,
258    RTEMS_FLOATING_POINT,
259    &task_id
260  );
261  directive_failed( status, "rtems_task_create of FP2" );
262
263  status = rtems_task_start( task_id, Floating_point_task_2, 0 );
264  directive_failed( status, "rtems_task_start of FP2" );
265
266#define LOW_PRIORITY (RTEMS_MAXIMUM_PRIORITY - 4u)   /*  200, */
267  status = rtems_task_create(
268    rtems_build_name( 'L', 'O', 'W', ' ' ),
269    LOW_PRIORITY,
270    RTEMS_MINIMUM_STACK_SIZE,
271    RTEMS_DEFAULT_MODES,
272    RTEMS_DEFAULT_ATTRIBUTES,
273    &task_id
274  );
275  directive_failed( status, "rtems_task_create of LOW" );
276
277  status = rtems_task_start( task_id, Low_task, 0 );
278  directive_failed( status, "rtems_task_start of LOW" );
279
280#define MIDDLE_PRIORITY (RTEMS_MAXIMUM_PRIORITY - 5u)   /*  128, */
281  status = rtems_task_create(
282    rtems_build_name( 'M', 'I', 'D', ' ' ),
283    MIDDLE_PRIORITY,
284    RTEMS_MINIMUM_STACK_SIZE,
285    RTEMS_DEFAULT_MODES,
286    RTEMS_DEFAULT_ATTRIBUTES,
287    &task_id
288  );
289  directive_failed( status, "rtems_task_create of MIDDLE" );
290
291  status = rtems_task_start( task_id, Middle_task, 0 );
292  directive_failed( status, "rtems_task_start of MIDDLE" );
293
294  status = rtems_task_create(
295    rtems_build_name( 'H', 'I', 'G', 'H' ),
296    5,
297    RTEMS_MINIMUM_STACK_SIZE,
298    RTEMS_DEFAULT_MODES,
299    RTEMS_DEFAULT_ATTRIBUTES,
300    &task_id
301  );
302  directive_failed( status, "rtems_task_create of HIGH" );
303
304  status = rtems_task_start( task_id, High_task, 0 );
305  directive_failed( status, "rtems_task_start of HIGH" );
306
307  status = rtems_semaphore_create(
308    rtems_build_name( 'S', 'E', 'M', '1' ),
309    OPERATION_COUNT,
310    RTEMS_DEFAULT_ATTRIBUTES,
311    RTEMS_NO_PRIORITY,
312    &Semaphore_id
313  );
314  directive_failed( status, "rtems_semaphore_create" );
315
316  for ( index = 1 ; index <= OPERATION_COUNT ; index++ ) {
317    status = rtems_task_create(
318      rtems_build_name( 'N', 'U', 'L', 'L' ),
319      RTEMS_MAXIMUM_PRIORITY - 1u,      /* 254, */
320      RTEMS_MINIMUM_STACK_SIZE,
321      RTEMS_DEFAULT_MODES,
322      RTEMS_DEFAULT_ATTRIBUTES,
323      &task_id
324    );
325    directive_failed( status, "rtems_task_create LOOP" );
326
327    status = rtems_task_start( task_id, null_task, 0 );
328    directive_failed( status, "rtems_task_start LOOP" );
329  }
330
331  status = rtems_task_delete( RTEMS_SELF );
332  directive_failed( status, "rtems_task_delete of RTEMS_SELF" );
333}
334
335rtems_task High_task(
336  rtems_task_argument argument
337)
338{
339  rtems_interrupt_level level;
340
341  _Thread_Disable_dispatch();
342
343  benchmark_timer_initialize();
344    rtems_interrupt_disable( level );
345  isr_disable_time = benchmark_timer_read();
346
347  benchmark_timer_initialize();
348    rtems_interrupt_flash( level );
349  isr_flash_time = benchmark_timer_read();
350
351  benchmark_timer_initialize();
352    rtems_interrupt_enable( level );
353  isr_enable_time = benchmark_timer_read();
354
355  _Thread_Enable_dispatch();
356
357  benchmark_timer_initialize();
358    _Thread_Disable_dispatch();
359  thread_disable_dispatch_time = benchmark_timer_read();
360
361  benchmark_timer_initialize();
362    _Thread_Enable_dispatch();
363  thread_enable_dispatch_time = benchmark_timer_read();
364
365  benchmark_timer_initialize();
366    thread_set_state( _Thread_Get_executing(), STATES_SUSPENDED );
367  thread_set_state_time = benchmark_timer_read();
368
369  set_thread_dispatch_necessary( true );
370
371  benchmark_timer_initialize();
372    _Thread_Dispatch();           /* dispatches Middle_task */
373}
374
375rtems_task Middle_task(
376  rtems_task_argument argument
377)
378{
379  Scheduler_priority_Context *scheduler_context =
380    _Scheduler_priority_Get_context( _Scheduler_Get( _Thread_Get_executing() ) );
381
382  thread_dispatch_no_fp_time = benchmark_timer_read();
383
384  thread_set_state( _Thread_Get_executing(), STATES_SUSPENDED );
385
386  Middle_tcb   = _Thread_Get_executing();
387
388  set_thread_executing(
389    (Thread_Control *) _Chain_First(&scheduler_context->Ready[LOW_PRIORITY])
390  );
391
392  /* do not force context switch */
393
394  set_thread_dispatch_necessary( false );
395
396  thread_disable_dispatch();
397
398  benchmark_timer_initialize();
399    _Context_Switch(
400      &Middle_tcb->Registers,
401      &_Thread_Get_executing()->Registers
402    );
403
404  benchmark_timer_initialize();
405    _Context_Switch(&Middle_tcb->Registers, &Low_tcb->Registers);
406}
407
408rtems_task Low_task(
409  rtems_task_argument argument
410)
411{
412  Scheduler_priority_Context *scheduler_context =
413    _Scheduler_priority_Get_context( _Scheduler_Get( _Thread_Get_executing() ) );
414  Thread_Control             *executing;
415
416  context_switch_no_fp_time = benchmark_timer_read();
417
418  executing    = _Thread_Get_executing();
419
420  Low_tcb = executing;
421
422  benchmark_timer_initialize();
423    _Context_Switch( &executing->Registers, &executing->Registers );
424
425  context_switch_self_time = benchmark_timer_read();
426
427  _Context_Switch(&executing->Registers, &Middle_tcb->Registers);
428
429  context_switch_another_task_time = benchmark_timer_read();
430
431  set_thread_executing(
432    (Thread_Control *) _Chain_First(&scheduler_context->Ready[FP1_PRIORITY])
433  );
434
435  /* do not force context switch */
436
437  set_thread_dispatch_necessary( false );
438
439  thread_disable_dispatch();
440
441  benchmark_timer_initialize();
442    _Context_Switch(
443      &executing->Registers,
444      &_Thread_Get_executing()->Registers
445    );
446}
447
448rtems_task Floating_point_task_1(
449  rtems_task_argument argument
450)
451{
452  Scheduler_priority_Context *scheduler_context =
453    _Scheduler_priority_Get_context( _Scheduler_Get( _Thread_Get_executing() ) );
454  Thread_Control             *executing;
455  FP_DECLARE;
456
457  context_switch_restore_1st_fp_time = benchmark_timer_read();
458
459  executing = _Thread_Get_executing();
460
461  set_thread_executing(
462    (Thread_Control *) _Chain_First(&scheduler_context->Ready[FP2_PRIORITY])
463  );
464
465  /* do not force context switch */
466
467  set_thread_dispatch_necessary( false );
468
469  thread_disable_dispatch();
470
471  benchmark_timer_initialize();
472#if (CPU_HARDWARE_FP == 1) || (CPU_SOFTWARE_FP == 1)
473    _Context_Save_fp( &executing->fp_context );
474    _Context_Restore_fp( &_Thread_Get_executing()->fp_context );
475#endif
476    _Context_Switch(
477      &executing->Registers,
478      &_Thread_Get_executing()->Registers
479    );
480  /* switch to Floating_point_task_2 */
481
482  context_switch_save_idle_restore_initted_time = benchmark_timer_read();
483
484  FP_LOAD( 1.0 );
485
486  executing = _Thread_Get_executing();
487
488  set_thread_executing(
489    (Thread_Control *) _Chain_First(&scheduler_context->Ready[FP2_PRIORITY])
490  );
491
492  benchmark_timer_initialize();
493#if (CPU_HARDWARE_FP == 1) || (CPU_SOFTWARE_FP == 1)
494    _Context_Save_fp( &executing->fp_context );
495    _Context_Restore_fp( &_Thread_Get_executing()->fp_context );
496#endif
497    _Context_Switch(
498      &executing->Registers,
499      &_Thread_Get_executing()->Registers
500    );
501  /* switch to Floating_point_task_2 */
502}
503
504rtems_task Floating_point_task_2(
505  rtems_task_argument argument
506)
507{
508  Scheduler_priority_Context *scheduler_context =
509    _Scheduler_priority_Get_context( _Scheduler_Get( _Thread_Get_executing() ) );
510  Thread_Control             *executing;
511  FP_DECLARE;
512
513  context_switch_save_restore_idle_time = benchmark_timer_read();
514
515  executing = _Thread_Get_executing();
516
517  set_thread_executing(
518    (Thread_Control *) _Chain_First(&scheduler_context->Ready[FP1_PRIORITY])
519  );
520
521  FP_LOAD( 1.0 );
522
523  benchmark_timer_initialize();
524#if (CPU_HARDWARE_FP == 1) || (CPU_SOFTWARE_FP == 1)
525    _Context_Save_fp( &executing->fp_context );
526    _Context_Restore_fp( &_Thread_Get_executing()->fp_context );
527#endif
528    _Context_Switch(
529      &executing->Registers,
530      &_Thread_Get_executing()->Registers
531    );
532  /* switch to Floating_point_task_1 */
533
534  context_switch_save_restore_initted_time = benchmark_timer_read();
535
536  complete_test();
537}
538
539void complete_test( void )
540{
541  uint32_t    index;
542  rtems_id          task_id;
543
544  benchmark_timer_initialize();
545    thread_resume( Middle_tcb );
546  thread_resume_time = benchmark_timer_read();
547
548  thread_set_state( Middle_tcb, STATES_WAITING_FOR_MESSAGE );
549
550  benchmark_timer_initialize();
551    thread_unblock( Middle_tcb );
552  thread_unblock_time = benchmark_timer_read();
553
554  thread_set_state( Middle_tcb, STATES_WAITING_FOR_MESSAGE );
555
556  benchmark_timer_initialize();
557    thread_ready( Middle_tcb );
558  thread_ready_time = benchmark_timer_read();
559
560  benchmark_timer_initialize();
561    for ( index=1 ; index <= OPERATION_COUNT ; index++ )
562      (void) benchmark_timer_empty_function();
563  overhead = benchmark_timer_read();
564
565  task_id = Middle_tcb->Object.id;
566
567  benchmark_timer_initialize();
568    for ( index=1 ; index <= OPERATION_COUNT ; index++ )
569      (void) _Thread_Get( task_id, &location );
570  thread_get_time = benchmark_timer_read();
571
572  benchmark_timer_initialize();
573    for ( index=1 ; index <= OPERATION_COUNT ; index++ )
574      (void) _Semaphore_Get( Semaphore_id, &location );
575  semaphore_get_time = benchmark_timer_read();
576
577  benchmark_timer_initialize();
578    for ( index=1 ; index <= OPERATION_COUNT ; index++ )
579      (void) _Thread_Get( 0x3, &location );
580  thread_get_invalid_time = benchmark_timer_read();
581
582  /*
583   *  This is the running task and we have tricked RTEMS out enough where
584   *  we need to set some internal tracking information to match this.
585   */
586
587  set_thread_heir( _Thread_Get_executing() );
588  set_thread_dispatch_necessary( false );
589
590  for (index = 0; index < 2 * OPERATION_COUNT; ++index) {
591    _Thread_Unnest_dispatch();
592  }
593
594  /*
595   *  Now dump all the times
596   */
597
598  put_time(
599    "rtems interrupt: _ISR_Disable",
600    isr_disable_time,
601    1,
602    0,
603    0
604  );
605
606  put_time(
607    "rtems interrupt: _ISR_Flash",
608    isr_flash_time,
609    1,
610    0,
611    0
612  );
613
614  put_time(
615    "rtems interrupt: _ISR_Enable",
616    isr_enable_time,
617    1,
618    0,
619    0
620  );
621
622  put_time(
623    "rtems internal: _Thread_Disable_dispatch",
624    thread_disable_dispatch_time,
625    1,
626    0,
627    0
628  );
629
630  put_time(
631    "rtems internal: _Thread_Enable_dispatch",
632    thread_enable_dispatch_time,
633    1,
634    0,
635    0
636  );
637
638  put_time(
639    "rtems internal: _Thread_Set_state",
640    thread_set_state_time,
641    1,
642    0,
643    0
644  );
645
646  put_time(
647    "rtems internal: _Thread_Dispatch NO FP",
648    thread_dispatch_no_fp_time,
649    1,
650    0,
651    0
652  );
653
654  put_time(
655    "rtems internal: context switch: no floating point contexts",
656    context_switch_no_fp_time,
657    1,
658    0,
659    0
660  );
661
662  put_time(
663    "rtems internal: context switch: self",
664    context_switch_self_time,
665    1,
666    0,
667    0
668  );
669
670  put_time(
671    "rtems internal: context switch to another task",
672    context_switch_another_task_time,
673    1,
674    0,
675    0
676  );
677
678#if (CPU_HARDWARE_FP == 1) || (CPU_SOFTWARE_FP == 1)
679  put_time(
680    "rtems internal: fp context switch restore 1st FP task",
681    context_switch_restore_1st_fp_time,
682    1,
683    0,
684    0
685  );
686
687  put_time(
688    "rtems internal: fp context switch save idle and restore initialized",
689    context_switch_save_idle_restore_initted_time,
690    1,
691    0,
692    0
693  );
694
695  put_time(
696    "rtems internal: fp context switch save idle, restore idle",
697    context_switch_save_restore_idle_time,
698    1,
699    0,
700    0
701  );
702
703  put_time(
704    "rtems internal: fp context switch save initialized, restore initialized",
705    context_switch_save_restore_initted_time,
706    1,
707    0,
708    0
709  );
710#else
711    puts(
712     "rtems internal: fp context switch restore 1st FP task - NA\n"
713     "rtems internal: fp context switch save idle restore initialized - NA\n"
714     "rtems internal: fp context switch save idle restore idle - NA\n"
715     "rtems internal: fp context switch save initialized\n"
716                      " restore initialized - NA"
717   );
718#endif
719
720  put_time(
721    "rtems internal: _Thread_Resume",
722    thread_resume_time,
723    1,
724    0,
725    0
726  );
727
728  put_time(
729    "rtems internal: _Thread_Unblock",
730    thread_unblock_time,
731    1,
732    0,
733    0
734  );
735
736  put_time(
737    "rtems internal: _Thread_Ready",
738    thread_ready_time,
739    1,
740    0,
741    0
742  );
743
744  put_time(
745    "rtems internal: _Thread_Get",
746    thread_get_time,
747    OPERATION_COUNT,
748    0,
749    0
750  );
751
752  put_time(
753    "rtems internal: _Semaphore_Get",
754    semaphore_get_time,
755    OPERATION_COUNT,
756    0,
757    0
758  );
759
760  put_time(
761    "rtems internal: _Thread_Get: invalid id",
762    thread_get_invalid_time,
763    OPERATION_COUNT,
764    0,
765    0
766  );
767
768  TEST_END();
769  rtems_test_exit( 0 );
770}
Note: See TracBrowser for help on using the repository browser.