Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:27

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSScoreThread
0007  *
0008  * @brief This source file contains the implementation of
0009  *   _Thread_Do_unpin().
0010  */
0011 
0012 /*
0013  * Copyright (c) 2018 embedded brains GmbH & Co. KG
0014  *
0015  * Redistribution and use in source and binary forms, with or without
0016  * modification, are permitted provided that the following conditions
0017  * are met:
0018  * 1. Redistributions of source code must retain the above copyright
0019  *    notice, this list of conditions and the following disclaimer.
0020  * 2. Redistributions in binary form must reproduce the above copyright
0021  *    notice, this list of conditions and the following disclaimer in the
0022  *    documentation and/or other materials provided with the distribution.
0023  *
0024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0025  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0027  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0028  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0029  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0030  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0031  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0032  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0033  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0034  * POSSIBILITY OF SUCH DAMAGE.
0035  */
0036 
0037 #ifdef HAVE_CONFIG_H
0038 #include "config.h"
0039 #endif
0040 
0041 #include <rtems/score/schedulerimpl.h>
0042 
0043 void _Thread_Do_unpin( Thread_Control *executing, Per_CPU_Control *cpu_self )
0044 {
0045   ISR_lock_Context         state_lock_context;
0046   ISR_lock_Context         scheduler_lock_context;
0047   Scheduler_Node          *pinned_node;
0048   const Scheduler_Control *pinned_scheduler;
0049   Scheduler_Node          *home_node;
0050   const Scheduler_Control *home_scheduler;
0051   const Scheduler_Control *scheduler;
0052 
0053   _Thread_State_acquire( executing, &state_lock_context );
0054 
0055   executing->Scheduler.pin_level = 0;
0056 
0057   pinned_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE(
0058     _Chain_First( &executing->Scheduler.Scheduler_nodes )
0059   );
0060   pinned_scheduler = _Scheduler_Node_get_scheduler( pinned_node );
0061   home_node = _Thread_Scheduler_get_home_node( executing );
0062   home_scheduler = _Thread_Scheduler_get_home( executing );
0063   scheduler = pinned_scheduler;
0064 
0065   executing->Scheduler.pinned_scheduler = NULL;
0066 
0067   _Scheduler_Acquire_critical( scheduler, &scheduler_lock_context );
0068 
0069   if ( _Thread_Is_ready( executing ) ) {
0070     ( *scheduler->Operations.block )( scheduler, executing, pinned_node );
0071   }
0072 
0073   ( *scheduler->Operations.unpin )(
0074     scheduler,
0075     executing,
0076     pinned_node,
0077     cpu_self
0078   );
0079 
0080   if ( home_node != pinned_node ) {
0081     _Scheduler_Release_critical( scheduler, &scheduler_lock_context );
0082 
0083     _Chain_Extract_unprotected( &home_node->Thread.Scheduler_node.Chain );
0084     _Chain_Prepend_unprotected(
0085       &executing->Scheduler.Scheduler_nodes,
0086       &home_node->Thread.Scheduler_node.Chain
0087     );
0088     scheduler = home_scheduler;
0089 
0090     _Scheduler_Acquire_critical( scheduler, &scheduler_lock_context );
0091   }
0092 
0093   if ( _Thread_Is_ready( executing ) ) {
0094     ( *scheduler->Operations.unblock )( scheduler, executing, home_node );
0095   }
0096 
0097   _Scheduler_Release_critical( scheduler, &scheduler_lock_context );
0098 
0099   _Thread_State_release( executing, &state_lock_context );
0100 }