/// Change prority of an active thread
osStatus osThreadSetPriority(osThreadId thread_id, osPriority priority)
{
	rt_err_t result;
	
	if (thread_id == RT_NULL)
		return osErrorOS;

	if (priority < osPriorityIdle || priority > osPriorityRealtime)
		return osErrorPriority;

	result = rt_thread_control(thread_id, RT_THREAD_CTRL_CHANGE_PRIORITY, &priority);	
	
	if (result == RT_EOK)
		return osOK;
	else
		return osErrorOS;
}
Ejemplo n.º 2
0
/**
 * This function will release a mutex, if there are threads suspended on mutex,
 * it will be waked up.
 *
 * @param mutex the mutex object
 *
 * @return the error code
 */
rt_err_t rt_mutex_release(rt_mutex_t mutex)
{
	register rt_base_t temp;
	struct rt_thread* thread;
	rt_bool_t need_schedule;

	need_schedule = RT_FALSE;

	/* get current thread */
	thread = rt_thread_self();

	/* disable interrupt */
	temp = rt_hw_interrupt_disable();

#ifdef RT_IPC_DEBUG
	rt_kprintf("mutex_release:current thread %s, mutex value: %d, hold: %d\n", 
		thread->name, mutex->value, mutex->hold);
#endif

#ifdef RT_USING_HOOK
	if (rt_object_put_hook != RT_NULL) rt_object_put_hook(&(mutex->parent.parent));
#endif

	/* mutex only can be released by owner */
	if (thread != mutex->owner)
	{
		thread->error = -RT_ERROR;

		/* enable interrupt */
		rt_hw_interrupt_enable(temp);

		return -RT_ERROR;
	}

	/* decrease hold */
	mutex->hold --;
	/* if no hold */
	if (mutex->hold == 0)
	{
		/* change the owner thread to original priority */
		if (mutex->owner->init_priority != mutex->owner->current_priority)
		{
			rt_thread_control(mutex->owner, RT_THREAD_CTRL_CHANGE_PRIORITY,
				&(mutex->owner->init_priority));
		}

		/* wakeup suspended thread */
		if (mutex->parent.suspend_thread_count > 0)
		{
			/* get thread entry */
			thread = rt_list_entry(mutex->parent.suspend_thread.next, struct rt_thread, tlist);

#ifdef RT_IPC_DEBUG
		rt_kprintf("mutex_release: resume thread: %s\n", thread->name);
#endif
			/* set new owner and priority */
			mutex->owner = thread;
			mutex->original_priority = thread->current_priority;
			mutex->hold ++;

			/* resume thread */
			rt_ipc_object_resume(&(mutex->parent));

			need_schedule = RT_TRUE;
		}
		else
		{
Ejemplo n.º 3
0
/**
 * This function will take a mutex, if the mutex is unavailable, the
 * thread shall wait for a specified time.
 *
 * @param mutex the mutex object
 * @param time the waiting time
 *
 * @return the error code
 */
rt_err_t rt_mutex_take (rt_mutex_t mutex, rt_int32_t time)
{
	register rt_base_t temp;
	struct rt_thread* thread;

	RT_ASSERT(mutex != RT_NULL);

	/* disable interrupt */
	temp = rt_hw_interrupt_disable();

	/* get current thread */
	thread = rt_thread_self();

#ifdef RT_USING_HOOK
	if (rt_object_trytake_hook != RT_NULL) rt_object_trytake_hook(&(mutex->parent.parent));
#endif

#ifdef RT_IPC_DEBUG
	rt_kprintf("mutex_take: current thread %s, mutex value: %d, hold: %d\n", 
		thread->name, mutex->value, mutex->hold);
#endif

	/* reset thread error */
	thread->error = RT_EOK;

	if (mutex->owner == thread)
	{
		/* it's the same thread */
		mutex->hold ++;
	}
	else
	{
		/* in initialization status, the value is 1. Therefore, if the 
		 * value is great than 1, which indicates the mutex is avaible.
		 */
		if (mutex->value > 0)
		{
			/* mutex is available */
			mutex->value --;

			/* set mutex owner and original priority */
			mutex->owner = thread;
			mutex->original_priority = thread->current_priority;
			mutex->hold ++;
		}
		else
		{
			/* no waiting, return with timeout */
			if (time == 0 )
			{
				/* set error as timeout */
				thread->error = -RT_ETIMEOUT;

				/* enable interrupt */
				rt_hw_interrupt_enable(temp);

				return -RT_ETIMEOUT;
			}
			else
			{
				/* mutex is unavailable, push to suspend list */
#ifdef RT_IPC_DEBUG
				rt_kprintf("mutex_take: suspend thread: %s\n", thread->name);
#endif
				/* change the owner thread priority of mutex */
				if (thread->current_priority < mutex->owner->current_priority)
				{
					/* change the owner thread priority */
					rt_thread_control(mutex->owner, RT_THREAD_CTRL_CHANGE_PRIORITY,
						&thread->current_priority);
				}

				/* suspend current thread */
				rt_ipc_object_suspend(&(mutex->parent), thread);

				/* has waiting time, start thread timer */
				if (time > 0)
				{
#ifdef RT_IPC_DEBUG
					rt_kprintf("mutex_take: start the timer of thread:%s\n", thread->name);
#endif
					/* reset the timeout of thread timer and start it */
					rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &time);
					rt_timer_start(&(thread->thread_timer));
				}

				/* enable interrupt */
				rt_hw_interrupt_enable(temp);

				/* do schedule */
				rt_schedule();

				if (thread->error != RT_EOK)
				{
					/* decrease suspended thread count */
					rt_ipc_object_decrease(&(mutex->parent));

					/* return error */
					return thread->error;
				}
				else
				{
					/* the mutex is taken successfully. */
					/* disable interrupt */
					temp = rt_hw_interrupt_disable();
				}
			}
		}
	}

	/* enable interrupt */
	rt_hw_interrupt_enable(temp);

#ifdef RT_USING_HOOK
	if (rt_object_take_hook != RT_NULL) rt_object_take_hook(&(mutex->parent.parent));
#endif

	return RT_EOK;
}