Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSTestSuitesValidation
0007  *
0008  * @brief This source file contains the implementation of the thread queue
0009  *   wrapper.
0010  */
0011 
0012 /*
0013  * Copyright (C) 2021 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 "tx-support.h"
0042 
0043 #include <rtems/score/threadimpl.h>
0044 #include <rtems/score/threadqimpl.h>
0045 
0046 #include <string.h>
0047 
0048 void WrapThreadQueueInitialize(
0049   WrapThreadQueueContext *ctx,
0050   void                 ( *handler )( void * ),
0051   void                   *arg
0052 )
0053 {
0054   memset( ctx, 0, sizeof( *ctx ) );
0055   ctx->isr_request.handler = handler;
0056   ctx->isr_request.arg = arg;
0057   _Thread_queue_Initialize( &ctx->thread_queue, "Wrap" );
0058 }
0059 
0060 static void Prepare(
0061   WrapThreadQueueContext *ctx,
0062   Thread_Control         *thread
0063 )
0064 {
0065   if ( thread->Wait.queue != NULL ) {
0066     ctx->wrapped_ops = thread->Wait.operations;
0067     thread->Wait.operations = &ctx->tq_ops;
0068   } else {
0069     Thread_queue_Context queue_context;
0070 
0071     ctx->wrapped_ops = NULL;
0072     _Thread_queue_Context_initialize( &queue_context );
0073     _Thread_queue_Acquire( &ctx->thread_queue, &queue_context );
0074     _Thread_Wait_flags_set(
0075       thread,
0076       THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_INTEND_TO_BLOCK
0077     );
0078     _Thread_Wait_claim( thread, &ctx->thread_queue.Queue );
0079     _Thread_Wait_claim_finalize( thread, &ctx->tq_ops );
0080     _Thread_queue_Release( &ctx->thread_queue, &queue_context );
0081   }
0082 }
0083 
0084 static void WrappedExtract(
0085   WrapThreadQueueContext *ctx,
0086   Thread_queue_Queue     *queue,
0087   Thread_Control         *thread,
0088   Thread_queue_Context   *queue_context
0089 )
0090 {
0091   if ( ctx->wrapped_ops ) {
0092     thread->Wait.operations = ctx->wrapped_ops;
0093     ( *thread->Wait.operations->extract )( queue, thread, queue_context );
0094   }
0095 }
0096 
0097 static void Extract(
0098   Thread_queue_Queue   *queue,
0099   Thread_Control       *thread,
0100   Thread_queue_Context *queue_context
0101 )
0102 {
0103   WrapThreadQueueContext *ctx;
0104 
0105   ctx = (WrapThreadQueueContext *) thread->Wait.operations;
0106   CallWithinISRSubmit( &ctx->isr_request );
0107   WrappedExtract( ctx, queue, thread, queue_context );
0108 }
0109 
0110 void WrapThreadQueueExtract(
0111   WrapThreadQueueContext *ctx,
0112   Thread_Control         *thread
0113 )
0114 {
0115   ctx->tq_ops.extract = Extract;
0116   Prepare( ctx, thread );
0117 }
0118 
0119 static void ExtractDirect(
0120   Thread_queue_Queue   *queue,
0121   Thread_Control       *thread,
0122   Thread_queue_Context *queue_context
0123 )
0124 {
0125   WrapThreadQueueContext *ctx;
0126 
0127   ctx = (WrapThreadQueueContext *) thread->Wait.operations;
0128   ( *ctx->isr_request.handler )( ctx->isr_request.arg );
0129   WrappedExtract( ctx, queue, thread, queue_context );
0130 }
0131 
0132 void WrapThreadQueueExtractDirect(
0133   WrapThreadQueueContext *ctx,
0134   Thread_Control         *thread
0135 )
0136 {
0137   ctx->tq_ops.extract = ExtractDirect;
0138   Prepare( ctx, thread );
0139 }
0140 
0141 void WrapThreadQueueDestroy( WrapThreadQueueContext *ctx )
0142 {
0143   _Thread_queue_Destroy( &ctx->thread_queue );
0144 }