Exemplo n.º 1
0
OS_Return _OS_GetTaskStatCounters(OS_Task_t task, OS_TaskStatCounters * ptr)
{
	if(!ptr)
		return INVALID_ARG;
	
	// This function can only be called by process with admin previleges.
	if(!(g_current_process->attributes & ADMIN_PROCESS))
		return NOT_ADMINISTRATOR;
	
	if(task >= MAX_TASK_COUNT)
		return INVALID_TASK;
	
	OS_Task * tcb = &g_task_pool[task];
	
	if(!tcb)
		return INVALID_TASK;
		
	ptr->task_time_us = tcb->accumulated_budget;
	ptr->total_time_us = _OS_GetElapsedTime();
	
	strncpy(ptr->name, tcb->name, sizeof(ptr->name) - 1);
	ptr->name[sizeof(ptr->name) - 1] = '\0';
	
    if(IS_PERIODIC_TASK(tcb->attributes))
	{
		ptr->period = tcb->p.period;
		ptr->budget = tcb->p.budget;
		ptr->exec_count = tcb->p.exec_count;
		ptr->TBE_count = tcb->p.TBE_count;
		ptr->dline_miss_count = tcb->p.dline_miss_count;
	}
	else
	{
		ptr->period = 0;
		ptr->budget = 0;
		ptr->exec_count = 0;
		ptr->TBE_count = 0;
		ptr->dline_miss_count = 0;
	}
		
	return SUCCESS;	
}
Exemplo n.º 2
0
OS_Return _OS_SemWait(OS_Sem_t sem)
{
	OS_Return status;
	
#if OS_ENABLE_CPU_STATS==1
    g_sched_starting_counter_value = _OS_Timer_GetCount(PERIODIC_TIMER);
#endif	

	if((status = assert_open(sem)) != SUCCESS) {
		goto exit;
	}

	// Get the Semaphore object
	OS_SemaphoreCB * semobj = (OS_SemaphoreCB *)&g_semaphore_pool[sem];

	// Make sure that the current process owns the Semaphore.
	if(semobj->owner != (OS_Process *) g_current_process)
	{
		status = RESOURCE_NOT_OWNED;
		goto exit;
	}

    // Get the task execution time
    UINT32 budget_spent = _OS_Timer_GetTimeElapsed_us(BUDGET_TIMER);
    g_current_task->accumulated_budget += budget_spent;
	
	if(IS_PERIODIC_TASK(g_current_task->attributes))
	{
	    // Adjust the remaining  budget for the current task
	    ASSERT(budget_spent <= ((OS_PeriodicTask *)g_current_task)->remaining_budget);
	    ((OS_PeriodicTask *)g_current_task)->remaining_budget -= budget_spent;		
	}

	// If the semaphore count is 0, then block the thread
	if(semobj->count == 0)
	{
		// Block the thread			
		if(IS_PERIODIC_TASK(g_current_task->attributes))
		{
			// Delete the current task from ready tasks queue
			_OS_QueueDelete(&g_ready_q, (void*)g_current_task); 
			
			// Add the current task to the semaphore's blocked queue for periodic tasks
			_OS_QueueInsert(&semobj->periodic_task_queue, (void*)g_current_task, 
				((OS_PeriodicTask *)g_current_task)->alarm_time); 
		}
		else
		{
			// Delete the current task from ready tasks queue
			_OS_QueueDelete(&g_ap_ready_q, (void*)g_current_task); 
			
			// Add the current task to the semaphore's blocked queue for aperiodic tasks
			_OS_QueueInsert(&semobj->aperiodic_task_queue, (void*)g_current_task, 
				((OS_AperiodicTask *)g_current_task)->priority);
		}
		
		Klog32(KLOG_SEMAPHORE_DEBUG, "Semaphore :- ", semobj->count);				
	}	
	else
	{
		// Decrement the semaphore count in order to acquire it
		semobj->count--;
		Klog32(KLOG_SEMAPHORE_DEBUG, "Semaphore - ", semobj->count);		
		
		// The return path for this function is through _OS_Schedule, so it is important to
		// update the result in the syscall_result
		if(g_current_task->syscall_result) 
			g_current_task->syscall_result[0] = SUCCESS;		
	}	
	
	_OS_Schedule();
	
exit:
	return status;
}
Exemplo n.º 3
0
OS_Return _OS_SemPost(OS_Sem_t sem)
{
	OS_GenericTask* task = NULL;
	OS_Return status;
	UINT64 key = 0;
	
#if OS_ENABLE_CPU_STATS==1
    g_sched_starting_counter_value = _OS_Timer_GetCount(PERIODIC_TIMER);
#endif

	if((status = assert_open(sem)) != SUCCESS) {
		goto exit;
	}
	
	// Get the Semaphore object
	OS_SemaphoreCB * semobj = (OS_SemaphoreCB *)&g_semaphore_pool[sem];
	
	// Make sure that the current process owns the Semaphore.
	if(semobj->owner != (OS_Process *) g_current_process)
	{
		status = RESOURCE_NOT_OWNED;
		goto exit;
	}
	
    // Get the task execution time
    UINT32 budget_spent = _OS_Timer_GetTimeElapsed_us(BUDGET_TIMER);
    g_current_task->accumulated_budget += budget_spent;
	
	if(IS_PERIODIC_TASK(g_current_task->attributes))
	{
	    // Adjust the remaining  budget for the current task
	    ASSERT(budget_spent <= ((OS_PeriodicTask *)g_current_task)->remaining_budget);
	    ((OS_PeriodicTask *)g_current_task)->remaining_budget -= budget_spent;		
	}

	if(semobj->count == 0)
	{
		// Unblock a waiting task. First check the periodic queue
		_OS_QueueGet(&semobj->periodic_task_queue, (void**)&task, &key);
		if(task)
		{
			// Place this task in the periodic task ready queue
			_OS_QueueInsert(&g_ready_q,(void*)task, key);
		}
		else 
		{
			// Now check the Aperiodic queue
			_OS_QueueGet(&semobj->aperiodic_task_queue, (void**)&task, &key);
			if(task)
			{
				// Insert this task into Aperiodic task queue
				_OS_QueueInsert(&g_ap_ready_q,(void*)task,key);
			}
		}
	}
	
	if(task)
	{
		// If a task is getting ready, then there is no need to increment the semaphore count
		// The return path for this function is through _OS_Schedule, so it is important to
		// update the result in the syscall_result
		if(task->syscall_result) 
			task->syscall_result[0] = SUCCESS;
		Klog32(KLOG_SEMAPHORE_DEBUG, "Semaphore :+ ", semobj->count);		
	}
	else
	{
		// Increment the resource count
		semobj->count++;	
		Klog32(KLOG_SEMAPHORE_DEBUG, "Semaphore + ", semobj->count);		
	}
		
	_OS_Schedule();	
	
exit:
	return status;
}
Exemplo n.º 4
0
OS_Return _OS_SemFree(OS_Sem_t sem)
{
	OS_Return status;
	OS_GenericTask* task = NULL;
	UINT64 key = 0;
	
#if OS_ENABLE_CPU_STATS==1
    g_sched_starting_counter_value = _OS_Timer_GetCount(PERIODIC_TIMER);
#endif
	
	if((status = assert_open(sem)) != SUCCESS) {
		goto exit;
	}
	
	// Get the Semaphore object
	OS_SemaphoreCB * semobj = (OS_SemaphoreCB *)&g_semaphore_pool[sem];
	
	// Make sure that the current process owns the Semaphore.
	if(semobj->owner != (OS_Process *) g_current_process)
	{
		status = RESOURCE_NOT_OWNED;
		goto exit;
	}

    // Get the task execution time
    UINT32 budget_spent = _OS_Timer_GetTimeElapsed_us(BUDGET_TIMER);
    g_current_task->accumulated_budget += budget_spent;
	
	if(IS_PERIODIC_TASK(g_current_task->attributes))
	{
	    // Adjust the remaining  budget for the current task
	    ASSERT(budget_spent <= ((OS_PeriodicTask *)g_current_task)->remaining_budget);
	    ((OS_PeriodicTask *)g_current_task)->remaining_budget -= budget_spent;		
	}

	// We need to unblock all waiting threads in its wait queues and make them ready
	while(TRUE)
	{
		// First check the periodic queue
		_OS_QueueGet(&semobj->periodic_task_queue, (void**)&task, &key);

		if(!task) break;
		
		// The return path for waiting tasks is through _OS_Schedule, so it is important to
		// update the result in the syscall_result	
		if(task->syscall_result) 
			task->syscall_result[0] = RESOURCE_DELETED;
		
		// Place this task in the periodic task ready queue
		_OS_QueueInsert(&g_ready_q,(void*)task, key);
	}	

	// Then check the Aperiodic queue
	while(TRUE)
	{
		_OS_QueueGet(&semobj->aperiodic_task_queue, (void**)&task, &key);

		if(!task) break;
		
		// The return path for waiting tasks is through _OS_Schedule, so it is important to
		// update the result in the syscall_result	
		if(task->syscall_result) 
			task->syscall_result[0] = RESOURCE_DELETED;
		
		// Insert this task into Aperiodic ready queue
		_OS_QueueInsert(&g_ap_ready_q,(void*)task, key);
	}	

	semobj->count = 0;
	semobj->owner = NULL;
	
	_OS_Schedule();	
	
exit:
	return status;
}
Exemplo n.º 5
0
///////////////////////////////////////////////////////////////////////////////
// Function to get the TBE count for the currently running task.
// It will be zero for an Aperiodic task.
///////////////////////////////////////////////////////////////////////////////
UINT32 OS_GetTBECount()
{
	OS_PeriodicTask * task = (OS_PeriodicTask *)g_current_task;
	return IS_PERIODIC_TASK(task->attributes) ? task->TBE_count : 0;
}