码迷,mamicode.com
首页 > 编程语言 > 详细

RT-Thread内核之线程调度(四)

时间:2015-07-13 18:41:41      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:操作系统   thread   源码   

以下为线程部分的源码分析:

extern rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];
extern struct rt_thread *rt_current_thread;
extern rt_list_t rt_thread_defunct;


/*******************************************************************************************
** 函数名称: rt_thread_exit
** 函数功能: 线程退出
** 入口参数: 无
** 返 回 值: 无
** 调    用: _rt_thread_init
*******************************************************************************************/

static void rt_thread_exit(void)
{
    struct rt_thread* thread;
    register rt_base_t level;

    /** 获取当前正在运行的线程 */
    thread = rt_current_thread;

    /** 禁止全局中断 */
    level = rt_hw_interrupt_disable();

    /** 从调度器中移除该线程 */
    rt_schedule_remove_thread(thread);

    /** 将线程的状态设置为CLOSE状态 */
    thread->stat = RT_THREAD_CLOSE;

    /** 注销线程内置的定时器 */
    rt_timer_detach(&thread->thread_timer);

    /** 如果对象为系统对象并且线程不含cleanup方法,注销该线程 */
    if ((rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) &&
        thread->cleanup == RT_NULL) {
        rt_object_detach((rt_object_t)thread);
    } else { /** 否则将该线程链接到僵尸线程链表中 */
        rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));
    }

    /** 使能全局中断 */
    rt_hw_interrupt_enable(level);

    /** 触发调度 */
    rt_schedule();
}


/*******************************************************************************************
** 函数名称: _rt_thread_init
** 函数功能: 初始化线程实例
** 入口参数: thread 线程对象句柄
**          name 线程的名字
**          entry 线程的入口函数
**          parameter 附加参数
**          stack_start 栈底指针
**          stack_size 栈的大小
**          priority 线程的优先级
**          tick 线程的初始滴答数(能运行的时间片值)
** 返 回 值: 成功返回RT_EOK
** 调    用: rt_thread_init
*******************************************************************************************/

static rt_err_t _rt_thread_init(struct rt_thread* thread,
                                 const char* name,
                                 void (*entry)(void *parameter),
                                 void * parameter,
                                 void * stack_start,
                                 rt_uint32_t stack_size,
                                 rt_uint8_t  priority,
                                 rt_uint32_t tick)
{


    /** 初始化线程链表节点成员 */
    rt_list_init(&(thread->tlist));

    thread->entry = (void *)entry;
    thread->parameter = parameter;

    thread->stack_addr = stack_start;
    thread->stack_size = (rt_uint16_t)stack_size;

    /** 初始化线程的栈 */
    rt_memset(thread->stack_addr, ‘#‘, thread->stack_size);
    thread->sp = (void *)rt_hw_stack_init(thread->entry, thread->parameter,
        (void *)((char *)thread->stack_addr + thread->stack_size - 4),
        (void *)rt_thread_exit);

    RT_ASSERT(priority < RT_THREAD_PRIORITY_MAX);
    thread->init_priority    = priority;
    thread->current_priority = priority;

    thread->init_tick      = tick;
    thread->remaining_tick = tick;

    thread->error = RT_EOK;

    /** 创建线程时,线程处于INIT状态 */
    thread->stat  = RT_THREAD_INIT;

    thread->cleanup   = 0;
    thread->user_data = 0;

    /** 初始化线程内嵌的定时器 */
    rt_timer_init(&(thread->thread_timer),
                  thread->name,
                  rt_thread_timeout,
                  thread,
                  0,
                  RT_TIMER_FLAG_ONE_SHOT);

    return RT_EOK;
}


/*******************************************************************************************
** 函数名称: rt_thread_init
** 函数功能: 静态初始化线程实例
** 入口参数: thread 线程对象句柄
**    name 线程的名字
**    entry 线程的入口函数
**    parameter 附加参数
**    stack_start 栈底指针
**    stack_size 栈的大小
**    priority 线程的优先级
**    tick 线程的初始滴答数(能运行的时间片值)
** 返 回 值: 成功返回RT_EOK
** 调    用: rt_thread_init
*******************************************************************************************/

rt_err_t rt_thread_init(struct rt_thread *thread,
                           const char       *name,
                           void (*entry)(void *parameter),
                           void* parameter,
                           void* stack_start,
                           rt_uint32_t stack_size,
                           rt_uint8_t priority,
                           rt_uint32_t tick)
{
    /** 参数检查 */
    RT_ASSERT(thread != RT_NULL);
    RT_ASSERT(stack_start != RT_NULL);


    /** 初始化线程内嵌的对象结构 */
    rt_object_init((rt_object_t)thread, RT_Object_Class_Thread, name);

    /** 初始化线程实例 */
    return _rt_thread_init(thread,
                           name,
                           entry,
                           parameter,
                           stack_start,
                           stack_size,
                           priority,
                           tick);
}
RTM_EXPORT(rt_thread_init);



/*******************************************************************************************
** 函数名称: rt_thread_init
** 函数功能: 返回当前正在运行的线程对象句柄
** 入口参数: 无
** 返 回 值: 线程对象句柄
** 调    用: rt_thread_init
*******************************************************************************************/

rt_thread_t rt_thread_self(void)
{
    return rt_current_thread;
}
RTM_EXPORT(rt_thread_self);



/*******************************************************************************************
** 函数名称: rt_thread_startup
** 函数功能: 启动线程将线程放入系统就绪队列中
** 入口参数: thread 线程对象句柄
** 返 回 值: 返回RT_EOK
** 调    用: 
*******************************************************************************************/

rt_err_t rt_thread_startup(rt_thread_t thread)
{
    /** 参数检查 */
    RT_ASSERT(thread !=RT_NULL);
    RT_ASSERT(thread->stat == RT_THREAD_INIT);

    /** 设置线程的当前优先级 */
    thread->current_priority = thread->init_priority;

    /** 计算优先级属性 */
#if RT_THREAD_PRIORITY_MAX > 32
    thread->number      = thread->current_priority >> 3;            /* 5bit */
    thread->number_mask = 1L << thread->number;
    thread->high_mask   = 1L << (thread->current_priority & 0x07);  /* 3bit */
#else
    thread->number_mask = 1L << thread->current_priority;
#endif


    RT_DEBUG_LOG(RT_DEBUG_THREAD, ("startup a thread:%s with priority:%d\n",
                                   thread->name, thread->init_priority));
    /** 设置线程的状态为挂起状态 */
    thread->stat = RT_THREAD_SUSPEND;


    /** 恢复线程 */
    rt_thread_resume(thread);


    /** 如果系统已经运行 */
    if (rt_thread_self() != RT_NULL) {
        rt_schedule(); /** 调度 */
    }

    return RT_EOK;
}
RTM_EXPORT(rt_thread_startup);


 
/*******************************************************************************************
** 函数名称: rt_thread_detach
** 函数功能: 注销线程
** 入口参数: thread 线程对象句柄
** 返 回 值: 返回RT_EOK
** 调    用: 
*******************************************************************************************/

rt_err_t rt_thread_detach(rt_thread_t thread)
{
    rt_base_t lock;


    /** 参数检查 */
    RT_ASSERT(thread != RT_NULL);

    /** 从调度队列中移除该线程 */
    rt_schedule_remove_thread(thread);

    /** 注销该线程内嵌的定时器 */
    rt_timer_detach(&(thread->thread_timer));

    /** 将线程的状态设置为CLOSE状态 */
    thread->stat = RT_THREAD_CLOSE;

    /** 注销线程内嵌的对象结构 */
    rt_object_detach((rt_object_t)thread);

    /** 如果线程含cleanup方法 */
    if (thread->cleanup != RT_NULL) {

        /** 禁止全局中断 */
        lock = rt_hw_interrupt_disable();

/** 将该线程插入到僵尸链表中 */
        rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));

/** 使能全局中断 */
        rt_hw_interrupt_enable(lock);
    }

    return RT_EOK;
}
RTM_EXPORT(rt_thread_detach);


#ifdef RT_USING_HEAP


/*******************************************************************************************
** 函数名称: rt_thread_create
** 函数功能: 动态的创建线程
** 入口参数: name 线程的名字
**     entry 线程的入口
**     parameter附加参数
**     stack_size线程栈的大小
**     priority线程的优先级
**     tick 线程的初始化滴答数
** 返 回 值: 线程对象句柄
** 调    用: 
*******************************************************************************************/

rt_thread_t rt_thread_create(const char *name,
                             void (*entry)(void *parameter),
                             void       *parameter,
                             rt_uint32_t stack_size,
                             rt_uint8_t  priority,
                             rt_uint32_t tick)
{
    struct rt_thread *thread;
    void *stack_start;

    /** 分配线程对象 */
    thread = (struct rt_thread *)rt_object_allocate(RT_Object_Class_Thread, name);
    if (thread == RT_NULL)
        return RT_NULL;

    /** 分配线程的栈 */
    stack_start = (void *)RT_KERNEL_MALLOC(stack_size);
    if (stack_start == RT_NULL) {
        rt_object_delete((rt_object_t)thread);
        return RT_NULL;
    }

    /** 初始化线程实例 */
    _rt_thread_init(thread,
                    name,
                    entry,
                    parameter,
                    stack_start,
                    stack_size,
                    priority,
                    tick);

    return thread;
}
RTM_EXPORT(rt_thread_create);



/*******************************************************************************************
** 函数名称: rt_thread_delete
** 函数功能: 释放一个线程
** 入口参数: thread 线程的句柄
** 返 回 值: 成功返回RT_EOK;失败返回-RT_ERROR
** 调    用: 
*******************************************************************************************/

rt_err_t rt_thread_delete(rt_thread_t thread)
{
    rt_base_t lock;

    /** 参数检查 */
    RT_ASSERT(thread != RT_NULL);

    /** 从调度队列中移除线程 */
    rt_schedule_remove_thread(thread);

    /** 注销线程内嵌的定时器对象 */
    rt_timer_detach(&(thread->thread_timer));

    /** 线程的状态设置为CLOSE */
    thread->stat = RT_THREAD_CLOSE;

    /** 禁止全局中断 */
    lock = rt_hw_interrupt_disable();

    /** 将线程放入僵尸链表中 */
    rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));

    /** 将线程放入僵尸链表中 */
    rt_hw_interrupt_enable(lock);

    return RT_EOK;
}
RTM_EXPORT(rt_thread_delete);
#endif



/*******************************************************************************************
** 函数名称: rt_thread_yield
** 函数功能: 线程放弃处理器
** 入口参数: 无
** 返 回 值: RT_EOK
** 调    用: 
*******************************************************************************************/

rt_err_t rt_thread_yield(void)
{
    register rt_base_t level;
    struct rt_thread *thread;

    /** 禁止全局中断 */
    level = rt_hw_interrupt_disable();

    /** 获取当前线程对象指针 */
    thread = rt_current_thread;

    /** 如果该线程处于就绪状态并且同一优先级链表中还有其他线程 */
    if (thread->stat == RT_THREAD_READY &&
        thread->tlist.next != thread->tlist.prev) {

/** 将该线程从就绪链表中移除 */
        rt_list_remove(&(thread->tlist));

/** 将线程放到就绪链表的末尾 */
        rt_list_insert_before(&(rt_thread_priority_table[thread->current_priority]),
                              &(thread->tlist));

  /** 使能全局中断 */
        rt_hw_interrupt_enable(level);

/** 调度 */
        rt_schedule();

        return RT_EOK;
    }

    /** 使能全局中断 */
    rt_hw_interrupt_enable(level);

    return RT_EOK;
}
RTM_EXPORT(rt_thread_yield);



/*******************************************************************************************
** 函数名称: rt_thread_sleep
** 函数功能: 线程睡眠tick个时钟滴答
** 入口参数: tick 线程睡眠的滴答数
** 返 回 值: 成功返回RT_EOK;失败返回-RT_ERROR
** 调    用: 
*******************************************************************************************/

rt_err_t rt_thread_sleep(rt_tick_t tick)
{
    register rt_base_t temp;
    struct rt_thread *thread;

    /** 禁止全局中断 */
    temp = rt_hw_interrupt_disable();

    /** 获取当前线程 */
    thread = rt_current_thread;
    RT_ASSERT(thread != RT_NULL);

    /** 挂起当前线程 */
    rt_thread_suspend(thread);

    /** 复位线程内嵌的定时器并启动定时器 */
    rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &tick);
    rt_timer_start(&(thread->thread_timer));

    /** 使能全局中断 */
    rt_hw_interrupt_enable(temp);

    /** 调度 */
    rt_schedule();

    /** 如果线程是因为超时唤醒 */
    if (thread->error == -RT_ETIMEOUT)
        thread->error = RT_EOK;


    return RT_EOK;
}



/*******************************************************************************************
** 函数名称: rt_thread_delay
** 函数功能: 线程睡眠tick个时钟滴答
** 入口参数: tick 线程睡眠的滴答数
** 返 回 值: 成功返回RT_EOK;失败返回-RT_ERROR
** 调    用: 
*******************************************************************************************/

rt_err_t rt_thread_delay(rt_tick_t tick)
{
    return rt_thread_sleep(tick);
}
RTM_EXPORT(rt_thread_delay);



/*******************************************************************************************
** 函数名称: rt_thread_control
** 函数功能: 给线程发命令
** 入口参数: thread 线程对象句柄
**     cmd 命令
**     arg 附加参数
** 返 回 值: 成功返回RT_EOK;失败返回-RT_ERROR
** 调    用: 
*******************************************************************************************/

rt_err_t rt_thread_control(rt_thread_t thread, rt_uint8_t cmd, void *arg)
{
    register rt_base_t temp;

    /** 参数检查 */
    RT_ASSERT(thread != RT_NULL);

    switch (cmd) {
    case RT_THREAD_CTRL_CHANGE_PRIORITY:/** 改变线程的优先级 */

        /** 禁止全局中断 */
        temp = rt_hw_interrupt_disable();

/** 如果线程为就绪状态 */
        if (thread->stat == RT_THREAD_READY) {

    /** 将线程从就绪队列中移除 */
    rt_schedule_remove_thread(thread);

  /** 改变线程的优先级 */
            thread->current_priority = *(rt_uint8_t *)arg;

    /** 重新计算线程的优先级属性 */
#if RT_THREAD_PRIORITY_MAX > 32
            thread->number      = thread->current_priority >> 3;            /* 5bit */
            thread->number_mask = 1 << thread->number;
            thread->high_mask   = 1 << (thread->current_priority & 0x07);   /* 3bit */
#else
            thread->number_mask = 1 << thread->current_priority;
#endif

    /** 将线程以新的优先级插入到就绪队列中 */
            rt_schedule_insert_thread(thread);
        } else {
    /** 线程的为非就绪状态 */
            thread->current_priority = *(rt_uint8_t *)arg;
#if RT_THREAD_PRIORITY_MAX > 32
            thread->number      = thread->current_priority >> 3;            /* 5bit */
            thread->number_mask = 1 << thread->number;
            thread->high_mask   = 1 << (thread->current_priority & 0x07);   /* 3bit */
#else
            thread->number_mask = 1 << thread->current_priority;
#endif
        }

/** 使能全局中断 */
        rt_hw_interrupt_enable(temp);
        break;

    case RT_THREAD_CTRL_STARTUP:/** 启动线程 */
        return rt_thread_startup(thread);

#ifdef RT_USING_HEAP
    case RT_THREAD_CTRL_CLOSE:/** 释放线程 */
        return rt_thread_delete(thread);
#endif

    default:
        break;
    }

    return RT_EOK;
}
RTM_EXPORT(rt_thread_control);



/*******************************************************************************************
** 函数名称: rt_thread_suspend
** 函数功能: 挂起线程
** 入口参数: thread 线程对象句柄
** 返 回 值: 成功返回RT_EOK;失败返回-RT_ERROR
** 调    用: 
*******************************************************************************************/

rt_err_t rt_thread_suspend(rt_thread_t thread)
{
    register rt_base_t temp;


    /** 参数检查 */
    RT_ASSERT(thread != RT_NULL);

    RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread suspend:  %s\n", thread->name));

    /** 如果线程的状态为非就绪状态,出错 */
    if (thread->stat != RT_THREAD_READY) {
        RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread suspend: thread disorder, %d\n",
                                       thread->stat));
        return -RT_ERROR;
    }

    /** 禁止全局中断 */
    temp = rt_hw_interrupt_disable();

    /** 设置线程的状态为挂起状态 */
    thread->stat = RT_THREAD_SUSPEND;

    /** 将线程从就绪队列中移除 */
    rt_schedule_remove_thread(thread);

    /** 使能全局中断 */
    rt_hw_interrupt_enable(temp);

    return RT_EOK;
}
RTM_EXPORT(rt_thread_suspend);



/*******************************************************************************************
** 函数名称: rt_thread_resume
** 函数功能: 恢复线程
** 入口参数: thread 线程对象句柄
** 返 回 值: 成功返回RT_EOK;失败返回-RT_ERROR
** 调    用: 
*******************************************************************************************/

rt_err_t rt_thread_resume(rt_thread_t thread)
{
    register rt_base_t temp;

    /** 检查参数 */
    RT_ASSERT(thread != RT_NULL);

    RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread resume:  %s\n", thread->name));

    /** 如果线程的状态非挂起状态,出错 */
    if (thread->stat != RT_THREAD_SUSPEND) {
        RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread resume: thread disorder, %d\n",
                                       thread->stat));
        return -RT_ERROR;
    }

    /** 禁止全局中断 */
    temp = rt_hw_interrupt_disable();

    /** 将线程从挂起链表中移除 */
    rt_list_remove(&(thread->tlist));

    /** 停止定时器 */
    rt_timer_stop(&thread->thread_timer);

    /** 使能全局中断 */
    rt_hw_interrupt_enable(temp);

    /** 将线程插入就绪队列中 */
    rt_schedule_insert_thread(thread);

    return RT_EOK;
}
RTM_EXPORT(rt_thread_resume);



/*******************************************************************************************
** 函数名称: rt_thread_timeout
** 函数功能: 线程定时器超时时的处理函数
** 入口参数: parameter 定时器的附加参数
** 返 回 值: 无
** 调    用: 
*******************************************************************************************/

void rt_thread_timeout(void *parameter)
{
    struct rt_thread *thread;

    thread = (struct rt_thread *)parameter;

    /** 参数检查 */
    RT_ASSERT(thread != RT_NULL);
    RT_ASSERT(thread->stat == RT_THREAD_SUSPEND);

    /** 超时 */
    thread->error = -RT_ETIMEOUT;

    /** 从挂起队列中移除 */
    rt_list_remove(&(thread->tlist));

    /** 插入到就绪队列中 */
    rt_schedule_insert_thread(thread);

    /** 调度 */
    rt_schedule();
}
RTM_EXPORT(rt_thread_timeout);


/********************************************************************************************* 函数名称: rt_thread_find
** 函数功能: 由名字找到对应的线程
** 入口参数: 线程对象句柄
** 返 回 值: 无
** 调    用: 
*******************************************************************************************/

rt_thread_t rt_thread_find(char *name)
{
    struct rt_object_information *information;
    struct rt_object *object;
    struct rt_list_node *node;

    extern struct rt_object_information rt_object_container[];

    /** 进入临界区 */
    if (rt_thread_self() != RT_NULL)
        rt_enter_critical();

    information = &rt_object_container[RT_Object_Class_Thread];
    for (node = information->object_list.next; node != &(information->object_list); node = node->next) {

        object = rt_list_entry(node, struct rt_object, list);
        if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0) {

        /** 找到对象后,退出临界区 */
            if (rt_thread_self() != RT_NULL)
                rt_exit_critical();

            return (rt_thread_t)object;
        }
    }

    /** 退出临界区 */
    if (rt_thread_self() != RT_NULL)
        rt_exit_critical();

    /** 没有找到,返回NULL */
    return RT_NULL;
}
RTM_EXPORT(rt_thread_find);


版权声明:本文为博主原创文章,未经博主允许不得转载。

RT-Thread内核之线程调度(四)

标签:操作系统   thread   源码   

原文地址:http://blog.csdn.net/lpjybn/article/details/46863927

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!