summaryrefslogblamecommitdiffstats
path: root/spec/rtems/task/req/construct.yml
blob: 9d2f0607512c8ac1bce3618b4d2cd3216aa14837 (plain) (tree)
1
2
3
4
5
6
7
8

                                                     
                                                                               



                          
                      





                                   
           

                                                            
                 

                                                  
           

                                                            


                                               
           

                                                            


                                                   
           

                                                            


                                               
           

                                                            


                                           
           

                                                            
               

                                               
           










                                                                  
                                  








                                                                   


                         
                         
             
         
             
                

                                          
           




                                                                             
                
                                          
           

                                                                               


                                    
                 
         
             
                
                                                 
           

                                                                           



                                                 



                                                                            


                                                 

                                                                               

                     
                 
         
             
                
                                                 
           


                                                                           


                                                 
























                                                                               


                                    
                   














                                                                             

















                                                                               




































































                                                                             
               



















                                                                



                
                                     










                                                                          
            
         
               
                
                                  
           
                                                        
                 
                
                               
           
                                                          

                     
          


                
                             
           


                                                                          
                
                     
           

                                                               

                     
                  


                
                                                      
           
                                                                             

                
                                                           
           
                                                                             


                     
                


                
                                                   
           
                                                                       
               

                
                                           
           
                                                                   
                 
                
                                                    
           
                                                                      

                     
            
         
               


                         
                                                                       
              
                
                                                           
           
                                                             
                     
                     



                
                                                                       
           
                                                                              
                                                             
                  
                
                                                            
           
                                                                              






                                              
                                                
           
                                                                            
                                           
                  


                          
                                                                          


                              
              




                                          

                                                            


                                           
                                                                    

                     















                                                                               
































































                                                                               


                            



                                                                               
              



                                      
                                 
                                  
                                  
                                         
                              


                                                                        
    
                                                             



                                              

                
                                    
                         
 
                                          
                        
 
                             
   

                                                                 
             















                                                                           




                                                                  

                   

                            

                   
           



                                   




                                

                   

                

                   
           
                   

                   

                                

                   
           



                                   



                                   



                                          



                               
                     

                   
           
                               

                   
           
                        




                          

                      
                          
          
                    
             
              
               




                                                           





                         
                     
                                    












                                                        

                                









                                             

                        

                                   


                   

                                                     
                                          
 
                                               
 
                                                                          
 
                                                                         
                            
                                             



                          

                                                      







                                                      


                                      
                                                     

   














                                                            




                                                                      

                                                               

   




                                                                            
                                                         


                

                                                                      

                 
                     
 
                                       































                                                           
                                       






















                                                                                 
   
        
 

                                                      


                                          





                                          
    



























                                                                       












                                                                            
                                  












                                                                               
                                                      




                         



                                                           
                        

                            




                        






                        
                       






                       

                          


                       
                           






                       
                       


                       
                         


                       
                       

                 
         




                        
          




                        
              

                        





                        

               


                        


















                             

                 












































































































































































                                               





                                      












































































































































                                  
                




                        





























                                      
                 

          
               
               

             

                   


              
                      



                  
                 
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
copyrights:
- Copyright (C) 2020, 2021 embedded brains GmbH (http://www.embedded-brains.de)
enabled-by: true
functional-type: action
links:
- role: interface-function
  uid: ../if/construct
post-conditions:
- name: Status
  states:
  - name: Ok
    test-code: |
      T_rsc_success( ctx->status );
    text: |
      The return status of ${../if/construct:/name} shall be
      ${../../status/if/successful:/name}.
  - name: InvAddr
    test-code: |
      T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
    text: |
      The return status of ${../if/construct:/name} shall be
      ${../../status/if/invalid-address:/name}.
  - name: InvName
    test-code: |
      T_rsc( ctx->status, RTEMS_INVALID_NAME );
    text: |
      The return status of ${../if/construct:/name} shall be
      ${../../status/if/invalid-name:/name}.
  - name: InvPrio
    test-code: |
      T_rsc( ctx->status, RTEMS_INVALID_PRIORITY );
    text: |
      The return status of ${../if/construct:/name} shall be
      ${../../status/if/invalid-priority:/name}.
  - name: InvSize
    test-code: |
      T_rsc( ctx->status, RTEMS_INVALID_SIZE );
    text: |
      The return status of ${../if/construct:/name} shall be
      ${../../status/if/invalid-size:/name}.
  - name: TooMany
    test-code: |
      T_rsc( ctx->status, RTEMS_TOO_MANY );
    text: |
      The return status of ${../if/construct:/name} shall be
      ${../../status/if/too-many:/name}.
  - name: Unsat
    test-code: |
      T_rsc( ctx->status, RTEMS_UNSATISFIED  );
    text: |
      The return status of ${../if/construct:/name} shall be
      ${../../status/if/unsatisfied:/name}.
  test-epilogue: null
  test-prologue: null
- name: Name
  states:
  - name: Valid
    test-code: |
      id = 0;
      sc = rtems_task_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
      T_rsc_success( sc );
      T_eq_u32( id, ctx->id_obj );
    text: |
      The unique object name shall identify the task constructed by
      the ${../if/construct:/name} call.
  - name: Invalid
    test-code: |
      sc = rtems_task_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
      T_rsc( sc, RTEMS_INVALID_NAME );
    text: |
      The unique object name shall not identify a task.
  test-epilogue: null
  test-prologue: |
    rtems_status_code sc;
    rtems_id          id;
- name: IdObj
  states:
  - name: Set
    test-code: |
      T_eq_ptr( ctx->id, &ctx->id_obj );
      T_ne_u32( ctx->id_obj, INVALID_ID );
    text: |
      The value of the object referenced by the
      ${../if/construct:/params[1]/name} parameter shall be set to the object
      identifier of the constructed task after the return of the
      ${../if/construct:/name} call.
  - name: Nop
    test-code: |
      T_eq_u32( ctx->id_obj, INVALID_ID );
    text: |
      Objects referenced by the ${../if/construct:/params[1]/name} parameter in
      past calls to ${../if/construct:/name} shall not be accessed by the
      ${../if/construct:/name} call.
  test-epilogue: null
  test-prologue: null
- name: CreateNew
  states:
  - name: All
    test-code: |
      T_eq_u32( ctx->create_extension_calls, 2 );
    text: |
      The thread create user extensions shall be invoked for the task under
      construction during the ${../if/construct:/name} call.
  - name: UpToFailing
    test-code: |
      T_eq_u32( ctx->create_extension_calls, 1 );
    text: |
      The thread create user extensions up to the failing extension shall be
      invoked for the task under construction during the
      ${../if/construct:/name} call.
  - name: Nop
    test-code: |
      T_eq_u32( ctx->create_extension_calls, 0 );
    text: |
      The thread create user extensions shall not be invoked for the task under
      construction during the ${../if/construct:/name} call.
  test-epilogue: null
  test-prologue: null
- name: DeleteNew
  states:
  - name: All
    test-code: |
      T_eq_u32( ctx->delete_extension_calls, 2 );
    text: |
      The thread delete user extensions shall be invoked for the task under
      construction during the ${../if/construct:/name} call.
  - name: Nop
    test-code: |
      T_eq_u32( ctx->delete_extension_calls, 0 );
    text: |
      The thread delete user extensions shall not be invoked for the task under
      construction during the ${../if/construct:/name} call.
  test-epilogue: null
  test-prologue: null
- name: KillZombies
  states:
  - name: 'Yes'
    test-code: |
      /*
       * We cannot check the zombie delete extension calls if we should call
       * rtems_task_construct() without an inactive TCB available.  Killing
       * a zombie would make one inactive TCB available.
       */
      if ( ctx->seized_objects == NULL ) {
        T_eq_u32( ctx->delete_zombie_extension_calls, 2 );
      }
    text: |
      The registered zombie threads shall be killed before an attempt to
      allocate a ${/glossary/tcb:/term} is made by the ${../if/construct:/name}
      call.
  - name: 'No'
    test-code: |
      T_eq_u32( ctx->delete_zombie_extension_calls, 0 );
    text: |
      The registered zombie threads shall not be killed by the
      ${../if/construct:/name} call.
  test-epilogue: null
  test-prologue: null
- name: StorageFree
  states:
  - name: 'Yes'
    test-code: |
      T_eq_u32( ctx->storage_free_calls, 1 );
    text: |
      The storage free handler of the task configuration shall be invoked
      during the ${../if/construct:/name} call.
  - name: 'No'
    test-code: |
      T_eq_u32( ctx->storage_free_calls, 0 );
    text: |
      The storage free handler of the task configuration shall not be invoked
      during the ${../if/construct:/name} call.
  test-epilogue: null
  test-prologue: null
- name: FloatingPoint
  states:
  - name: 'Yes'
    test-code: |
      /* Validated by WorkerTask() */
    text: |
      Where threads have a dedicated floating-point context, the task
      constructed by the ${../if/construct:/name} call shall be able to use the
      floating-point unit.
  - name: 'No'
    test-code: |
      /* Validated by WorkerTask() */
    text: |
      Where threads have a dedicated floating-point context, the task
      constructed by the ${../if/construct:/name} call shall not be able to use
      the floating-point unit.
  test-epilogue: null
  test-prologue: null
- name: Preempt
  states:
  - name: 'Yes'
    test-code: |
      T_eq_u32( ctx->actual_modes & RTEMS_PREEMPT, RTEMS_PREEMPT );
    text: |
      Task preemption in the initial modes of the task constructed by the
      ${../if/construct:/name} call shall be enabled.
  - name: 'No'
    test-code: |
      T_eq_u32( ctx->actual_modes & RTEMS_PREEMPT, 0 );
    text: |
      Task preemption in the initial modes of the task constructed by the
      ${../if/construct:/name} call shall be disabled.
  test-epilogue: null
  test-prologue: null
- name: Timeslice
  states:
  - name: 'Yes'
    test-code: |
      T_eq_u32( ctx->actual_modes & RTEMS_TIMESLICE, RTEMS_TIMESLICE );
    text: |
      Timeslicing in the initial modes of the task constructed by the
      ${../if/construct:/name} call shall be enabled.
  - name: 'No'
    test-code: |
      T_eq_u32( ctx->actual_modes & RTEMS_TIMESLICE, 0 );
    text: |
      Timeslicing in the initial modes of the task constructed by the
      ${../if/construct:/name} call shall be disabled.
  test-epilogue: null
  test-prologue: null
- name: ASR
  states:
  - name: 'Yes'
    test-code: |
      T_eq_u32( ctx->actual_modes & RTEMS_ASR, RTEMS_ASR );
    text: |
      ASR processing in the initial modes of the task constructed by the
      ${../if/construct:/name} call shall be enabled.
  - name: 'No'
    test-code: |
      T_eq_u32( ctx->actual_modes & RTEMS_ASR, 0 );
    text: |
      ASR processing in the initial modes of the task constructed by the
      ${../if/construct:/name} call shall be disabled.
  test-epilogue: null
  test-prologue: null
- name: IntLvl
  states:
  - name: Zero
    test-code: |
      T_eq_u32( ctx->actual_modes & RTEMS_INTERRUPT_MASK, 0 );
    text: |
      The interrupt level in the initial modes of the task constructed by the
      ${../if/construct:/name} call shall be zero.
  - name: Positive
    test-code: |
      T_eq_u32(
        ctx->actual_modes & RTEMS_INTERRUPT_MASK,
        ctx->config_obj.initial_modes & RTEMS_INTERRUPT_MASK
      );
    text: |
      The interrupt level in the initial modes of the task constructed by the
      ${../if/construct:/name} call shall be the interrupt level specified by
      the initial modes of the task configuration mapped to an
      ${/glossary/target-arch:/term}-specific positive value.
  test-epilogue: null
  test-prologue: null
pre-conditions:
- name: CPUs
  states:
  - name: One
    test-code: |
      if ( rtems_scheduler_get_processor_maximum() != 1 ) {
        ${.:skip}
      }
    text: |
      Where the system does not need inter-processor interrupts,
      where the scheduler does support the no-preempt mode.
  - name: More
    test-code: |
      if ( rtems_scheduler_get_processor_maximum() == 1 ) {
        ${.:skip}
      }
    text: |
      Where the system needs inter-processor interrupts,
      where the scheduler does not support the no-preempt mode.
  test-epilogue: null
  test-prologue: null
- name: Config
  states:
  - name: Valid
    test-code: |
      ctx->config = &ctx->config_obj;
    text: |
      While the ${../if/construct:/params[0]/name} parameter references an
      object of type ${../if/config:/name}.
  - name: 'Null'
    test-code: |
      ctx->config = NULL;
    text: |
      While the ${../if/construct:/params[0]/name} parameter is
      ${/c/if/null:/name}.
  test-epilogue: null
  test-prologue: null
- name: Name
  states:
  - name: Valid
    test-code: |
      ctx->config_obj.name = NAME;
    text: |
      While the name of the task configuration is valid.
  - name: Invalid
    test-code: |
      ctx->config_obj.name = 0;
    text: |
      While the name of the task configuration is invalid.
  test-epilogue: null
  test-prologue: null
- name: Id
  states:
  - name: Valid
    test-code: |
      ctx->id = &ctx->id_obj;
    text: |
      While the ${../if/construct:/params[1]/name} parameter references an
      object of type ${../../type/if/id:/name}.
  - name: 'Null'
    test-code: |
      ctx->id = NULL;
    text: |
      While the ${../if/construct:/params[1]/name} parameter is
      ${/c/if/null:/name}.
  test-epilogue: null
  test-prologue: null
- name: SystemTask
  states:
  - name: 'Yes'
    test-code: |
      ctx->config_obj.attributes |= RTEMS_SYSTEM_TASK;
    text: |
      While the attributes of the task configuration specifies a system task.
  - name: 'No'
    test-code: |
      ctx->config_obj.attributes |= RTEMS_APPLICATION_TASK;
    text: |
      While the attributes of the task configuration specifies an application
      task.
  test-epilogue: null
  test-prologue: null
- name: Priority
  states:
  - name: Valid
    test-code: |
      ctx->config_obj.initial_priority = PRIO_HIGH;
    text: |
      While the initial priority of the task configuration is valid and
      non-zero.
  - name: Zero
    test-code: |
      ctx->config_obj.initial_priority = 0;
    text: |
      While the initial priority of the task configuration is zero.
  - name: Invalid
    test-code: |
      ctx->config_obj.initial_priority = 0xffffffff;
    text: |
      While the initial priority of the task configuration is invalid.
  test-epilogue: null
  test-prologue: null
- name: Free
  states:
  - name: 'Yes'
    test-code: |
      /* Nothing to do */
    text: |
      While the system has at least one inactive task object available.
  - name: 'No'
    test-code: |
      ctx->seized_objects = T_seize_objects( Create, ctx );
    text: |
      While the system has no inactive task object available.
  test-epilogue: null
  test-prologue: null
- name: TLS
  states:
  - name: Enough
    test-code: |
      ctx->config_obj.maximum_thread_local_storage_size = MAX_TLS_SIZE;
    text: |
      While the maximum thread-local storage size of the task configuration is
      greater than or equal to the thread-local storage size.
  - name: TooSmall
    test-code: |
      ctx->config_obj.maximum_thread_local_storage_size = 0;
    text: |
      While the maximum thread-local storage size of the task configuration is
      less than the thread-local storage size.
  test-epilogue: null
  test-prologue: null
- name: Stack
  states:
  - name: Enough
    test-code: |
      ctx->stack_size = TEST_MINIMUM_STACK_SIZE;
    text: |
      While the task stack size of the task configuration is greater than or
      equal to the configured minimum size.
  - name: TooSmall
    test-code: |
      ctx->stack_size = 0;
    text: |
      While the task stack size of the task configuration is less than the
      configured minimum size.
  test-epilogue: null
  test-prologue: null
- name: Create
  states:
  - name: Ok
    test-code: |
      ctx->create_extension_status = true;
    text: |
      While none of the thread create user extensions fails.
  - name: Error
    test-code: |
      ctx->create_extension_status = false;
    text: |
      While at least one of the thread create user extensions fails.
  test-epilogue: null
  test-prologue: null
- name: FloatingPoint
  states:
  - name: 'Yes'
    test-code: |
      ctx->config_obj.attributes |= RTEMS_FLOATING_POINT;
    text: |
      While the attributes of the task configuration specifies a floating-point
      task.
  - name: 'No'
    test-code: |
      ctx->config_obj.attributes |= RTEMS_NO_FLOATING_POINT;
    text: |
      While the attributes of the task configuration specifies a
      non-floating-point task.
  test-epilogue: null
  test-prologue: null
- name: Preempt
  states:
  - name: 'Yes'
    test-code: |
      ctx->config_obj.initial_modes |= RTEMS_PREEMPT;
    text: |
      While the initial modes of the task configuration specify that preemption
      is enabled.
  - name: 'No'
    test-code: |
      ctx->config_obj.initial_modes |= RTEMS_NO_PREEMPT;
    text: |
      While the initial modes of the task configuration specify that preemption
      is disabled.
  test-epilogue: null
  test-prologue: null
- name: Timeslice
  states:
  - name: 'Yes'
    test-code: |
      ctx->config_obj.initial_modes |= RTEMS_TIMESLICE;
    text: |
      While the initial modes of the task configuration specify that
      timeslicing is enabled.
  - name: 'No'
    test-code: |
      ctx->config_obj.initial_modes |= RTEMS_NO_TIMESLICE;
    text: |
      While the initial modes of the task configuration specify that
      timeslicing is disabled.
  test-epilogue: null
  test-prologue: null
- name: ASR
  states:
  - name: 'Yes'
    test-code: |
      ctx->config_obj.initial_modes |= RTEMS_ASR;
    text: |
      While the initial modes of the task configuration specify that ASR
      processing is enabled.
  - name: 'No'
    test-code: |
      ctx->config_obj.initial_modes |= RTEMS_NO_ASR;
    text: |
      While the initial modes of the task configuration specify that ASR
      processing is disabled.
  test-epilogue: null
  test-prologue: null
- name: IntLvl
  states:
  - name: Zero
    test-code: |
      ctx->config_obj.initial_modes |= RTEMS_INTERRUPT_LEVEL( 0 );
    text: |
      While the initial modes of the task configuration specify an interrupt
      level of zero.
  - name: Positive
    test-code: |
      ctx->config_obj.initial_modes |= RTEMS_INTERRUPT_LEVEL( 1 );
    text: |
      While the initial modes of the task configuration specify an interrupt
      level greater than zero and less than or equal to
      ${/score/cpu/if/modes-interrupt-mask:/name}.
  test-epilogue: null
  test-prologue: null
rationale: null
references: []
requirement-type: functional
skip-reasons:
  OnlyOneCPU: |
    Where the system is build with SMP support disabled, the system has exactly
    one processor.
test-action: |
  if ( ctx->seized_objects == NULL ) {
    PrepareZombie( ctx );
  }

  ctx->actual_modes = UINT32_MAX;
  ctx->create_extension_calls = 0;
  ctx->delete_extension_calls = 0;
  ctx->delete_zombie_extension_calls = 0;
  ctx->storage_free_calls = 0;
  ctx->config_obj.storage_size = RTEMS_TASK_STORAGE_SIZE(
    ctx->config_obj.maximum_thread_local_storage_size + ctx->stack_size,
    ctx->config_obj.attributes
  );
  ctx->status = rtems_task_construct( ctx->config, ctx->id );

  if ( ctx->status == RTEMS_SUCCESSFUL ) {
    StartTask( ctx->id_obj, WorkerTask, ctx );
  }
test-brief: null
test-cleanup: |
  if ( ctx->id_obj != INVALID_ID ) {
    rtems_status_code sc;

    sc = rtems_task_delete( ctx->id_obj );
    T_rsc_success( sc );

    ctx->id_obj = INVALID_ID;
  }

  T_surrender_objects( &ctx->seized_objects, rtems_task_delete );
test-context:
- brief: |
    This member contains the scheduler B identifier.
  description: null
  member: |
    rtems_id scheduler_b_id
- brief: |
    This member contains the thread zombie registry ticket right before the
    task exit of the zombie task.
  description: null
  member: |
    unsigned int thread_zombie_ticket
- brief: |
    If this member is true, then the zombie thread is ready to get killed.
  description: null
  member: |
    volatile bool zombie_ready;
- brief: |
    This member contains the actual modes of the constructed task.
  description: null
  member: |
    rtems_mode actual_modes
- brief: null
  description: null
  member: |
    rtems_status_code status
- brief: null
  description: null
  member: |
    const rtems_task_config *config
- brief: null
  description: null
  member: |
    rtems_task_config config_obj
- brief: null
  description: null
  member: |
    rtems_id zombie_id
- brief: null
  description: null
  member: |
    rtems_id *id
- brief: null
  description: null
  member: |
    rtems_id id_obj
- brief: null
  description: null
  member: |
    bool create_extension_status
- brief: null
  description: null
  member: |
    uint32_t create_extension_calls
- brief: null
  description: null
  member: |
    uint32_t delete_extension_calls
- brief: null
  description: null
  member: |
    uint32_t delete_zombie_extension_calls
- brief: null
  description: null
  member: |
    uint32_t storage_free_calls
- brief: null
  description: null
  member: |
    size_t stack_size
- brief: null
  description: null
  member: |
    rtems_id extension_ids[ 2 ]
- brief: null
  description: null
  member: |
    void *seized_objects
test-context-support: null
test-description: null
test-header: null
test-includes:
- rtems.h
- rtems/score/atomic.h
- rtems/score/percpu.h
- rtems/score/threadimpl.h
- string.h
test-local-includes:
- ts-config.h
- tx-support.h
test-prepare: |
  KillZombies();
  ctx->id_obj = INVALID_ID;
  memset( &ctx->config_obj, 0, sizeof( ctx->config_obj ) );
  ctx->config_obj.storage_area = task_storage,
  ctx->config_obj.storage_free = StorageFree;
test-setup:
  brief: null
  code: |
    rtems_status_code sc;
    int var;

    var = tls_object;
    RTEMS_OBFUSCATE_VARIABLE( var );
    tls_object = var;

    ctx->scheduler_b_id = INVALID_ID;
    #if defined(RTEMS_SMP)
    ctx->zombie_ready = true;
    if ( rtems_scheduler_get_processor_maximum() > 1 ) {
      sc = rtems_scheduler_ident(
        TEST_SCHEDULER_B_NAME,
        &ctx->scheduler_b_id
      );
      T_rsc_success( sc );
    }
    #endif

    sc = rtems_extension_create(
      rtems_build_name( 'E', 'X', 'T', '1' ),
      &extensions[ 0 ],
      &ctx->extension_ids[ 0 ]
    );
    T_rsc_success( sc );

    sc = rtems_extension_create(
      rtems_build_name( 'E', 'X', 'T', '2' ),
      &extensions[ 1 ],
      &ctx->extension_ids[ 1 ]
    );
    T_rsc_success( sc );

    SetSelfPriority( PRIO_NORMAL );
  description: null
test-stop: null
test-support: |
  #define NAME rtems_build_name( 'T', 'E', 'S', 'T' )

  typedef ${.:/test-context-type} Context;

  static volatile _Thread_local int tls_object;

  #define MAX_TLS_SIZE RTEMS_ALIGN_UP( 128, RTEMS_TASK_STORAGE_ALIGNMENT )

  RTEMS_ALIGNED( RTEMS_TASK_STORAGE_ALIGNMENT ) static char task_storage[
    RTEMS_TASK_STORAGE_SIZE(
      MAX_TLS_SIZE + TEST_MINIMUM_STACK_SIZE,
      RTEMS_FLOATING_POINT
    )
  ];

  static const rtems_task_config seize_task_config = {
    .name = rtems_build_name( 'S', 'I', 'Z', 'E' ),
    .initial_priority = 1,
    .storage_area = task_storage,
    .storage_size = sizeof( task_storage ),
    .maximum_thread_local_storage_size = MAX_TLS_SIZE,
    .initial_modes = RTEMS_DEFAULT_MODES,
    .attributes = RTEMS_DEFAULT_MODES
  };

  static void StorageFree( void *ptr )
  {
    T_eq_ptr( ptr, task_storage );
    ++${.:/test-context-instance}.storage_free_calls;
  }

  static rtems_status_code Create( void *arg, uint32_t *id )
  {
    Context          *ctx;
    bool              create_extension_status;
    rtems_status_code sc;

    ctx = arg;
    create_extension_status = ctx->create_extension_status;
    ctx->create_extension_status = true;
    sc = rtems_task_construct( &seize_task_config, id );
    ctx->create_extension_status = create_extension_status;

    return sc;
  }

  static bool ThreadCreate( rtems_tcb *executing, rtems_tcb *created )
  {
    (void) executing;
    (void) created;

    ++${.:/test-context-instance}.create_extension_calls;
    return ${.:/test-context-instance}.create_extension_status;
  }

  static bool SecondThreadCreate( rtems_tcb *executing, rtems_tcb *created )
  {
    (void) executing;
    (void) created;

    ++${.:/test-context-instance}.create_extension_calls;
    return true;
  }

  static void ThreadDelete( rtems_tcb *executing, rtems_tcb *deleted )
  {
    Context *ctx;

    (void) executing;

    ctx = &${.:/test-context-instance};

    if ( deleted->Object.id == ctx->zombie_id ) {
      ++ctx->delete_zombie_extension_calls;
    } else {
      ++ctx->delete_extension_calls;
    }
  }

  #if defined(RTEMS_SMP)
  static void PreemptionIntervention( void *arg )
  {
    Context     *ctx;
    unsigned int ticket;

    ctx = arg;
    T_false( ctx->zombie_ready );
    ctx->zombie_ready = true;

    do {
      ticket = _Atomic_Load_uint(
        &_Thread_Zombies.Lock.Lock.Ticket_lock.now_serving,
        ATOMIC_ORDER_RELAXED
      );
    } while ( ( ticket - ctx->thread_zombie_ticket ) < 2 );

    T_busy( 100 );
  }

  static void ThreadTerminate( rtems_tcb *executing )
  {
    Context *ctx;

    ctx = &${.:/test-context-instance};

    if (
      ctx->scheduler_b_id != INVALID_ID &&
      ctx->zombie_id == executing->Object.id
    ) {
      /*
       * We use the ticket lock of the thread zombie registry to delay the thread
       * dispatch and provoke an executing thread in
       * _Thread_Kill_zombies().  The first acquire is done in the
       * rtems_task_exit() below.  The second acquire is done in
       * _Thread_Kill_zombies().
       */
      ctx->thread_zombie_ticket = _Atomic_Fetch_add_uint(
        &_Thread_Zombies.Lock.Lock.Ticket_lock.now_serving,
        0,
        ATOMIC_ORDER_RELAXED
      );
      SetPreemptionIntervention(
        _Per_CPU_Get_snapshot(),
        PreemptionIntervention,
        ctx
      );
    }
  }
  #endif

  static const rtems_extensions_table extensions[] = {
    {
  #if defined(RTEMS_SMP)
      .thread_terminate = ThreadTerminate,
  #endif
      .thread_create = ThreadCreate,
      .thread_delete = ThreadDelete
    }, {
      .thread_create = SecondThreadCreate,
      .thread_delete = ThreadDelete
    }
  };

  static void ZombieTask( rtems_task_argument arg )
  {
    (void) arg;
    rtems_task_exit();
  }

  static void PrepareZombie( Context *ctx )
  {
    bool create_extension_status;

    create_extension_status = ctx->create_extension_status;
    ctx->create_extension_status = true;
    ctx->zombie_id = CreateTask( "ZOMB", PRIO_HIGH );
    ctx->create_extension_status = create_extension_status;
  #if defined(RTEMS_SMP)
    if ( ctx->scheduler_b_id != INVALID_ID ) {
      ctx->zombie_ready = false;
      SetScheduler( ctx->zombie_id, ctx->scheduler_b_id, PRIO_NORMAL );
    }
  #endif
    StartTask( ctx->zombie_id, ZombieTask, ctx );
  #if defined(RTEMS_SMP)
    while ( !ctx->zombie_ready ) {
      /* Wait */
    }
  #endif
  }

  static volatile double double_object;

  static RTEMS_NO_INLINE void UseFloatingPointUnit( void )
  {
    double_object = ( 123.0 * double_object + double_object / 123.0 ) / 2.0;
  }

  static void WorkerTask( rtems_task_argument arg )
  {
    Context *ctx;

    ctx = (Context *) arg;
    ctx->actual_modes = GetMode();

    /*
     * We don't validate here that we cannot use the floating-point unit if the
     * RTEMS_FLOATING_POINT attribute is not set.  This is done elsewhere.
     * Using the floating-point unit if the RTEMS_FLOATING_POINT attribute is
     * not set may result in unrecoverable fatal errors.
     */
    if ( ( ctx->config_obj.attributes & RTEMS_FLOATING_POINT ) != 0 ) {
      UseFloatingPointUnit();
    }

    SuspendSelf();
  }
test-target: testsuites/validation/tc-task-construct.c
test-teardown:
  brief: null
  code: |
    rtems_status_code sc;

    sc = rtems_extension_delete( ctx->extension_ids[ 0 ] );
    T_rsc_success( sc );

    sc = rtems_extension_delete( ctx->extension_ids[ 1 ] );
    T_rsc_success( sc );

    RestoreRunnerPriority();
  description: null
text: ${.:text-template}
transition-map:
- enabled-by: true
  post-conditions:
    Status:
    - if:
        pre-conditions:
          Config: 'Null'
      then: InvAddr
    - if:
        pre-conditions:
          Name: Invalid
      then: InvName
    - if:
        pre-conditions:
          Id: 'Null'
      then: InvAddr
    - if:
        pre-conditions:
          Priority: Zero
          SystemTask: 'No'
      then: InvPrio
    - if:
        pre-conditions:
          Priority: Invalid
      then: InvPrio
    - if:
        pre-conditions:
          Free: 'No'
      then: TooMany
    - if:
        pre-conditions:
          TLS: TooSmall
      then: InvSize
    - if:
        pre-conditions:
          Stack: TooSmall
      then: InvSize
    - if:
        pre-conditions:
          Create: Error
      then: Unsat
    - else: Ok
    Name:
    - if:
        post-conditions:
          Status: Ok
      then: Valid
    - else: Invalid
    IdObj:
    - if:
        post-conditions:
          Status: Ok
      then: Set
    - else: Nop
    CreateNew:
    - if:
        post-conditions:
          Status: Ok
      then: All
    - if:
        post-conditions:
          Status: Unsat
      then: UpToFailing
    - else: Nop
    DeleteNew:
    - if:
        post-conditions:
          Status: Unsat
      then: All
    - else: Nop
    KillZombies:
    - if:
        - pre-conditions:
            Config: Valid
            Name: Valid
            Id: Valid
            SystemTask: 'Yes'
            Priority:
            - Valid
            - Zero
        - pre-conditions:
            Config: Valid
            Name: Valid
            Id: Valid
            SystemTask: 'No'
            Priority:
            - Valid
      then: 'Yes'
    - else: 'No'
    StorageFree:
    - if:
        post-conditions:
          Status: Unsat
      then: 'Yes'
    - else: 'No'
    FloatingPoint:
    - if:
        post-conditions:
          Status: Ok
      then-specified-by: FloatingPoint
    - else: N/A
    Preempt:
    - if:
        post-conditions:
          Status: Ok
      then-specified-by: Preempt
    - else: N/A
    Timeslice:
    - if:
        post-conditions:
          Status: Ok
      then-specified-by: Timeslice
    - else: N/A
    ASR:
    - if:
        post-conditions:
          Status: Ok
      then-specified-by: ASR
    - else: N/A
    IntLvl:
    - if:
        post-conditions:
          Status: Ok
      then-specified-by: IntLvl
    - else: N/A
  pre-conditions:
    CPUs:
    - One
    Config: all
    Create: all
    Id: all
    Name: all
    SystemTask: all
    Priority: all
    Stack: all
    TLS: all
    Free: all
    FloatingPoint: all
    Preempt: all
    Timeslice: all
    ASR: all
    IntLvl: all
- enabled-by: true
  post-conditions: OnlyOneCPU
  pre-conditions:
    CPUs:
    - More
    Config: all
    Create: all
    Id: all
    Name: all
    SystemTask: all
    Priority: all
    Stack: all
    TLS: all
    Free: all
    FloatingPoint: all
    Preempt: all
    Timeslice: all
    ASR: all
    IntLvl: all
- enabled-by: CPU_ENABLE_ROBUST_THREAD_DISPATCH
  post-conditions:
    Status:
    - if:
        pre-conditions:
          Config: 'Null'
      then: InvAddr
    - if:
        pre-conditions:
          Name: Invalid
      then: InvName
    - if:
        pre-conditions:
          Id: 'Null'
      then: InvAddr
    - if:
        pre-conditions:
          Priority: Zero
          SystemTask: 'No'
      then: InvPrio
    - if:
        pre-conditions:
          Priority: Invalid
      then: InvPrio
    - if:
        pre-conditions:
          Free: 'No'
      then: TooMany
    - if:
        pre-conditions:
          TLS: TooSmall
      then: InvSize
    - if:
        pre-conditions:
          Stack: TooSmall
      then: InvSize
    - if:
        pre-conditions:
          IntLvl: Positive
      then: Unsat
    - if:
        pre-conditions:
          Create: Error
      then: Unsat
    - else: Ok
    Name:
    - if:
        post-conditions:
          Status: Ok
      then: Valid
    - else: Invalid
    IdObj:
    - if:
        post-conditions:
          Status: Ok
      then: Set
    - else: Nop
    CreateNew:
    - if:
        post-conditions:
          Status: Ok
      then: All
    - if:
        and:
          - post-conditions:
              Status: Unsat
          - pre-conditions:
              IntLvl: Zero
      then: UpToFailing
    - else: Nop
    DeleteNew:
    - if:
        post-conditions:
          Status: Unsat
      then: All
    - else: Nop
    KillZombies:
    - if:
        - pre-conditions:
            Config: Valid
            Name: Valid
            Id: Valid
            SystemTask: 'Yes'
            Priority:
            - Valid
            - Zero
        - pre-conditions:
            Config: Valid
            Name: Valid
            Id: Valid
            SystemTask: 'No'
            Priority:
            - Valid
      then: 'Yes'
    - else: 'No'
    StorageFree:
    - if:
        post-conditions:
          Status: Unsat
      then: 'Yes'
    - else: 'No'
    FloatingPoint:
    - if:
        post-conditions:
          Status: Ok
      then-specified-by: FloatingPoint
    - else: N/A
    Preempt:
    - if:
        post-conditions:
          Status: Ok
      then-specified-by: Preempt
    - else: N/A
    Timeslice:
    - if:
        post-conditions:
          Status: Ok
      then-specified-by: Timeslice
    - else: N/A
    ASR:
    - if:
        post-conditions:
          Status: Ok
      then-specified-by: ASR
    - else: N/A
    IntLvl:
    - if:
        post-conditions:
          Status: Ok
      then-specified-by: IntLvl
    - else: N/A
  pre-conditions:
    CPUs:
    - One
    Config: all
    Create: all
    Id: all
    Name: all
    SystemTask: all
    Priority: all
    Stack: all
    TLS: all
    Free: all
    FloatingPoint: all
    Preempt: all
    Timeslice: all
    ASR: all
    IntLvl: all
- enabled-by: RTEMS_SMP
  post-conditions:
    Status:
    - if:
        pre-conditions:
          Config: 'Null'
      then: InvAddr
    - if:
        pre-conditions:
          Name: Invalid
      then: InvName
    - if:
        pre-conditions:
          Id: 'Null'
      then: InvAddr
    - if:
        pre-conditions:
          Priority: Zero
          SystemTask: 'No'
      then: InvPrio
    - if:
        pre-conditions:
          Priority: Invalid
      then: InvPrio
    - if:
        pre-conditions:
          Free: 'No'
      then: TooMany
    - if:
        pre-conditions:
          TLS: TooSmall
      then: InvSize
    - if:
        pre-conditions:
          Stack: TooSmall
      then: InvSize
    - if:
        pre-conditions:
          Preempt: 'No'
      then: Unsat
    - if:
        pre-conditions:
          IntLvl: Positive
      then: Unsat
    - if:
        pre-conditions:
          Create: Error
      then: Unsat
    - else: Ok
    Name:
    - if:
        post-conditions:
          Status: Ok
      then: Valid
    - else: Invalid
    IdObj:
    - if:
        post-conditions:
          Status: Ok
      then: Set
    - else: Nop
    CreateNew:
    - if:
        post-conditions:
          Status: Ok
      then: All
    - if:
        and:
          - post-conditions:
              Status: Unsat
          - pre-conditions:
              Preempt: 'Yes'
              IntLvl: Zero
      then: UpToFailing
    - else: Nop
    DeleteNew:
    - if:
        post-conditions:
          Status: Unsat
      then: All
    - else: Nop
    KillZombies:
    - if:
        - pre-conditions:
            Config: Valid
            Name: Valid
            Id: Valid
            SystemTask: 'Yes'
            Priority:
            - Valid
            - Zero
        - pre-conditions:
            Config: Valid
            Name: Valid
            Id: Valid
            SystemTask: 'No'
            Priority:
            - Valid
      then: 'Yes'
    - else: 'No'
    StorageFree:
    - if:
        post-conditions:
          Status: Unsat
      then: 'Yes'
    - else: 'No'
    FloatingPoint:
    - if:
        post-conditions:
          Status: Ok
      then-specified-by: FloatingPoint
    - else: N/A
    Preempt:
    - if:
        post-conditions:
          Status: Ok
      then-specified-by: Preempt
    - else: N/A
    Timeslice:
    - if:
        post-conditions:
          Status: Ok
      then-specified-by: Timeslice
    - else: N/A
    ASR:
    - if:
        post-conditions:
          Status: Ok
      then-specified-by: ASR
    - else: N/A
    IntLvl:
    - if:
        post-conditions:
          Status: Ok
      then-specified-by: IntLvl
    - else: N/A
  pre-conditions:
    CPUs:
    - More
    Config: all
    Create: all
    Id: all
    Name: all
    SystemTask: all
    Priority: all
    Stack: all
    TLS: all
    Free: all
    FloatingPoint: all
    Preempt: all
    Timeslice: all
    ASR: all
    IntLvl: all
type: requirement