File indexing completed on 2025-05-11 08:24:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #ifdef HAVE_CONFIG_H
0039 #include "config.h"
0040 #endif
0041
0042 #include <rtems/rtems/regionimpl.h>
0043 #include <rtems/rtems/optionsimpl.h>
0044 #include <rtems/rtems/statusimpl.h>
0045 #include <rtems/score/threadqimpl.h>
0046 #include <rtems/score/statesimpl.h>
0047
0048 static void _Region_Enqueue_callout(
0049 Thread_queue_Queue *queue,
0050 Thread_Control *the_thread,
0051 Per_CPU_Control *cpu_self,
0052 Thread_queue_Context *queue_context
0053 )
0054 {
0055 Region_Control *the_region;
0056
0057 _Thread_queue_Add_timeout_ticks(
0058 queue,
0059 the_thread,
0060 cpu_self,
0061 queue_context
0062 );
0063
0064 the_region = REGION_OF_THREAD_QUEUE_QUEUE( queue );
0065 _Region_Unlock( the_region );
0066 }
0067
0068 rtems_status_code rtems_region_get_segment(
0069 rtems_id id,
0070 uintptr_t size,
0071 rtems_option option_set,
0072 rtems_interval timeout,
0073 void **segment
0074 )
0075 {
0076 rtems_status_code status;
0077 Region_Control *the_region;
0078
0079 if ( segment == NULL ) {
0080 return RTEMS_INVALID_ADDRESS;
0081 }
0082
0083 *segment = NULL;
0084
0085 if ( size == 0 ) {
0086 return RTEMS_INVALID_SIZE;
0087 }
0088
0089 the_region = _Region_Get_and_lock( id );
0090
0091 if ( the_region == NULL ) {
0092 return RTEMS_INVALID_ID;
0093 }
0094
0095 if ( size > the_region->maximum_segment_size ) {
0096 status = RTEMS_INVALID_SIZE;
0097 } else {
0098 void *the_segment;
0099
0100 the_segment = _Region_Allocate_segment( the_region, size );
0101
0102 if ( the_segment != NULL ) {
0103 *segment = the_segment;
0104 status = RTEMS_SUCCESSFUL;
0105 } else if ( _Options_Is_no_wait( option_set ) ) {
0106 status = RTEMS_UNSATISFIED;
0107 } else {
0108 Thread_queue_Context queue_context;
0109 Thread_Control *executing;
0110
0111 _Thread_queue_Context_initialize( &queue_context );
0112 _Thread_queue_Acquire( &the_region->Wait_queue, &queue_context );
0113
0114 executing = _Thread_Executing;
0115 executing->Wait.count = size;
0116 executing->Wait.return_argument = segment;
0117
0118
0119 _Thread_queue_Context_set_thread_state(
0120 &queue_context,
0121 STATES_WAITING_FOR_SEGMENT
0122 );
0123 _Thread_queue_Context_set_timeout_ticks( &queue_context, timeout );
0124 _Thread_queue_Context_set_enqueue_callout(
0125 &queue_context,
0126 _Region_Enqueue_callout
0127 );
0128 _Thread_queue_Enqueue(
0129 &the_region->Wait_queue.Queue,
0130 the_region->wait_operations,
0131 executing,
0132 &queue_context
0133 );
0134 return _Status_Get_after_wait( executing );
0135 }
0136 }
0137
0138 _Region_Unlock( the_region );
0139 return status;
0140 }