⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipc.c.svn-base

📁 RT-Thread是发展中的下一代微内核嵌入式实时操作系统
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
 */rt_err_t rt_mutex_delete (rt_mutex_t mutex){	RT_ASSERT(mutex != RT_NULL);	/* wakeup all suspend threads */	rt_ipc_object_resume_all(&(mutex->parent));	/* delete semaphore object */	rt_object_delete(&(mutex->parent.parent));	return RT_EOK;}#endif/** * 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 time){	register rt_base_t temp;	struct rt_thread* thread;	RT_ASSERT(mutex != RT_NULL);#ifdef RT_USING_HOOK	if (rt_object_trytake_hook != RT_NULL) rt_object_trytake_hook(&(mutex->parent.parent));#endif	/* disable interrupt */	temp = rt_hw_interrupt_disable();#ifdef IPC_DEBUG	rt_kprintf("mutex_take:mutex value: %d, hold: %d\n", mutex->value, mutex->hold);#endif	/* get current thread */	thread = rt_thread_self();	/* reset thread error */	thread->error = RT_EOK;	if (mutex->owner == thread)	{		/* it's the same thread */		mutex->hold ++;	}	else	{		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 */				mutex->value --;#ifdef IPC_DEBUG				rt_kprintf("sem 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 IPC_DEBUG					rt_kprintf("set thread:%s to timer list\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)				{					/* return error */					return thread->error;				}				else				{					/* disable interrupt */					temp = rt_hw_interrupt_disable();					/* take mutex */					mutex->owner = thread;					mutex->hold ++;					/* set thread error */					thread->error = RT_EOK;				}			}		}	}	/* 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;}/** * 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;	/* disable interrupt */	temp = rt_hw_interrupt_disable();#ifdef IPC_DEBUG	rt_kprintf("mutex_release:mutex value: %d, hold: %d\n", mutex->value, mutex->hold);#endif#ifdef RT_USING_HOOK	if (rt_object_put_hook != RT_NULL) rt_object_put_hook(&(mutex->parent.parent));#endif	/* get current thread */	thread = rt_thread_self();	/* mutex is only 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->value <= 0 && mutex->parent.suspend_thread_count > 0)		{#ifdef IPC_DEBUG		rt_kprintf("mutex release: resume thread: %s\n", thread->name);#endif			/* resume thread */			rt_ipc_object_resume(&(mutex->parent));		}		/* increase value */		mutex->value ++;	}	/* enable interrupt */	rt_hw_interrupt_enable(temp);	rt_schedule();	return RT_EOK;}/** * This function can get or set some extra attributions of a mutex object. * * @param mutex the mutex object * @param cmd the execution command * @param arg the execution argument * * @return the error code */rt_err_t rt_mutex_control(rt_mutex_t mutex, rt_uint8 cmd, void* arg){	return RT_EOK;}#endif /* end of RT_USING_MUTEX */#ifdef RT_USING_FASTEVENT/** * This function will initialize a fast event and put it under control of resource * management. * * @param event the fast event object * @param name the name of fast event * @param flag the flag of fast event * * @return the operation status, RT_EOK on successful */rt_err_t rt_fast_event_init(rt_fast_event_t event, const char* name, rt_uint8 flag){	register rt_base_t offset;	RT_ASSERT(event != RT_NULL);	/* init object */	rt_object_init(&(event->parent), RT_Object_Class_FastEvent, name);	/* set parent */	event->parent.flag = flag;	/* clear event set */	event->set = 0x00;	/* init thread list */	for (offset = 0; offset < 32; offset ++)	{		rt_list_init(&(event->thread_list[offset]));	}	return RT_EOK;}/** * This function will detach a fast event from resource management * * @param event the fast event object * * @return the operation status, RT_EOK on successful */rt_err_t rt_fast_event_detach(rt_fast_event_t event){	register rt_base_t bit;	struct rt_thread* thread;	register rt_ubase_t level;	RT_ASSERT(event != RT_NULL);	for (bit = 0; bit < RT_EVENT_LENGTH; bit ++)	{		/* resume all suspend thread */		if (!rt_list_isempty(&(event->thread_list[bit])))		{			/* wakeup all suspend threads */			while (!rt_list_isempty(&(event->thread_list[bit])))			{				/* disable interrupt */				level = rt_hw_interrupt_disable();				/* get next suspend thread */				thread = rt_list_entry(event->thread_list[bit].next, struct rt_thread, tlist);				/* set error code to RT_ERROR */				thread->error = -RT_ERROR;				/* resume thread */				rt_thread_resume(thread);				/* enable interrupt */				rt_hw_interrupt_enable(level);			}		}	}	/* detach event object */	rt_object_detach(&(event->parent));	return RT_EOK;}#ifdef RT_USING_HEAP/** * This function will create a fast event object from system resource * * @param name the name of fast event * @param flag the flag of fast event * * @return the created fast event, RT_NULL on error happen */rt_fast_event_t rt_fast_event_create (const char* name, rt_uint8 flag){	rt_fast_event_t event;	register rt_base_t offset;	/* allocate object */	event = (rt_fast_event_t) rt_object_allocate(RT_Object_Class_FastEvent, name);	if (event == RT_NULL) return event;	/* set parent */	event->parent.flag = flag;	/* clear event set */	event->set = 0x00;	/* init thread list */	for (offset = 0; offset < 32; offset ++)	{		rt_list_init(&(event->thread_list[offset]));	}	return event;}/** * This function will delete a fast event object and release the memory * * @param event the fast event object * * @return the error code */rt_err_t rt_fast_event_delete (rt_fast_event_t event){	register rt_base_t bit;	struct rt_thread* thread;	register rt_ubase_t level;	RT_ASSERT(event != RT_NULL);	for (bit = 0; bit < RT_EVENT_LENGTH; bit ++)	{		/* resume all suspend thread */		if (!rt_list_isempty(&(event->thread_list[bit])))		{			/* wakeup all suspend threads */			while (!rt_list_isempty(&(event->thread_list[bit])))			{				/* disable interrupt */				level = rt_hw_interrupt_disable();				/* get next suspend thread */				thread = rt_list_entry(event->thread_list[bit].next, struct rt_thread, tlist);				/* set error code to RT_ERROR */				thread->error = -RT_ERROR;				/* resume thread */				rt_thread_resume(thread);				/* enable interrupt */				rt_hw_interrupt_enable(level);			}		}	}	/* detach semaphore object */	rt_object_delete(&(event->parent));	return RT_EOK;}#endif/** * This function will send an event to the fast event object, if there are threads  * suspended on fast event object, it will be waked up. * * @param event the fast event object * @param bit the event bit * * @return the error code */rt_err_t rt_fast_event_send(rt_fast_event_t event, rt_uint8 bit){	rt_uint32 offset;	register rt_ubase_t level;	struct rt_thread *thread;	struct rt_list_node *n;	/* parameter check */	RT_ASSERT(event != RT_NULL);	RT_ASSERT(bit < RT_EVENT_LENGTH);	offset = 1 << bit;#ifdef RT_USING_HOOK	if (rt_object_put_hook != RT_NULL) rt_object_put_hook(&(event->parent));#endif	/* disable interrupt */	level = rt_hw_interrupt_disable();	event->set |= offset;	/* if thread list at offset is not empty */	n = event->thread_list[bit].next;	while (n != &(event->thread_list[bit]))	{		/* get thread */		thread = rt_list_entry(n, struct rt_thread, tlist);		/* move to next node */		n = n->next;		/* clear bit or not */		if (thread->event_info & RT_EVENT_FLAG_CLEAR)			event->set &= ~offset;		/* resume thread */		rt_thread_resume(thread);	}	/* enable interrupt */	rt_hw_interrupt_enable(level);	/* do a schedule */	rt_schedule();	return RT_EOK;}/** * This function will receive an event from fast event object, if the event is  * unavailable, the thread shall wait for a specified time. * * @param event the fast event object * @param bit the interested event * @param option the receive option * @param timeout the waiting time * * @return the error code */rt_err_t rt_fast_event_recv(rt_fast_event_t event, rt_uint8 bit, rt_uint8 option, rt_int32 timeout){ 	rt_base_t offset;	struct rt_thread* thread;	register rt_ubase_t level;	/* parameter check */	RT_ASSERT(event != RT_NULL);	RT_ASSERT(bit < RT_EVENT_LENGTH);	offset = 1 << bit;#ifdef RT_USING_HOOK	if (rt_object_trytake_hook != RT_NULL) rt_object_trytake_hook(&(event->parent));#endif	/* disable interrupt */	level = rt_hw_interrupt_disable();	/* get current thread */	thread = rt_thread_self();	thread->error = RT_EOK;	/* get event successfully */	if (event->set & offset)	{		if (option & RT_EVENT_FLAG_CLEAR)			event->set &= ~ offset;		/* enable interrupt */		rt_hw_interrupt_enable(level);		return RT_EOK;	}	/* no event happen */	/* check waiting time */	if (timeout == 0)	{		/* no waiting */		thread->error = -RT_ETIMEOUT;	}	else	{		/* there are no event, suspend thread */		rt_thread_suspend(thread);		/* set event info in thread */		thread->event_info = option;		switch (event->parent.flag)		{		case RT_IPC_FLAG_FIFO:			rt_list_insert_after(&(event->thread_list[bit]), &(thread->tlist));			break;		case RT_IPC_FLAG_PRIO:			{				struct rt_list_node* n;				struct rt_thread* sthread;				/* find a suitable position */				for (n = event->thread_list[bit].next; n != &(event->thread_list[bit]); n = n->next)				{					sthread = rt_list_entry(n, struct rt_thread, tlist);					/* find out */					if (thread->current_priority < sthread->current_priority) break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -