void *rtems_heap_greedy_allocate_all_except_largest( uintptr_t *allocatable_size ) { void *opaque; _RTEMS_Lock_allocator(); opaque = _Heap_Greedy_allocate_all_except_largest( RTEMS_Malloc_Heap, allocatable_size ); _RTEMS_Unlock_allocator(); return opaque; }
void rtems_bsd_chunk_free(rtems_bsd_chunk_control *self, void *some_addr_in_chunk) { rtems_bsd_chunk_info *info = rtems_bsd_chunk_get_info(self, some_addr_in_chunk); _RTEMS_Lock_allocator(); rtems_rbtree_extract(&self->chunks, &info->node); _RTEMS_Unlock_allocator(); (*self->info_dtor)(self, info); free(info, M_TEMP); }
boolean _Protected_heap_Resize_block( Heap_Control *the_heap, void *starting_address, size_t size ) { Heap_Resize_status status; uint32_t old_mem_size; uint32_t avail_mem_size; _RTEMS_Lock_allocator(); status = _Heap_Resize_block( the_heap, starting_address, size, &old_mem_size, &avail_mem_size ); _RTEMS_Unlock_allocator(); return (status == HEAP_RESIZE_SUCCESSFUL); }
bool _Protected_heap_Get_information( Heap_Control *the_heap, Heap_Information_block *the_info ) { if ( !the_heap ) return false; if ( !the_info ) return false; _RTEMS_Lock_allocator(); _Heap_Get_information( the_heap, the_info ); _RTEMS_Unlock_allocator(); return true; }
void _Region_Process_queue( Region_Control *the_region ) { Thread_Control *the_thread; void *the_segment; /* * Switch from using the memory allocation mutex to using a * dispatching disabled critical section. We have to do this * because this thread may unblock one or more threads that were * waiting on memory. * * NOTE: Be sure to disable dispatching before unlocking the mutex * since we do not want to open a window where a context * switch could occur. */ _Thread_Disable_dispatch(); _RTEMS_Unlock_allocator(); /* * NOTE: The following loop is O(n) where n is the number of * threads whose memory request is satisfied. */ for ( ; ; ) { the_thread = _Thread_queue_First( &the_region->Wait_queue ); if ( the_thread == NULL ) break; the_segment = (void **) _Region_Allocate_segment( the_region, the_thread->Wait.count ); if ( the_segment == NULL ) break; *(void **)the_thread->Wait.return_argument = the_segment; the_region->number_of_used_blocks += 1; _Thread_queue_Extract( &the_region->Wait_queue, the_thread ); the_thread->Wait.return_code = RTEMS_SUCCESSFUL; } _Thread_Enable_dispatch(); }
rtems_status_code rtems_region_get_free_information( rtems_id id, Heap_Information_block *the_info ) { Objects_Locations location; rtems_status_code return_status; Region_Control *the_region; if ( !the_info ) return RTEMS_INVALID_ADDRESS; _RTEMS_Lock_allocator(); the_region = _Region_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: the_info->Used.number = 0; the_info->Used.total = 0; the_info->Used.largest = 0; _Heap_Get_free_information( &the_region->Memory, &the_info->Free ); return_status = RTEMS_SUCCESSFUL; break; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* this error cannot be returned */ break; #endif case OBJECTS_ERROR: default: return_status = RTEMS_INVALID_ID; break; } _RTEMS_Unlock_allocator(); return return_status; }
void *_Protected_heap_Allocate_aligned_with_boundary( Heap_Control *heap, uintptr_t size, uintptr_t alignment, uintptr_t boundary ) { void *p; _RTEMS_Lock_allocator(); p = _Heap_Allocate_aligned_with_boundary( heap, size, alignment, boundary ); _RTEMS_Unlock_allocator(); return p; }
void * rtems_bsd_chunk_alloc(rtems_bsd_chunk_control *self, uintptr_t chunk_size) { char *p = rtems_cache_aligned_malloc(chunk_size + self->info_size); if (p != NULL) { rtems_bsd_chunk_info *info = (rtems_bsd_chunk_info *) p; p += self->info_size; info->begin = (uintptr_t) p; info->end = (uintptr_t) p + chunk_size; (*self->info_ctor)(self, info); _RTEMS_Lock_allocator(); rtems_rbtree_insert(&self->chunks, &info->node, chunk_compare, true); _RTEMS_Unlock_allocator(); } return p; }
rtems_status_code rtems_region_get_segment_size( rtems_id id, void *segment, uintptr_t *size ) { Objects_Locations location; rtems_status_code return_status = RTEMS_SUCCESSFUL; register Region_Control *the_region; if ( !segment ) return RTEMS_INVALID_ADDRESS; if ( !size ) return RTEMS_INVALID_ADDRESS; _RTEMS_Lock_allocator(); the_region = _Region_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: if ( !_Heap_Size_of_alloc_area( &the_region->Memory, segment, size ) ) return_status = RTEMS_INVALID_ADDRESS; break; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* this error cannot be returned */ break; #endif case OBJECTS_ERROR: return_status = RTEMS_INVALID_ID; break; } _RTEMS_Unlock_allocator(); return return_status; }
rtems_status_code rtems_region_delete( rtems_id id ) { Objects_Locations location; rtems_status_code return_status; Region_Control *the_region; _RTEMS_Lock_allocator(); the_region = _Region_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: _Region_Debug_Walk( the_region, 5 ); if ( the_region->number_of_used_blocks != 0 ) return_status = RTEMS_RESOURCE_IN_USE; else { _Objects_Close( &_Region_Information, &the_region->Object ); _Region_Free( the_region ); return_status = RTEMS_SUCCESSFUL; } break; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* this error cannot be returned */ break; #endif case OBJECTS_ERROR: default: return_status = RTEMS_INVALID_ID; break; } _RTEMS_Unlock_allocator(); return return_status; }
void rtems_cache_coherent_free( void *ptr ) { Heap_Control *heap; _RTEMS_Lock_allocator(); heap = cache_coherent_heap; if ( heap != NULL ) { if ( _Heap_Free( heap, ptr ) ) { heap = NULL; } else { heap = RTEMS_Malloc_Heap; } } else { heap = RTEMS_Malloc_Heap; } if ( heap != NULL ) { _Heap_Free( heap, ptr ); } _RTEMS_Unlock_allocator(); }
void rtems_resource_snapshot_take(rtems_resource_snapshot *snapshot) { uint32_t *active = &snapshot->active_posix_keys; size_t i; memset(snapshot, 0, sizeof(*snapshot)); _RTEMS_Lock_allocator(); _Thread_Kill_zombies(); get_heap_info(RTEMS_Malloc_Heap, &snapshot->heap_info); get_heap_info(&_Workspace_Area, &snapshot->workspace_info); for (i = 0; i < RTEMS_ARRAY_SIZE(objects_info_table); ++i) { active [i] = _Objects_Active_count(objects_info_table[i]); } _RTEMS_Unlock_allocator(); snapshot->active_posix_key_value_pairs = get_active_posix_key_value_pairs(); snapshot->open_files = open_files(); }
bool _Protected_heap_Walk( Heap_Control *the_heap, int source, bool do_dump ) { bool status; /* * If we are called from within a dispatching critical section, * then it is forbidden to lock a mutex. But since we are inside * a critical section, it should be safe to walk it unlocked. * * NOTE: Dispatching is also disabled during initialization. */ if ( !_Thread_Dispatch_disable_level ) { _RTEMS_Lock_allocator(); status = _Heap_Walk( the_heap, source, do_dump ); _RTEMS_Unlock_allocator(); } else { status = _Heap_Walk( the_heap, source, do_dump ); } return status; }
void bsp_interrupt_unlock(void) { if (_System_state_Is_up(_System_state_Get())) { _RTEMS_Unlock_allocator(); } }
int pthread_create( pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)( void * ), void *arg ) { const pthread_attr_t *the_attr; Priority_Control core_priority; Thread_CPU_budget_algorithms budget_algorithm; Thread_CPU_budget_algorithm_callout budget_callout; bool is_fp; bool status; Thread_Control *the_thread; POSIX_API_Control *api; int schedpolicy = SCHED_RR; struct sched_param schedparam; Objects_Name name; int rc; if ( !start_routine ) return EFAULT; the_attr = (attr) ? attr : &_POSIX_Threads_Default_attributes; if ( !the_attr->is_initialized ) return EINVAL; /* * Core Thread Initialize ensures we get the minimum amount of * stack space if it is allowed to allocate it itself. * * NOTE: If the user provides the stack we will let it drop below * twice the minimum. */ if ( the_attr->stackaddr && !_Stack_Is_enough(the_attr->stacksize) ) return EINVAL; #if 0 int cputime_clock_allowed; /* see time.h */ rtems_set_errno_and_return_minus_one( ENOSYS ); #endif /* * P1003.1c/Draft 10, p. 121. * * If inheritsched is set to PTHREAD_INHERIT_SCHED, then this thread * inherits scheduling attributes from the creating thread. If it is * PTHREAD_EXPLICIT_SCHED, then scheduling parameters come from the * attributes structure. */ switch ( the_attr->inheritsched ) { case PTHREAD_INHERIT_SCHED: api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; schedpolicy = api->schedpolicy; schedparam = api->schedparam; break; case PTHREAD_EXPLICIT_SCHED: schedpolicy = the_attr->schedpolicy; schedparam = the_attr->schedparam; break; default: return EINVAL; } /* * Check the contentionscope since rtems only supports PROCESS wide * contention (i.e. no system wide contention). */ if ( the_attr->contentionscope != PTHREAD_SCOPE_PROCESS ) return ENOTSUP; /* * Interpret the scheduling parameters. */ if ( !_POSIX_Priority_Is_valid( schedparam.sched_priority ) ) return EINVAL; core_priority = _POSIX_Priority_To_core( schedparam.sched_priority ); /* * Set the core scheduling policy information. */ rc = _POSIX_Thread_Translate_sched_param( schedpolicy, &schedparam, &budget_algorithm, &budget_callout ); if ( rc ) return rc; /* * Currently all POSIX threads are floating point if the hardware * supports it. */ #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) is_fp = true; #else is_fp = false; #endif /* * Lock the allocator mutex for protection */ _RTEMS_Lock_allocator(); /* * Allocate the thread control block. * * NOTE: Global threads are not currently supported. */ the_thread = _POSIX_Threads_Allocate(); if ( !the_thread ) { _RTEMS_Unlock_allocator(); return EAGAIN; } /* * Initialize the core thread for this task. */ name.name_p = NULL; /* posix threads don't have a name by default */ status = _Thread_Initialize( &_POSIX_Threads_Information, the_thread, the_attr->stackaddr, _POSIX_Threads_Ensure_minimum_stack(the_attr->stacksize), is_fp, core_priority, true, /* preemptible */ budget_algorithm, budget_callout, 0, /* isr level */ name /* posix threads don't have a name */ ); if ( !status ) { _POSIX_Threads_Free( the_thread ); _RTEMS_Unlock_allocator(); return EAGAIN; } /* * finish initializing the per API structure */ api = the_thread->API_Extensions[ THREAD_API_POSIX ]; api->Attributes = *the_attr; api->detachstate = the_attr->detachstate; api->schedpolicy = schedpolicy; api->schedparam = schedparam; /* * This insures we evaluate the process-wide signals pending when we * first run. * * NOTE: Since the thread starts with all unblocked, this is necessary. */ the_thread->do_post_task_switch_extension = true; /* * POSIX threads are allocated and started in one operation. */ status = _Thread_Start( the_thread, THREAD_START_POINTER, start_routine, arg, 0 /* unused */ ); #if defined(RTEMS_DEBUG) /* * _Thread_Start only fails if the thread was in the incorrect state * * NOTE: This can only happen if someone slips in and touches the * thread while we are creating it. */ if ( !status ) { _POSIX_Threads_Free( the_thread ); _RTEMS_Unlock_allocator(); return EINVAL; } #endif if ( schedpolicy == SCHED_SPORADIC ) { _Watchdog_Insert_ticks( &api->Sporadic_timer, _Timespec_To_ticks( &api->schedparam.sched_ss_repl_period ) ); } /* * Return the id and indicate we successfully created the thread */ *thread = the_thread->Object.id; _RTEMS_Unlock_allocator(); return 0; }
void _POSIX_Thread_Exit( Thread_Control *the_thread, void *value_ptr ) { Objects_Information *the_information; Thread_Control *unblocked; POSIX_API_Control *api; the_information = _Objects_Get_information_id( the_thread->Object.id ); api = the_thread->API_Extensions[ THREAD_API_POSIX ]; /* * The_information has to be non-NULL. Otherwise, we couldn't be * running in a thread of this API and class. * * NOTE: Lock and unlock in different order so we do not throw a * fatal error when locking the allocator mutex. And after * we unlock, we want to defer the context switch until we * are ready to be switched out. Otherwise, an ISR could * occur and preempt us out while we still hold the * allocator mutex. */ _RTEMS_Lock_allocator(); _Thread_Disable_dispatch(); the_thread->Wait.return_argument = value_ptr; /* * Process join */ if ( api->detachstate == PTHREAD_CREATE_JOINABLE ) { unblocked = _Thread_queue_Dequeue( &api->Join_List ); if ( unblocked ) { do { *(void **)unblocked->Wait.return_argument = value_ptr; } while ( (unblocked = _Thread_queue_Dequeue( &api->Join_List )) ); } else { _Thread_Set_state( the_thread, STATES_WAITING_FOR_JOIN_AT_EXIT | STATES_TRANSIENT ); _RTEMS_Unlock_allocator(); _Thread_Enable_dispatch(); /* now waiting for thread to arrive */ _RTEMS_Lock_allocator(); _Thread_Disable_dispatch(); } } /* * Now shut down the thread */ _Thread_Close( the_information, the_thread ); _POSIX_Threads_Free( the_thread ); _RTEMS_Unlock_allocator(); _Thread_Enable_dispatch(); }
rtems_status_code rtems_region_get_segment( Objects_Id id, uint32_t size, rtems_option option_set, rtems_interval timeout, void **segment ) { register Region_Control *the_region; Objects_Locations location; Thread_Control *executing; void *the_segment; if ( !segment ) return RTEMS_INVALID_ADDRESS; *segment = NULL; if ( size == 0 ) return RTEMS_INVALID_SIZE; _RTEMS_Lock_allocator(); executing = _Thread_Executing; the_region = _Region_Get( id, &location ); switch ( location ) { case OBJECTS_REMOTE: /* this error cannot be returned */ _RTEMS_Unlock_allocator(); return RTEMS_INTERNAL_ERROR; case OBJECTS_ERROR: _RTEMS_Unlock_allocator(); return RTEMS_INVALID_ID; case OBJECTS_LOCAL: if ( size > the_region->maximum_segment_size ) { _RTEMS_Unlock_allocator(); return RTEMS_INVALID_SIZE; } _Region_Debug_Walk( the_region, 1 ); the_segment = _Region_Allocate_segment( the_region, size ); _Region_Debug_Walk( the_region, 2 ); if ( the_segment ) { the_region->number_of_used_blocks += 1; _RTEMS_Unlock_allocator(); *segment = the_segment; return RTEMS_SUCCESSFUL; } if ( _Options_Is_no_wait( option_set ) ) { _RTEMS_Unlock_allocator(); return RTEMS_UNSATISFIED; } /* * Switch from using the memory allocation mutex to using a * dispatching disabled critical section. We have to do this * because this thread is going to block. */ _Thread_Disable_dispatch(); _RTEMS_Unlock_allocator(); executing->Wait.queue = &the_region->Wait_queue; executing->Wait.id = id; executing->Wait.count = size; executing->Wait.return_argument = segment; _Thread_queue_Enter_critical_section( &the_region->Wait_queue ); _Thread_queue_Enqueue( &the_region->Wait_queue, timeout ); _Thread_Enable_dispatch(); return (rtems_status_code) executing->Wait.return_code; } return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ }
rtems_status_code rtems_region_get_segment( rtems_id id, uintptr_t size, rtems_option option_set, rtems_interval timeout, void **segment ) { Thread_Control *executing; Objects_Locations location; rtems_status_code return_status; Region_Control *the_region; void *the_segment; if ( !segment ) return RTEMS_INVALID_ADDRESS; *segment = NULL; if ( size == 0 ) return RTEMS_INVALID_SIZE; _RTEMS_Lock_allocator(); executing = _Thread_Get_executing(); the_region = _Region_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: if ( size > the_region->maximum_segment_size ) return_status = RTEMS_INVALID_SIZE; else { _Region_Debug_Walk( the_region, 1 ); the_segment = _Region_Allocate_segment( the_region, size ); _Region_Debug_Walk( the_region, 2 ); if ( the_segment ) { the_region->number_of_used_blocks += 1; *segment = the_segment; return_status = RTEMS_SUCCESSFUL; } else if ( _Options_Is_no_wait( option_set ) ) { return_status = RTEMS_UNSATISFIED; } else { /* * Switch from using the memory allocation mutex to using a * dispatching disabled critical section. We have to do this * because this thread is going to block. */ /* FIXME: Lock order reversal */ _Thread_Disable_dispatch(); _RTEMS_Unlock_allocator(); executing->Wait.queue = &the_region->Wait_queue; executing->Wait.id = id; executing->Wait.count = size; executing->Wait.return_argument = segment; _Thread_queue_Enter_critical_section( &the_region->Wait_queue ); _Thread_queue_Enqueue( &the_region->Wait_queue, executing, timeout ); _Objects_Put( &the_region->Object ); return (rtems_status_code) executing->Wait.return_code; } } break; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* this error cannot be returned */ break; #endif case OBJECTS_ERROR: default: return_status = RTEMS_INVALID_ID; break; } _RTEMS_Unlock_allocator(); return return_status; }
rtems_status_code rtems_task_delete( rtems_id id ) { register Thread_Control *the_thread; Objects_Locations location; Objects_Information *the_information; #if defined( RTEMS_SMP ) if ( rtems_configuration_is_smp_enabled() ) { return RTEMS_NOT_IMPLEMENTED; } #endif _RTEMS_Lock_allocator(); the_thread = _Thread_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: the_information = _Objects_Get_information_id( the_thread->Object.id ); #if defined(RTEMS_DEBUG) if ( !the_information ) { _Objects_Put( &the_thread->Object ); return RTEMS_INVALID_ID; /* This should never happen if _Thread_Get() works right */ } #endif #if defined(RTEMS_MULTIPROCESSING) if ( the_thread->is_global ) { _Objects_MP_Close( &_RTEMS_tasks_Information, the_thread->Object.id ); _RTEMS_tasks_MP_Send_process_packet( RTEMS_TASKS_MP_ANNOUNCE_DELETE, the_thread->Object.id, 0 /* Not used */ ); } #endif _Thread_Close( the_information, the_thread ); _RTEMS_tasks_Free( the_thread ); /* FIXME: Lock order reversal */ _RTEMS_Unlock_allocator(); _Objects_Put( &the_thread->Object ); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: _RTEMS_Unlock_allocator(); _Thread_Dispatch(); return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; #endif case OBJECTS_ERROR: break; } _RTEMS_Unlock_allocator(); return RTEMS_INVALID_ID; }
rtems_status_code rtems_region_create( rtems_name name, void *starting_address, uintptr_t length, uintptr_t page_size, rtems_attribute attribute_set, rtems_id *id ) { rtems_status_code return_status; Region_Control *the_region; if ( !rtems_is_name_valid( name ) ) return RTEMS_INVALID_NAME; if ( !starting_address ) return RTEMS_INVALID_ADDRESS; if ( !id ) return RTEMS_INVALID_ADDRESS; _RTEMS_Lock_allocator(); /* to prevent deletion */ the_region = _Region_Allocate(); if ( !the_region ) return_status = RTEMS_TOO_MANY; else { the_region->maximum_segment_size = _Heap_Initialize( &the_region->Memory, starting_address, length, page_size ); if ( !the_region->maximum_segment_size ) { _Region_Free( the_region ); return_status = RTEMS_INVALID_SIZE; } else { the_region->starting_address = starting_address; the_region->length = length; the_region->page_size = page_size; the_region->attribute_set = attribute_set; the_region->number_of_used_blocks = 0; _Thread_queue_Initialize( &the_region->Wait_queue, _Attributes_Is_priority( attribute_set ) ? THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO, STATES_WAITING_FOR_SEGMENT, RTEMS_TIMEOUT ); _Objects_Open( &_Region_Information, &the_region->Object, (Objects_Name) name ); *id = the_region->Object.id; return_status = RTEMS_SUCCESSFUL; } } _RTEMS_Unlock_allocator(); return return_status; }
rtems_status_code rtems_task_create( rtems_name name, rtems_task_priority initial_priority, size_t stack_size, rtems_mode initial_modes, rtems_attribute attribute_set, rtems_id *id ) { register Thread_Control *the_thread; bool is_fp; #if defined(RTEMS_MULTIPROCESSING) Objects_MP_Control *the_global_object = NULL; bool is_global; #endif bool status; rtems_attribute the_attribute_set; Priority_Control core_priority; RTEMS_API_Control *api; ASR_Information *asr; if ( !id ) return RTEMS_INVALID_ADDRESS; if ( !rtems_is_name_valid( name ) ) return RTEMS_INVALID_NAME; /* * Core Thread Initialize insures we get the minimum amount of * stack space. */ /* * Fix the attribute set to match the attributes which * this processor (1) requires and (2) is able to support. * First add in the required flags for attribute_set * Typically this might include FP if the platform * or application required all tasks to be fp aware. * Then turn off the requested bits which are not supported. */ the_attribute_set = _Attributes_Set( attribute_set, ATTRIBUTES_REQUIRED ); the_attribute_set = _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED ); if ( _Attributes_Is_floating_point( the_attribute_set ) ) is_fp = true; else is_fp = false; /* * Validate the RTEMS API priority and convert it to the core priority range. */ if ( !_Attributes_Is_system_task( the_attribute_set ) ) { if ( !_RTEMS_tasks_Priority_is_valid( initial_priority ) ) return RTEMS_INVALID_PRIORITY; } core_priority = _RTEMS_tasks_Priority_to_Core( initial_priority ); #if defined(RTEMS_MULTIPROCESSING) if ( _Attributes_Is_global( the_attribute_set ) ) { is_global = true; if ( !_System_state_Is_multiprocessing ) return RTEMS_MP_NOT_CONFIGURED; } else is_global = false; #endif /* * Make sure system is MP if this task is global */ /* * Lock the allocator mutex for protection */ _RTEMS_Lock_allocator(); /* * Allocate the thread control block and -- if the task is global -- * allocate a global object control block. * * NOTE: This routine does not use the combined allocate and open * global object routine because this results in a lack of * control over when memory is allocated and can be freed in * the event of an error. */ the_thread = _RTEMS_tasks_Allocate(); if ( !the_thread ) { _RTEMS_Unlock_allocator(); return RTEMS_TOO_MANY; } #if defined(RTEMS_MULTIPROCESSING) if ( is_global ) { the_global_object = _Objects_MP_Allocate_global_object(); if ( _Objects_MP_Is_null_global_object( the_global_object ) ) { _RTEMS_tasks_Free( the_thread ); _RTEMS_Unlock_allocator(); return RTEMS_TOO_MANY; } } #endif /* * Initialize the core thread for this task. */ status = _Thread_Initialize( &_RTEMS_tasks_Information, the_thread, NULL, stack_size, is_fp, core_priority, _Modes_Is_preempt(initial_modes) ? true : false, _Modes_Is_timeslice(initial_modes) ? THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE : THREAD_CPU_BUDGET_ALGORITHM_NONE, NULL, /* no budget algorithm callout */ _Modes_Get_interrupt_level(initial_modes), (Objects_Name) name ); if ( !status ) { #if defined(RTEMS_MULTIPROCESSING) if ( is_global ) _Objects_MP_Free_global_object( the_global_object ); #endif _RTEMS_tasks_Free( the_thread ); _RTEMS_Unlock_allocator(); return RTEMS_UNSATISFIED; } api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; asr = &api->Signal; asr->is_enabled = _Modes_Is_asr_disabled(initial_modes) ? false : true; *id = the_thread->Object.id; #if defined(RTEMS_MULTIPROCESSING) the_thread->is_global = is_global; if ( is_global ) { _Objects_MP_Open( &_RTEMS_tasks_Information, the_global_object, name, the_thread->Object.id ); _RTEMS_tasks_MP_Send_process_packet( RTEMS_TASKS_MP_ANNOUNCE_CREATE, the_thread->Object.id, name ); } #endif _RTEMS_Unlock_allocator(); return RTEMS_SUCCESSFUL; }
rtems_status_code rtems_region_resize_segment( rtems_id id, void *segment, uintptr_t size, uintptr_t *old_size ) { uintptr_t avail_size; Objects_Locations location; uintptr_t osize; rtems_status_code return_status; Heap_Resize_status status; register Region_Control *the_region; if ( !old_size ) return RTEMS_INVALID_ADDRESS; _RTEMS_Lock_allocator(); the_region = _Region_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: _Region_Debug_Walk( the_region, 7 ); status = _Heap_Resize_block( &the_region->Memory, segment, (uint32_t) size, &osize, &avail_size ); *old_size = (uint32_t) osize; _Region_Debug_Walk( the_region, 8 ); if ( status == HEAP_RESIZE_SUCCESSFUL ) _Region_Process_queue( the_region ); /* unlocks allocator */ else _RTEMS_Unlock_allocator(); if (status == HEAP_RESIZE_SUCCESSFUL) return RTEMS_SUCCESSFUL; if (status == HEAP_RESIZE_UNSATISFIED) return RTEMS_UNSATISFIED; return RTEMS_INVALID_ADDRESS; break; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* this error cannot be returned */ break; #endif case OBJECTS_ERROR: default: return_status = RTEMS_INVALID_ID; break; } _RTEMS_Unlock_allocator(); return return_status; }
void rtems_heap_greedy_free( void *opaque ) { _RTEMS_Lock_allocator(); _Heap_Greedy_free( RTEMS_Malloc_Heap, opaque ); _RTEMS_Unlock_allocator(); }