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

📄 scheduler.c.svn-base

📁 RT-Thread是发展中的下一代微内核嵌入式实时操作系统
💻 SVN-BASE
字号:
/* * File      : scheduler.c * This file is part of RT-Thread RTOS * COPYRIGHT (C) 2006, RT-Thread Development Team * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.fayfayspace.org/license/LICENSE. * * Change Logs: * Date           Author       Notes * 2006-03-17     Bernard      the first version * 2006-04-28     Bernard      fix the scheduler algorthm * 2006-04-30     Bernard      add SCHEDULER_DEBUG * 2006-05-27     Bernard      fix the scheduler algorthm for same priority thread *                             schedule * 2006-06-04     Bernard      rewrite the scheduler algorithm *//** * @addtogroup Kernel *//*@{*/#include <rtthread.h>#include <rthw.h>#include "kservice.h"// #define SCHEDULER_DEBUGstatic rt_int16 rt_scheduler_lock_nest;extern rt_uint32 rt_interrupt_nest;rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];struct rt_thread* rt_current_thread;rt_uint8 rt_current_priority;rt_uint32 rt_thread_ready_priority_group;rt_uint8 rt_thread_ready_table[32];rt_uint8 rt_lowest_bitmap[] ={	/* 00 */ 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	/* 10 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	/* 20 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	/* 30 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	/* 40 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	/* 50 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	/* 60 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	/* 70 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	/* 80 */ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	/* 90 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	/* A0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	/* B0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	/* C0 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	/* D0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	/* E0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	/* F0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0};void rt_system_scheduler_init(){	register rt_base_t offset;	rt_scheduler_lock_nest = 0;	for (offset = 0; offset < RT_THREAD_PRIORITY_MAX; offset ++)	{		rt_list_init(&rt_thread_priority_table[offset]);	}	rt_current_priority = RT_THREAD_PRIORITY_MAX - 1;	rt_current_thread	= RT_NULL;	/* init ready priority group */	rt_thread_ready_priority_group = 0;	/* init ready table */	rt_memset(rt_thread_ready_table, 0, sizeof(rt_thread_ready_table));}/** * @brief do a thread-schedule * * This function will perform one schedule. It will select one thread * with highest priority, then switch to it. */void rt_schedule(){	register rt_uint8 number;	register rt_base_t level;	register rt_uint8 highest_ready_priority;	struct rt_thread *to_thread;	struct rt_thread *from_thread;	/* disable interrupt */	level = rt_hw_interrupt_disable();	/* check the scheduler is enabled or not */	if(rt_scheduler_lock_nest == 0)	{		/* find out the highest priority task */		if (rt_thread_ready_priority_group & 0xff)		{			number = rt_lowest_bitmap[rt_thread_ready_priority_group & 0xff];		}		else if (rt_thread_ready_priority_group & 0xff00)		{			number = rt_lowest_bitmap[(rt_thread_ready_priority_group >> 8) & 0xff] + 8;		}		else if (rt_thread_ready_priority_group & 0xff0000)		{			number = rt_lowest_bitmap[(rt_thread_ready_priority_group >> 16) & 0xff] + 16;		}		else		{			number = rt_lowest_bitmap[(rt_thread_ready_priority_group >> 24) & 0xff] + 24;		}		highest_ready_priority = (number << 3) + rt_lowest_bitmap[rt_thread_ready_table[number]];		/* get switch to thread */		to_thread = rt_list_entry(rt_thread_priority_table[highest_ready_priority].next,			struct rt_thread, tlist);		/* if the destination thread is not the same as current thread */		if (to_thread != rt_current_thread)		{			rt_current_priority = highest_ready_priority;			from_thread = rt_current_thread;			rt_current_thread = to_thread;			/* switch to new thread */#ifdef SCHEDULER_DEBUG			rt_kprintf("switch to priority#%d thread:%s\n", highest_ready_priority,				to_thread->name);#endif			if (rt_interrupt_nest == 0)			{				rt_hw_context_switch((rt_uint32)&from_thread->sp, (rt_uint32)&to_thread->sp);			}			else			{#ifdef SCHEDULER_DEBUG				rt_kprintf("switch in interrupt\n");#endif				rt_hw_context_switch_interrupt((rt_uint32)&from_thread->sp,					(rt_uint32)&to_thread->sp);			}		}	}	/* enable interrupt */	rt_hw_interrupt_enable(level);}void rt_schedule_insert_thread(struct rt_thread* thread){	register rt_base_t temp;	RT_ASSERT(thread != RT_NULL);	/* disable interrupt */	temp = rt_hw_interrupt_disable();	/* insert thread to ready list */	rt_list_insert_before(&(rt_thread_priority_table[thread->current_priority]),		&(thread->tlist));	/* set priority mask */#ifdef SCHEDULER_DEBUG	rt_kprintf("insert thread, the priority: %d 0x%x %d\n", thread->number, thread->number_mask, thread->high_mask);#endif	rt_thread_ready_table[thread->number] |= thread->high_mask;	rt_thread_ready_priority_group |= thread->number_mask;	/* enable interrupt */	rt_hw_interrupt_enable(temp);}void rt_schedule_remove_thread(struct rt_thread* thread){	register rt_base_t temp;	RT_ASSERT(thread != RT_NULL);	/* disable interrupt */	temp = rt_hw_interrupt_disable();#ifdef SCHEDULER_DEBUG	rt_kprintf("remove thread, the priority: %d 0x%x %d\n", thread->number,		thread->number_mask, thread->high_mask);#endif	/* remove thread from ready list */	rt_list_remove(&(thread->tlist));	if (rt_list_isempty(&(rt_thread_priority_table[thread->current_priority])))	{		rt_thread_ready_table[thread->number] &= ~thread->high_mask;		if (rt_thread_ready_table[thread->number] == 0)		{			rt_thread_ready_priority_group &= ~thread->number_mask;		}	}	/* enable interrupt */	rt_hw_interrupt_enable(temp);}/** * @brief lock thread scheduler * * This function will lock thread scheduler. */void rt_enter_critical(){	register rt_base_t level;	/* disable interrupt */	level = rt_hw_interrupt_disable();	if (rt_scheduler_lock_nest < 255u)		rt_scheduler_lock_nest++;	/* enable interrupt */	rt_hw_interrupt_enable(level);}/** * @brief unlock thread scheduler * * This function will unlock thread scheduler. */void rt_exit_critical(){	register rt_base_t level;	/* disable interrupt */	level = rt_hw_interrupt_disable();	rt_scheduler_lock_nest --;	if (rt_scheduler_lock_nest <= 0)	{		rt_scheduler_lock_nest = 0;		rt_schedule();	}	else	{		/* enable interrupt */		rt_hw_interrupt_enable(level);	}}/*@}*/

⌨️ 快捷键说明

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