Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSImplClassicSemaphoreMP
0007  *
0008  * @brief This source file contains the implementation to support the Semaphore
0009  *   Manager in multiprocessing (MP) configurations.
0010  */
0011 
0012 /*
0013  *  COPYRIGHT (c) 1989-2008.
0014  *  On-Line Applications Research Corporation (OAR).
0015  *
0016  * Redistribution and use in source and binary forms, with or without
0017  * modification, are permitted provided that the following conditions
0018  * are met:
0019  * 1. Redistributions of source code must retain the above copyright
0020  *    notice, this list of conditions and the following disclaimer.
0021  * 2. Redistributions in binary form must reproduce the above copyright
0022  *    notice, this list of conditions and the following disclaimer in the
0023  *    documentation and/or other materials provided with the distribution.
0024  *
0025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0026  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0028  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0029  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0030  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0031  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0033  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0034  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0035  * POSSIBILITY OF SUCH DAMAGE.
0036  */
0037 
0038 #ifdef HAVE_CONFIG_H
0039 #include "config.h"
0040 #endif
0041 
0042 #include <rtems/rtems/semimpl.h>
0043 #include <rtems/rtems/optionsimpl.h>
0044 #include <rtems/rtems/statusimpl.h>
0045 #include <rtems/sysinit.h>
0046 
0047 RTEMS_STATIC_ASSERT(
0048   sizeof(Semaphore_MP_Packet) <= MP_PACKET_MINIMUM_PACKET_SIZE,
0049   Semaphore_MP_Packet
0050 );
0051 
0052 static Semaphore_MP_Packet *_Semaphore_MP_Get_packet( void )
0053 {
0054   return (Semaphore_MP_Packet *) _MPCI_Get_packet();
0055 }
0056 
0057 void _Semaphore_MP_Send_process_packet (
0058   Semaphore_MP_Remote_operations  operation,
0059   Objects_Id                      semaphore_id,
0060   rtems_name                      name,
0061   Objects_Id                      proxy_id
0062 )
0063 {
0064   Semaphore_MP_Packet *the_packet;
0065   uint32_t             node;
0066 
0067   switch ( operation ) {
0068 
0069     case SEMAPHORE_MP_ANNOUNCE_CREATE:
0070     case SEMAPHORE_MP_ANNOUNCE_DELETE:
0071     case SEMAPHORE_MP_EXTRACT_PROXY:
0072 
0073       the_packet                    = _Semaphore_MP_Get_packet();
0074       the_packet->Prefix.the_class  = MP_PACKET_SEMAPHORE;
0075       the_packet->Prefix.length     = sizeof ( Semaphore_MP_Packet );
0076       the_packet->Prefix.to_convert = sizeof ( Semaphore_MP_Packet );
0077       the_packet->operation         = operation;
0078       the_packet->Prefix.id         = semaphore_id;
0079       the_packet->name              = name;
0080       the_packet->proxy_id          = proxy_id;
0081 
0082       if ( operation == SEMAPHORE_MP_EXTRACT_PROXY )
0083          node = _Objects_Get_node( semaphore_id );
0084       else
0085          node = MPCI_ALL_NODES;
0086 
0087       _MPCI_Send_process_packet( node, &the_packet->Prefix );
0088       break;
0089 
0090     case SEMAPHORE_MP_OBTAIN_REQUEST:
0091     case SEMAPHORE_MP_OBTAIN_RESPONSE:
0092     case SEMAPHORE_MP_RELEASE_REQUEST:
0093     case SEMAPHORE_MP_RELEASE_RESPONSE:
0094       break;
0095   }
0096 }
0097 
0098 static rtems_status_code _Semaphore_MP_Send_request_packet(
0099   Objects_Id                     semaphore_id,
0100   rtems_option                   option_set,
0101   rtems_interval                 timeout,
0102   Semaphore_MP_Remote_operations operation
0103 )
0104 {
0105   Semaphore_MP_Packet *the_packet;
0106   Status_Control       status;
0107 
0108   if ( !_Semaphore_MP_Is_remote( semaphore_id ) ) {
0109     return RTEMS_INVALID_ID;
0110   }
0111 
0112   switch ( operation ) {
0113 
0114     case SEMAPHORE_MP_OBTAIN_REQUEST:
0115     case SEMAPHORE_MP_RELEASE_REQUEST:
0116 
0117       the_packet                    = _Semaphore_MP_Get_packet();
0118       the_packet->Prefix.the_class  = MP_PACKET_SEMAPHORE;
0119       the_packet->Prefix.length     = sizeof ( Semaphore_MP_Packet );
0120       the_packet->Prefix.to_convert = sizeof ( Semaphore_MP_Packet );
0121       if ( ! _Options_Is_no_wait(option_set))
0122           the_packet->Prefix.timeout = timeout;
0123 
0124       the_packet->operation         = operation;
0125       the_packet->Prefix.id         = semaphore_id;
0126       the_packet->option_set        = option_set;
0127 
0128       status = _MPCI_Send_request_packet(
0129         _Objects_Get_node( semaphore_id ),
0130         &the_packet->Prefix,
0131         STATES_WAITING_FOR_SEMAPHORE
0132       );
0133       return _Status_Get( status );
0134 
0135     case SEMAPHORE_MP_ANNOUNCE_CREATE:
0136     case SEMAPHORE_MP_ANNOUNCE_DELETE:
0137     case SEMAPHORE_MP_EXTRACT_PROXY:
0138     case SEMAPHORE_MP_OBTAIN_RESPONSE:
0139     case SEMAPHORE_MP_RELEASE_RESPONSE:
0140       break;
0141 
0142   }
0143   /*
0144    *  The following line is included to satisfy compilers which
0145    *  produce warnings when a function does not end with a return.
0146    */
0147   return RTEMS_SUCCESSFUL;
0148 }
0149 
0150 rtems_status_code _Semaphore_MP_Obtain(
0151   rtems_id        id,
0152   rtems_option    option_set,
0153   rtems_interval  timeout
0154 )
0155 {
0156   return _Semaphore_MP_Send_request_packet(
0157     id,
0158     option_set,
0159     timeout,
0160     SEMAPHORE_MP_OBTAIN_REQUEST
0161   );
0162 }
0163 
0164 rtems_status_code _Semaphore_MP_Release( rtems_id id )
0165 {
0166   return _Semaphore_MP_Send_request_packet(
0167     id,
0168     0,
0169     MPCI_DEFAULT_TIMEOUT,
0170     SEMAPHORE_MP_RELEASE_REQUEST
0171   );
0172 }
0173 
0174 static void _Semaphore_MP_Send_response_packet (
0175   Semaphore_MP_Remote_operations  operation,
0176   Objects_Id                      semaphore_id,
0177   Thread_Control                 *the_thread
0178 )
0179 {
0180   Semaphore_MP_Packet *the_packet;
0181 
0182   switch ( operation ) {
0183 
0184     case SEMAPHORE_MP_OBTAIN_RESPONSE:
0185     case SEMAPHORE_MP_RELEASE_RESPONSE:
0186 
0187       the_packet = ( Semaphore_MP_Packet *) the_thread->receive_packet;
0188 
0189 /*
0190  *  The packet being returned already contains the class, length, and
0191  *  to_convert fields, therefore they are not set in this routine.
0192  */
0193       the_packet->operation = operation;
0194       the_packet->Prefix.id = the_packet->Prefix.source_tid;
0195 
0196       _MPCI_Send_response_packet(
0197         _Objects_Get_node( the_packet->Prefix.source_tid ),
0198         &the_packet->Prefix
0199       );
0200       break;
0201 
0202     case SEMAPHORE_MP_ANNOUNCE_CREATE:
0203     case SEMAPHORE_MP_ANNOUNCE_DELETE:
0204     case SEMAPHORE_MP_EXTRACT_PROXY:
0205     case SEMAPHORE_MP_OBTAIN_REQUEST:
0206     case SEMAPHORE_MP_RELEASE_REQUEST:
0207       break;
0208 
0209   }
0210 }
0211 
0212 static void _Semaphore_MP_Process_packet (
0213   rtems_packet_prefix  *the_packet_prefix
0214 )
0215 {
0216   Semaphore_MP_Packet *the_packet;
0217   Thread_Control      *the_thread;
0218 
0219   the_packet = (Semaphore_MP_Packet *) the_packet_prefix;
0220 
0221   switch ( the_packet->operation ) {
0222 
0223     case SEMAPHORE_MP_ANNOUNCE_CREATE:
0224 
0225       _Objects_MP_Allocate_and_open(
0226         &_Semaphore_Information,
0227         the_packet->name,
0228         the_packet->Prefix.id,
0229         true
0230       );
0231 
0232       _MPCI_Return_packet( the_packet_prefix );
0233       break;
0234 
0235     case SEMAPHORE_MP_ANNOUNCE_DELETE:
0236 
0237       _Objects_MP_Close( &_Semaphore_Information, the_packet->Prefix.id );
0238 
0239       _MPCI_Return_packet( the_packet_prefix );
0240       break;
0241 
0242     case SEMAPHORE_MP_EXTRACT_PROXY:
0243 
0244       the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id );
0245 
0246       if ( the_thread != NULL ) {
0247         _Thread_queue_Extract( the_thread );
0248       }
0249 
0250       _MPCI_Return_packet( the_packet_prefix );
0251       break;
0252 
0253     case SEMAPHORE_MP_OBTAIN_REQUEST:
0254 
0255       the_packet->Prefix.return_code = rtems_semaphore_obtain(
0256         the_packet->Prefix.id,
0257         the_packet->option_set,
0258         the_packet->Prefix.timeout
0259       );
0260 
0261       if ( the_packet->Prefix.return_code != RTEMS_PROXY_BLOCKING )
0262         _Semaphore_MP_Send_response_packet(
0263            SEMAPHORE_MP_OBTAIN_RESPONSE,
0264            the_packet->Prefix.id,
0265            _Thread_Executing
0266         );
0267       break;
0268 
0269     case SEMAPHORE_MP_OBTAIN_RESPONSE:
0270     case SEMAPHORE_MP_RELEASE_RESPONSE:
0271 
0272       the_thread = _MPCI_Process_response( the_packet_prefix );
0273 
0274       _MPCI_Return_packet( the_packet_prefix );
0275       break;
0276 
0277     case SEMAPHORE_MP_RELEASE_REQUEST:
0278 
0279       the_packet->Prefix.return_code = rtems_semaphore_release(
0280         the_packet->Prefix.id
0281       );
0282 
0283       _Semaphore_MP_Send_response_packet(
0284         SEMAPHORE_MP_RELEASE_RESPONSE,
0285         the_packet->Prefix.id,
0286         _Thread_Executing
0287       );
0288       break;
0289   }
0290 }
0291 
0292 void _Semaphore_MP_Send_object_was_deleted (
0293   Thread_Control *the_proxy,
0294   Objects_Id      mp_id
0295 )
0296 {
0297   the_proxy->receive_packet->return_code = RTEMS_OBJECT_WAS_DELETED;
0298 
0299   _Semaphore_MP_Send_response_packet(
0300     SEMAPHORE_MP_OBTAIN_RESPONSE,
0301     mp_id,
0302     the_proxy
0303   );
0304 
0305 }
0306 
0307 void _Semaphore_MP_Send_extract_proxy (
0308   Thread_Control *the_thread,
0309   Objects_Id      id
0310 )
0311 {
0312   _Semaphore_MP_Send_process_packet(
0313     SEMAPHORE_MP_EXTRACT_PROXY,
0314     id,
0315     (rtems_name) 0,
0316     the_thread->Object.id
0317   );
0318 
0319 }
0320 
0321 void  _Semaphore_Core_mutex_mp_support (
0322   Thread_Control *the_thread,
0323   Objects_Id      id
0324 )
0325 {
0326   the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
0327 
0328   _Semaphore_MP_Send_response_packet(
0329      SEMAPHORE_MP_OBTAIN_RESPONSE,
0330      id,
0331      the_thread
0332    );
0333 }
0334 
0335 void  _Semaphore_Core_semaphore_mp_support (
0336   Thread_Control *the_thread,
0337   Objects_Id      id
0338 )
0339 {
0340   the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
0341 
0342   _Semaphore_MP_Send_response_packet(
0343      SEMAPHORE_MP_OBTAIN_RESPONSE,
0344      id,
0345      the_thread
0346    );
0347 }
0348 
0349 static void _Semaphore_MP_Initialize( void )
0350 {
0351   _MPCI_Register_packet_processor(
0352     MP_PACKET_SEMAPHORE,
0353     _Semaphore_MP_Process_packet
0354   );
0355 }
0356 
0357 RTEMS_SYSINIT_ITEM(
0358   _Semaphore_MP_Initialize,
0359   RTEMS_SYSINIT_CLASSIC_SEMAPHORE_MP,
0360   RTEMS_SYSINIT_ORDER_MIDDLE
0361 );