void *_Freechain_Get( Freechain_Control *freechain, Freechain_Allocator allocator, size_t number_nodes_to_extend, size_t node_size ) { _Assert( node_size >= sizeof( Chain_Node ) ); if ( _Chain_Is_empty( &freechain->Free ) && number_nodes_to_extend > 0 ) { void *starting_address; starting_address = ( *allocator )( number_nodes_to_extend * node_size ); number_nodes_to_extend *= ( starting_address != NULL ); _Chain_Initialize( &freechain->Free, starting_address, number_nodes_to_extend, node_size ); } return _Chain_Get_unprotected( &freechain->Free ); }
void _POSIX_signals_Manager_Initialization(void) { uint32_t signo; uint32_t maximum_queued_signals; maximum_queued_signals = Configuration_POSIX_API.maximum_queued_signals; memcpy( _POSIX_signals_Vectors, _POSIX_signals_Default_vectors, sizeof( _POSIX_signals_Vectors ) ); /* * Initialize the set of pending signals for the entire process */ sigemptyset( &_POSIX_signals_Pending ); /* * Initialize the queue we use to block for signals */ _Thread_queue_Initialize( &_POSIX_signals_Wait_queue, THREAD_QUEUE_DISCIPLINE_FIFO, STATES_WAITING_FOR_SIGNAL | STATES_INTERRUPTIBLE_BY_SIGNAL, EAGAIN ); /* XXX status codes */ /* * Allocate the siginfo pools. */ for ( signo=1 ; signo<= SIGRTMAX ; signo++ ) _Chain_Initialize_empty( &_POSIX_signals_Siginfo[ signo ] ); if ( maximum_queued_signals ) { _Chain_Initialize( &_POSIX_signals_Inactive_siginfo, _Workspace_Allocate_or_fatal_error( maximum_queued_signals * sizeof( POSIX_signals_Siginfo_node ) ), maximum_queued_signals, sizeof( POSIX_signals_Siginfo_node ) ); } else { _Chain_Initialize_empty( &_POSIX_signals_Inactive_siginfo ); } }
void FillLinePool( void ) { void *pool; #define LINE_POOL_FILL_COUNT 100 pool = malloc( sizeof( Line_Control ) * LINE_POOL_FILL_COUNT ); assert( pool ); _Chain_Initialize( &Line_Pool, pool, LINE_POOL_FILL_COUNT, sizeof( Line_Control ) ); }
static void _POSIX_Keys_Initialize_keypool( void ) { Freechain_Control *keypool = &_POSIX_Keys_Keypool; size_t initial_count = _POSIX_Keys_Get_initial_keypool_size(); _Freechain_Initialize( keypool, _POSIX_Keys_Keypool_extend ); if ( initial_count > 0 ) { size_t size = initial_count * sizeof( POSIX_Keys_Key_value_pair ); POSIX_Keys_Key_value_pair *nodes = _Workspace_Allocate_or_fatal_error( size ); _Chain_Initialize( &keypool->Freechain, nodes, initial_count, sizeof( *nodes ) ); } }
static bool _POSIX_Keys_Keypool_extend( Freechain_Control *keypool ) { size_t bump_count = _POSIX_Keys_Get_keypool_bump_count(); bool ok = bump_count > 0; if ( ok ) { size_t size = bump_count * sizeof( POSIX_Keys_Key_value_pair ); POSIX_Keys_Key_value_pair *nodes = _Workspace_Allocate( size ); ok = nodes != NULL; if ( ok ) { _Chain_Initialize( &keypool->Freechain, nodes, bump_count, sizeof( *nodes ) ); } } return ok; }
void _Freechain_Initialize( Freechain_Control *freechain, Freechain_Allocator allocator, size_t number_nodes, size_t node_size ) { void *starting_address; if ( number_nodes > 0 ) { starting_address = ( *allocator )( number_nodes * node_size ); number_nodes *= ( starting_address != NULL ); } else { starting_address = NULL; } _Chain_Initialize( &freechain->Free, starting_address, number_nodes, node_size ); }
void _Thread_MP_Handler_initialization ( uint32_t maximum_proxies ) { _Chain_Initialize_empty( &_Thread_MP_Active_proxies ); if ( maximum_proxies == 0 ) { _Chain_Initialize_empty( &_Thread_MP_Inactive_proxies ); return; } _Chain_Initialize( &_Thread_MP_Inactive_proxies, _Workspace_Allocate_or_fatal_error( maximum_proxies * sizeof( Thread_Proxy_control ) ), maximum_proxies, sizeof( Thread_Proxy_control ) ); }
void _Thread_MP_Handler_initialization ( uint32_t maximum_proxies ) { size_t proxy_size; size_t alloc_size; char *proxies; uint32_t i; if ( maximum_proxies == 0 ) { return; } proxy_size = sizeof( Thread_Proxy_control ) + THREAD_QUEUE_HEADS_SIZE( _Scheduler_Count ); alloc_size = maximum_proxies * proxy_size; proxies = _Workspace_Allocate_or_fatal_error( alloc_size ); memset( proxies, 0, alloc_size ); _Chain_Initialize( &_Thread_MP_Inactive_proxies, proxies, maximum_proxies, proxy_size ); for ( i = 0 ; i < maximum_proxies ; ++i ) { Thread_Proxy_control *proxy; proxy = (Thread_Proxy_control *) ( proxies + i * proxy_size ); _Thread_Timer_initialize( &proxy->Timer, _Per_CPU_Get_by_index( 0 ) ); proxy->Wait.spare_heads = &proxy->Thread_queue_heads[ 0 ]; _Thread_queue_Heads_initialize( proxy->Wait.spare_heads ); } }
void _Objects_MP_Handler_initialization(void) { uint32_t maximum_global_objects; maximum_global_objects = _Configuration_MP_table->maximum_global_objects; _Objects_MP_Maximum_global_objects = maximum_global_objects; if ( maximum_global_objects == 0 ) { _Chain_Initialize_empty( &_Objects_MP_Inactive_global_objects ); return; } _Chain_Initialize( &_Objects_MP_Inactive_global_objects, _Workspace_Allocate_or_fatal_error( maximum_global_objects * sizeof( Objects_MP_Control ) ), maximum_global_objects, sizeof( Objects_MP_Control ) ); }
void _Objects_Extend_information( Objects_Information *information ) { Objects_Control *the_object; Chain_Control Inactive; uint32_t block_count; uint32_t block; uint32_t index_base; uint32_t minimum_index; uint32_t index; uint32_t maximum; size_t block_size; void *new_object_block; bool do_extend; /* * Search for a free block of indexes. If we do NOT need to allocate or * extend the block table, then we will change do_extend. */ do_extend = true; minimum_index = _Objects_Get_index( information->minimum_id ); index_base = minimum_index; block = 0; /* if ( information->maximum < minimum_index ) */ if ( information->object_blocks == NULL ) block_count = 0; else { block_count = information->maximum / information->allocation_size; for ( ; block < block_count; block++ ) { if ( information->object_blocks[ block ] == NULL ) { do_extend = false; break; } else index_base += information->allocation_size; } } maximum = (uint32_t) information->maximum + information->allocation_size; /* * We need to limit the number of objects to the maximum number * representable in the index portion of the object Id. In the * case of 16-bit Ids, this is only 256 object instances. */ if ( maximum > OBJECTS_ID_FINAL_INDEX ) { return; } /* * Allocate the name table, and the objects and if it fails either return or * generate a fatal error depending on auto-extending being active. */ block_size = information->allocation_size * information->size; if ( information->auto_extend ) { new_object_block = _Workspace_Allocate( block_size ); if ( !new_object_block ) return; } else { new_object_block = _Workspace_Allocate_or_fatal_error( block_size ); } /* * Do we need to grow the tables? */ if ( do_extend ) { ISR_Level level; void **object_blocks; uint32_t *inactive_per_block; Objects_Control **local_table; void *old_tables; size_t block_size; /* * Growing the tables means allocating a new area, doing a copy and * updating the information table. * * If the maximum is minimum we do not have a table to copy. First * time through. * * The allocation has : * * void *objects[block_count]; * uint32_t inactive_count[block_count]; * Objects_Control *local_table[maximum]; * * This is the order in memory. Watch changing the order. See the memcpy * below. */ /* * Up the block count and maximum */ block_count++; /* * Allocate the tables and break it up. */ block_size = block_count * (sizeof(void *) + sizeof(uint32_t) + sizeof(Objects_Name *)) + ((maximum + minimum_index) * sizeof(Objects_Control *)); object_blocks = (void**) _Workspace_Allocate( block_size ); if ( !object_blocks ) { _Workspace_Free( new_object_block ); return; } /* * Break the block into the various sections. */ inactive_per_block = (uint32_t *) _Addresses_Add_offset( object_blocks, block_count * sizeof(void*) ); local_table = (Objects_Control **) _Addresses_Add_offset( inactive_per_block, block_count * sizeof(uint32_t) ); /* * Take the block count down. Saves all the (block_count - 1) * in the copies. */ block_count--; if ( information->maximum > minimum_index ) { /* * Copy each section of the table over. This has to be performed as * separate parts as size of each block has changed. */ memcpy( object_blocks, information->object_blocks, block_count * sizeof(void*) ); memcpy( inactive_per_block, information->inactive_per_block, block_count * sizeof(uint32_t) ); memcpy( local_table, information->local_table, (information->maximum + minimum_index) * sizeof(Objects_Control *) ); } else { /* * Deal with the special case of the 0 to minimum_index */ for ( index = 0; index < minimum_index; index++ ) { local_table[ index ] = NULL; } } /* * Initialise the new entries in the table. */ object_blocks[block_count] = NULL; inactive_per_block[block_count] = 0; for ( index=index_base ; index < ( information->allocation_size + index_base ); index++ ) { local_table[ index ] = NULL; } _ISR_Disable( level ); old_tables = information->object_blocks; information->object_blocks = object_blocks; information->inactive_per_block = inactive_per_block; information->local_table = local_table; information->maximum = (Objects_Maximum) maximum; information->maximum_id = _Objects_Build_id( information->the_api, information->the_class, _Objects_Local_node, information->maximum ); _ISR_Enable( level ); _Workspace_Free( old_tables ); block_count++; } /* * Assign the new object block to the object block table. */ information->object_blocks[ block ] = new_object_block; /* * Initialize objects .. add to a local chain first. */ _Chain_Initialize( &Inactive, information->object_blocks[ block ], information->allocation_size, information->size ); /* * Move from the local chain, initialise, then append to the inactive chain */ index = index_base; while ((the_object = (Objects_Control *) _Chain_Get( &Inactive )) != NULL ) { the_object->id = _Objects_Build_id( information->the_api, information->the_class, _Objects_Local_node, index ); _Chain_Append( &information->Inactive, &the_object->Node ); index++; } information->inactive_per_block[ block ] = information->allocation_size; information->inactive = (Objects_Maximum)(information->inactive + information->allocation_size); }
rtems_status_code rtems_partition_create( rtems_name name, void *starting_address, uint32_t length, uint32_t buffer_size, rtems_attribute attribute_set, rtems_id *id ) { register Partition_Control *the_partition; if ( !rtems_is_name_valid( name ) ) return RTEMS_INVALID_NAME; if ( !starting_address ) return RTEMS_INVALID_ADDRESS; if ( !id ) return RTEMS_INVALID_ADDRESS; if ( length == 0 || buffer_size == 0 || length < buffer_size || !_Partition_Is_buffer_size_aligned( buffer_size ) ) return RTEMS_INVALID_SIZE; if ( !_Addresses_Is_aligned( starting_address ) ) return RTEMS_INVALID_ADDRESS; #if defined(RTEMS_MULTIPROCESSING) if ( _Attributes_Is_global( attribute_set ) && !_System_state_Is_multiprocessing ) return RTEMS_MP_NOT_CONFIGURED; #endif _Thread_Disable_dispatch(); /* prevents deletion */ the_partition = _Partition_Allocate(); if ( !the_partition ) { _Thread_Enable_dispatch(); return RTEMS_TOO_MANY; } #if defined(RTEMS_MULTIPROCESSING) if ( _Attributes_Is_global( attribute_set ) && !( _Objects_MP_Allocate_and_open( &_Partition_Information, name, the_partition->Object.id, false ) ) ) { _Partition_Free( the_partition ); _Thread_Enable_dispatch(); return RTEMS_TOO_MANY; } #endif the_partition->starting_address = starting_address; the_partition->length = length; the_partition->buffer_size = buffer_size; the_partition->attribute_set = attribute_set; the_partition->number_of_used_blocks = 0; _Chain_Initialize( &the_partition->Memory, starting_address, length / buffer_size, buffer_size ); _Objects_Open( &_Partition_Information, &the_partition->Object, (Objects_Name) name ); *id = the_partition->Object.id; #if defined(RTEMS_MULTIPROCESSING) if ( _Attributes_Is_global( attribute_set ) ) _Partition_MP_Send_process_packet( PARTITION_MP_ANNOUNCE_CREATE, the_partition->Object.id, name, 0 /* Not used */ ); #endif _Thread_Enable_dispatch(); return RTEMS_SUCCESSFUL; }
bool _CORE_message_queue_Initialize( CORE_message_queue_Control *the_message_queue, CORE_message_queue_Attributes *the_message_queue_attributes, uint32_t maximum_pending_messages, size_t maximum_message_size ) { size_t message_buffering_required = 0; size_t allocated_message_size; the_message_queue->maximum_pending_messages = maximum_pending_messages; the_message_queue->number_of_pending_messages = 0; the_message_queue->maximum_message_size = maximum_message_size; _CORE_message_queue_Set_notify( the_message_queue, NULL, NULL ); allocated_message_size = maximum_message_size; /* * Check if allocated_message_size is aligned to uintptr-size boundary. * If not, it will increase allocated_message_size to multiplicity of pointer * size. */ if (allocated_message_size & (sizeof(uintptr_t) - 1)) { allocated_message_size += sizeof(uintptr_t); allocated_message_size &= ~(sizeof(uintptr_t) - 1); } /* * Check for an overflow. It can occur while increasing allocated_message_size * to multiplicity of uintptr_t above. */ if (allocated_message_size < maximum_message_size) return false; /* * Calculate how much total memory is required for message buffering and * check for overflow on the multiplication. */ if ( !size_t_mult32_with_overflow( (size_t) maximum_pending_messages, allocated_message_size + sizeof(CORE_message_queue_Buffer_control), &message_buffering_required ) ) return false; /* * Attempt to allocate the message memory */ the_message_queue->message_buffers = (CORE_message_queue_Buffer *) _Workspace_Allocate( message_buffering_required ); if (the_message_queue->message_buffers == 0) return false; /* * Initialize the pool of inactive messages, pending messages, * and set of waiting threads. */ _Chain_Initialize ( &the_message_queue->Inactive_messages, the_message_queue->message_buffers, (size_t) maximum_pending_messages, allocated_message_size + sizeof( CORE_message_queue_Buffer_control ) ); _Chain_Initialize_empty( &the_message_queue->Pending_messages ); _Thread_queue_Initialize( &the_message_queue->Wait_queue, _CORE_message_queue_Is_priority( the_message_queue_attributes ) ? THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO, STATES_WAITING_FOR_MESSAGE, CORE_MESSAGE_QUEUE_STATUS_TIMEOUT ); return true; }
bool _CORE_message_queue_Initialize( CORE_message_queue_Control *the_message_queue, CORE_message_queue_Attributes *the_message_queue_attributes, uint32_t maximum_pending_messages, size_t maximum_message_size ) { size_t message_buffering_required; size_t allocated_message_size; the_message_queue->maximum_pending_messages = maximum_pending_messages; the_message_queue->number_of_pending_messages = 0; the_message_queue->maximum_message_size = maximum_message_size; _CORE_message_queue_Set_notify( the_message_queue, NULL, NULL ); /* * Round size up to multiple of a pointer for chain init and * check for overflow on adding overhead to each message. */ allocated_message_size = maximum_message_size; if (allocated_message_size & (sizeof(uint32_t) - 1)) { allocated_message_size += sizeof(uint32_t); allocated_message_size &= ~(sizeof(uint32_t) - 1); } if (allocated_message_size < maximum_message_size) return false; /* * Calculate how much total memory is required for message buffering and * check for overflow on the multiplication. */ message_buffering_required = (size_t) maximum_pending_messages * (allocated_message_size + sizeof(CORE_message_queue_Buffer_control)); if (message_buffering_required < allocated_message_size) return false; /* * Attempt to allocate the message memory */ the_message_queue->message_buffers = (CORE_message_queue_Buffer *) _Workspace_Allocate( message_buffering_required ); if (the_message_queue->message_buffers == 0) return false; /* * Initialize the pool of inactive messages, pending messages, * and set of waiting threads. */ _Chain_Initialize ( &the_message_queue->Inactive_messages, the_message_queue->message_buffers, (size_t) maximum_pending_messages, allocated_message_size + sizeof( CORE_message_queue_Buffer_control ) ); _Chain_Initialize_empty( &the_message_queue->Pending_messages ); _Thread_queue_Initialize( &the_message_queue->Wait_queue, _CORE_message_queue_Is_priority( the_message_queue_attributes ) ? THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO, STATES_WAITING_FOR_MESSAGE, CORE_MESSAGE_QUEUE_STATUS_TIMEOUT ); return true; }
bool _CORE_message_queue_Initialize( CORE_message_queue_Control *the_message_queue, CORE_message_queue_Disciplines discipline, uint32_t maximum_pending_messages, size_t maximum_message_size ) { size_t message_buffering_required = 0; size_t aligned_message_size; size_t align_mask; the_message_queue->maximum_pending_messages = maximum_pending_messages; the_message_queue->number_of_pending_messages = 0; the_message_queue->maximum_message_size = maximum_message_size; _CORE_message_queue_Set_notify( the_message_queue, NULL ); /* * Align up the maximum message size to be an integral multiple of the * pointer size. */ align_mask = sizeof(uintptr_t) - 1; aligned_message_size = ( maximum_message_size + align_mask ) & ~align_mask; /* * Check for an integer overflow. It can occur while aligning up the maximum * message size. */ if (aligned_message_size < maximum_message_size) return false; /* * Calculate how much total memory is required for message buffering and * check for overflow on the multiplication. */ if ( !size_t_mult32_with_overflow( (size_t) maximum_pending_messages, aligned_message_size + sizeof(CORE_message_queue_Buffer_control), &message_buffering_required ) ) return false; /* * Attempt to allocate the message memory */ the_message_queue->message_buffers = (CORE_message_queue_Buffer *) _Workspace_Allocate( message_buffering_required ); if (the_message_queue->message_buffers == 0) return false; /* * Initialize the pool of inactive messages, pending messages, * and set of waiting threads. */ _Chain_Initialize ( &the_message_queue->Inactive_messages, the_message_queue->message_buffers, (size_t) maximum_pending_messages, aligned_message_size + sizeof( CORE_message_queue_Buffer_control ) ); _Chain_Initialize_empty( &the_message_queue->Pending_messages ); _Thread_queue_Initialize( &the_message_queue->Wait_queue ); if ( discipline == CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY ) { the_message_queue->operations = &_Thread_queue_Operations_priority; } else { the_message_queue->operations = &_Thread_queue_Operations_FIFO; } return true; }
void _POSIX_signals_Manager_Initialization(void) { uint32_t signo; uint32_t maximum_queued_signals; maximum_queued_signals = Configuration_POSIX_API.maximum_queued_signals; /* * Ensure we have the same number of vectors and default vector entries */ #if defined(RTEMS_DEBUG) assert( sizeof(_POSIX_signals_Vectors) == sizeof(_POSIX_signals_Default_vectors) ); #endif memcpy( _POSIX_signals_Vectors, _POSIX_signals_Default_vectors, sizeof( _POSIX_signals_Vectors ) ); /* * Initialize the set of pending signals for the entire process */ sigemptyset( &_POSIX_signals_Pending ); /* * Initialize the queue we use to block for signals */ _Thread_queue_Initialize( &_POSIX_signals_Wait_queue, THREAD_QUEUE_DISCIPLINE_FIFO, STATES_WAITING_FOR_SIGNAL | STATES_INTERRUPTIBLE_BY_SIGNAL, EAGAIN ); /* XXX status codes */ /* * Allocate the siginfo pools. */ for ( signo=1 ; signo<= SIGRTMAX ; signo++ ) _Chain_Initialize_empty( &_POSIX_signals_Siginfo[ signo ] ); if ( maximum_queued_signals ) { _Chain_Initialize( &_POSIX_signals_Inactive_siginfo, _Workspace_Allocate_or_fatal_error( maximum_queued_signals * sizeof( POSIX_signals_Siginfo_node ) ), maximum_queued_signals, sizeof( POSIX_signals_Siginfo_node ) ); } else { _Chain_Initialize_empty( &_POSIX_signals_Inactive_siginfo ); } /* * Initialize the Alarm Timer */ _Watchdog_Initialize( &_POSIX_signals_Alarm_timer, NULL, 0, NULL ); _Watchdog_Initialize( &_POSIX_signals_Ualarm_timer, NULL, 0, NULL ); }