您的位置:首页 > 其它

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

2015-07-13 16:49 309 查看
以下为线程部分的源码分析:

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,

 
11a88
                         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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  操作系统 thread 源码