void _RBTree_Initialize( RBTree_Control *the_rbtree, RBTree_Compare_function compare_function, void *starting_address, size_t number_nodes, size_t node_size, bool is_unique ) { size_t count; RBTree_Node *next; /* TODO: Error message? */ if (!the_rbtree) return; /* could do sanity checks here */ _RBTree_Initialize_empty(the_rbtree, compare_function, is_unique); count = number_nodes; next = starting_address; while ( count-- ) { _RBTree_Insert(the_rbtree, next); next = (RBTree_Node *) _Addresses_Add_offset( (void *) next, node_size ); } }
Scheduler_Void_or_thread _Scheduler_EDF_Yield( const Scheduler_Control *scheduler, Thread_Control *the_thread ) { Scheduler_EDF_Context *context = _Scheduler_EDF_Get_context( scheduler ); Scheduler_EDF_Node *node = _Scheduler_EDF_Thread_get_node( the_thread ); /* * The RBTree has more than one node, enqueue behind the tasks * with the same priority in case there are such ones. */ _RBTree_Extract( &context->Ready, &node->Node ); _RBTree_Insert( &context->Ready, &node->Node, _Scheduler_EDF_Compare, false ); _Scheduler_EDF_Schedule_body( scheduler, the_thread, false ); SCHEDULER_RETURN_VOID_OR_NULL; }
void _Scheduler_EDF_Enqueue( Thread_Control *the_thread ) { Scheduler_EDF_Per_thread *sched_info = (Scheduler_EDF_Per_thread*) the_thread->scheduler_info; RBTree_Node *node = &(sched_info->Node); _RBTree_Insert( &_Scheduler_EDF_Ready_queue, node ); sched_info->queue_state = SCHEDULER_EDF_QUEUE_STATE_YES; }
static void _Thread_queue_Priority_do_enqueue( Thread_queue_Heads *heads, Thread_Control *the_thread ) { _RBTree_Insert( &heads->Heads.Priority, &the_thread->Wait.Node.RBTree, _Thread_queue_Compare_priority, false ); }
void _Scheduler_EDF_Change_priority( const Scheduler_Control *scheduler, Thread_Control *the_thread, Priority_Control new_priority, bool prepend_it ) { Scheduler_EDF_Context *context = _Scheduler_EDF_Get_context( scheduler ); Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread ); _RBTree_Extract( &context->Ready, &node->Node ); _RBTree_Insert( &context->Ready, &node->Node ); }
static void _Thread_queue_Requeue_priority( Thread_Control *the_thread, Priority_Control new_priority, void *context ) { Thread_queue_Control *tq = context; _RBTree_Extract( &tq->Queues.Priority, &the_thread->RBNode ); _RBTree_Insert( &tq->Queues.Priority, &the_thread->RBNode, _Thread_queue_Compare_priority, false ); }
void _Thread_queue_Requeue( Thread_queue_Control *the_thread_queue, Thread_Control *the_thread ) { /* * Just in case the thread really wasn't blocked on a thread queue * when we get here. */ if ( !the_thread_queue ) return; /* * If queueing by FIFO, there is nothing to do. This only applies to * priority blocking discipline. */ if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY ) { Thread_queue_Control *tq = the_thread_queue; ISR_Level level; _ISR_Disable( level ); if ( _States_Is_waiting_on_thread_queue( the_thread->current_state ) ) { _Thread_queue_Enter_critical_section( tq ); /* extract the thread */ _RBTree_Extract( &the_thread->Wait.queue->Queues.Priority, &the_thread->RBNode ); /* enqueue the thread at the new priority */ _RBTree_Insert( &the_thread_queue->Queues.Priority, &the_thread->RBNode, _Thread_queue_Compare_priority, false ); } _ISR_Enable( level ); } }
static void _Thread_queue_Priority_do_enqueue( Thread_queue_Heads *heads, Thread_Control *the_thread ) { Thread_queue_Priority_queue *priority_queue = _Thread_queue_Priority_queue( heads, the_thread ); #if defined(RTEMS_SMP) if ( _RBTree_Is_empty( &priority_queue->Queue ) ) { _Chain_Append_unprotected( &heads->Heads.Fifo, &priority_queue->Node ); } #endif _RBTree_Insert( &priority_queue->Queue, &the_thread->Wait.Node.RBTree, _Thread_queue_Compare_priority, false ); }
static void _Thread_queue_Priority_priority_change( Thread_Control *the_thread, Priority_Control new_priority, Thread_queue_Queue *queue ) { Thread_queue_Heads *heads = queue->heads; _Assert( heads != NULL ); _RBTree_Extract( &heads->Heads.Priority, &the_thread->Wait.Node.RBTree ); _RBTree_Insert( &heads->Heads.Priority, &the_thread->Wait.Node.RBTree, _Thread_queue_Compare_priority, false ); }
Scheduler_Void_or_thread _Scheduler_EDF_Change_priority( const Scheduler_Control *scheduler, Thread_Control *the_thread, Priority_Control new_priority, bool prepend_it ) { Scheduler_EDF_Context *context = _Scheduler_EDF_Get_context( scheduler ); Scheduler_EDF_Node *node = _Scheduler_EDF_Thread_get_node( the_thread ); _RBTree_Extract( &context->Ready, &node->Node ); _RBTree_Insert( &context->Ready, &node->Node, _Scheduler_EDF_Compare, false ); SCHEDULER_RETURN_VOID_OR_NULL; }
void _RBTree_Initialize( RBTree_Control *the_rbtree, RBTree_Compare compare, void *starting_address, size_t number_nodes, size_t node_size, bool is_unique ) { size_t count; RBTree_Node *next; /* could do sanity checks here */ _RBTree_Initialize_empty( the_rbtree ); count = number_nodes; next = starting_address; while ( count-- ) { _RBTree_Insert( the_rbtree, next, compare, is_unique ); next = (RBTree_Node *) _Addresses_Add_offset( next, node_size ); } }
void _Thread_queue_Enqueue( Thread_queue_Control *the_thread_queue, Thread_Control *the_thread, States_Control state, Watchdog_Interval timeout ) { ISR_lock_Context lock_context; Thread_blocking_operation_States sync_state; #if defined(RTEMS_MULTIPROCESSING) if ( _Thread_MP_Is_receive( the_thread ) && the_thread->receive_packet ) the_thread = _Thread_MP_Allocate_proxy( state ); else #endif /* * Set the blocking state for this thread queue in the thread. */ _Thread_Set_state( the_thread, state ); /* * If the thread wants to timeout, then schedule its timer. */ if ( timeout ) { _Watchdog_Initialize( &the_thread->Timer, _Thread_queue_Timeout, the_thread->Object.id, NULL ); _Watchdog_Insert_ticks( &the_thread->Timer, timeout ); } /* * Now initiate the enqueuing and checking if the blocking operation * should be completed or the thread has had its blocking condition * satisfied before we got here. */ _Thread_queue_Acquire( &lock_context ); sync_state = the_thread_queue->sync_state; the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED; if ( sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) { /* * Invoke the discipline specific enqueue method. */ if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_FIFO ) { _Chain_Append_unprotected( &the_thread_queue->Queues.Fifo, &the_thread->Object.Node ); } else { /* must be THREAD_QUEUE_DISCIPLINE_PRIORITY */ _Thread_Lock_set( the_thread, &_Thread_queue_Lock ); _Thread_Priority_set_change_handler( the_thread, _Thread_queue_Requeue_priority, the_thread_queue ); _RBTree_Insert( &the_thread_queue->Queues.Priority, &the_thread->RBNode, _Thread_queue_Compare_priority, false ); } the_thread->Wait.queue = the_thread_queue; the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED; _Thread_queue_Release( &lock_context ); } else { /* Cancel a blocking operation due to ISR */ _Assert( sync_state == THREAD_BLOCKING_OPERATION_TIMEOUT || sync_state == THREAD_BLOCKING_OPERATION_SATISFIED ); _Thread_blocking_operation_Finalize( the_thread, &lock_context ); } }
int pthread_setspecific( pthread_key_t key, const void *value ) { POSIX_Keys_Control *the_key; Objects_Locations location; POSIX_Keys_Key_value_pair *value_pair_ptr; RBTree_Node *p; POSIX_Keys_Key_value_pair search_node; Thread_Control *executing; the_key = _POSIX_Keys_Get( key, &location ); switch ( location ) { case OBJECTS_LOCAL: executing = _Thread_Executing; p = _POSIX_Keys_Find( key, executing, &search_node ); if ( p != NULL ) { value_pair_ptr = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( p ); value_pair_ptr->value = value; } else { value_pair_ptr = _POSIX_Keys_Key_value_pair_allocate(); if ( !value_pair_ptr ) { _Objects_Put( &the_key->Object ); return ENOMEM; } value_pair_ptr->key = key; value_pair_ptr->thread = executing; value_pair_ptr->value = value; /* The insert can only go wrong if the same node is already in a unique * tree. This has been already checked with the _RBTree_Find() */ _RBTree_Insert( &_POSIX_Keys_Key_value_lookup_tree, &value_pair_ptr->Key_value_lookup_node, _POSIX_Keys_Key_value_compare, true ); /** append rb_node to the thread API extension's chain */ _Chain_Append_unprotected( &_Thread_Executing->Key_Chain, &value_pair_ptr->Key_values_per_thread_node ); } _Objects_Put( &the_key->Object ); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* should never happen */ #endif case OBJECTS_ERROR: break; } return EINVAL; }