thread.c 20.9 KB
Newer Older
1 2 3
/*
 * File      : thread.c
 * This file is part of RT-Thread RTOS
D
dzzxzz 已提交
4
 * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
5
 *
B
Bernard Xiong 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 20 21 22 23
 *
 * Change Logs:
 * Date           Author       Notes
 * 2006-03-28     Bernard      first version
 * 2006-04-29     Bernard      implement thread timer
24 25 26 27 28
 * 2006-04-30     Bernard      added THREAD_DEBUG
 * 2006-05-27     Bernard      fixed the rt_thread_yield bug
 * 2006-06-03     Bernard      fixed the thread timer init bug
 * 2006-08-10     Bernard      fixed the timer bug in thread_sleep
 * 2006-09-03     Bernard      changed rt_timer_delete to rt_timer_detach
29
 * 2006-09-03     Bernard      implement rt_thread_detach
30
 * 2008-02-16     Bernard      fixed the rt_thread_timeout bug
31 32
 * 2010-03-21     Bernard      change the errno of rt_thread_delay/sleep to
 *                             RT_EOK.
33
 * 2010-11-10     Bernard      add cleanup callback function in thread exit.
34 35
 * 2011-09-01     Bernard      fixed rt_thread_exit issue when the current
 *                             thread preempted, which reported by Jiaxing Lee.
36
 * 2011-09-08     Bernard      fixed the scheduling issue in rt_thread_startup.
37
 * 2012-12-29     Bernard      fixed compiling warning.
38
 * 2016-08-09     ArdaFu       add thread suspend and resume hook.
39 40
 * 2017-04-10     armink       fixed the rt_thread_delete and rt_thread_detach
                               bug when thread has not startup.
41 42 43 44 45 46
 */

#include <rtthread.h>
#include <rthw.h>

extern rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];
D
dzzxzz 已提交
47
extern struct rt_thread *rt_current_thread;
48 49
extern rt_list_t rt_thread_defunct;

50 51 52
#ifdef RT_USING_HOOK

static void (*rt_thread_suspend_hook)(rt_thread_t thread);
B
Bernard Xiong 已提交
53 54 55
static void (*rt_thread_resume_hook) (rt_thread_t thread);
static void (*rt_thread_inited_hook) (rt_thread_t thread);

56 57 58 59 60 61 62 63 64 65 66 67
/**
 * @ingroup Hook
 * This function sets a hook function when the system suspend a thread. 
 *
 * @param hook the specified hook function
 *
 * @note the hook function must be simple and never be blocked or suspend.
 */
void rt_thread_suspend_sethook(void (*hook)(rt_thread_t thread))
{
    rt_thread_suspend_hook = hook;
}
B
Bernard Xiong 已提交
68

69 70 71 72 73 74 75 76 77 78 79 80
/**
 * @ingroup Hook
 * This function sets a hook function when the system resume a thread. 
 *
 * @param hook the specified hook function
 *
 * @note the hook function must be simple and never be blocked or suspend.
 */
void rt_thread_resume_sethook(void (*hook)(rt_thread_t thread))
{
    rt_thread_resume_hook = hook;
}
B
Bernard Xiong 已提交
81 82 83 84 85 86 87 88 89 90 91 92

/**
 * @ingroup Hook
 * This function sets a hook function when a thread is initialized. 
 *
 * @param hook the specified hook function
 */
void rt_thread_inited_sethook(void (*hook)(rt_thread_t thread))
{
	rt_thread_inited_hook = hook;
}

93 94
#endif

95
void rt_thread_exit(void)
96
{
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
    struct rt_thread *thread;
    register rt_base_t level;

    /* get current thread */
    thread = rt_current_thread;

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

    /* remove from schedule */
    rt_schedule_remove_thread(thread);
    /* change stat */
    thread->stat = RT_THREAD_CLOSE;

    /* remove it from timer list */
112
    rt_timer_detach(&thread->thread_timer);
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129

    if ((rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) &&
        thread->cleanup == RT_NULL)
    {
        rt_object_detach((rt_object_t)thread);
    }
    else
    {
        /* insert to defunct thread list */
        rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));
    }

    /* enable interrupt */
    rt_hw_interrupt_enable(level);

    /* switch to next task */
    rt_schedule();
130
}
131

D
dzzxzz 已提交
132
static rt_err_t _rt_thread_init(struct rt_thread *thread,
133 134 135 136 137 138 139
                                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)
140
{
141 142 143 144 145 146 147 148
    /* init thread list */
    rt_list_init(&(thread->tlist));

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

    /* stack init */
    thread->stack_addr = stack_start;
W
weety 已提交
149
    thread->stack_size = stack_size;
150 151 152 153 154 155 156 157 158 159 160 161

    /* init thread stack */
    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);

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

162 163 164 165 166 167
    thread->number_mask = 0;
#if RT_THREAD_PRIORITY_MAX > 32
    thread->number = 0;
    therad->high_mask = 0;
#endif

168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
    /* tick init */
    thread->init_tick      = tick;
    thread->remaining_tick = tick;

    /* error and flags */
    thread->error = RT_EOK;
    thread->stat  = RT_THREAD_INIT;

    /* initialize cleanup function and user data */
    thread->cleanup   = 0;
    thread->user_data = 0;

    /* init thread timer */
    rt_timer_init(&(thread->thread_timer),
                  thread->name,
                  rt_thread_timeout,
                  thread,
                  0,
                  RT_TIMER_FLAG_ONE_SHOT);

B
Bernard Xiong 已提交
188 189
    RT_OBJECT_HOOK_CALL(rt_thread_inited_hook,(thread));

190
    return RT_EOK;
191 192 193 194 195 196
}

/**
 * @addtogroup Thread
 */

D
dogandog 已提交
197
/**@{*/
198 199

/**
B
bernard.xiong@gmail.com 已提交
200 201
 * This function will initialize a thread, normally it's used to initialize a
 * static thread object.
202 203 204 205 206 207 208 209 210 211
 *
 * @param thread the static thread object
 * @param name the name of thread, which shall be unique
 * @param entry the entry function of thread
 * @param parameter the parameter of thread enter function
 * @param stack_start the start address of thread stack
 * @param stack_size the size of thread stack
 * @param priority the priority of thread
 * @param tick the time slice if there are same priority thread
 *
B
bernard.xiong@gmail.com 已提交
212
 * @return the operation status, RT_EOK on OK, -RT_ERROR on error
213
 */
D
dzzxzz 已提交
214
rt_err_t rt_thread_init(struct rt_thread *thread,
215 216 217 218 219 220 221
                        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)
222
{
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
    /* thread check */
    RT_ASSERT(thread != RT_NULL);
    RT_ASSERT(stack_start != RT_NULL);

    /* init thread object */
    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);
238
}
239
RTM_EXPORT(rt_thread_init);
240 241 242 243 244 245

/**
 * This function will return self thread object
 *
 * @return the self thread object
 */
D
dzzxzz 已提交
246
rt_thread_t rt_thread_self(void)
247
{
248
    return rt_current_thread;
249
}
250
RTM_EXPORT(rt_thread_self);
251 252 253 254 255 256

/**
 * This function will start a thread and put it to system ready queue
 *
 * @param thread the thread to be started
 *
B
bernard.xiong@gmail.com 已提交
257
 * @return the operation status, RT_EOK on OK, -RT_ERROR on error
258
 */
D
dzzxzz 已提交
259
rt_err_t rt_thread_startup(rt_thread_t thread)
260
{
261 262 263
    /* thread check */
    RT_ASSERT(thread != RT_NULL);
    RT_ASSERT(thread->stat == RT_THREAD_INIT);
264

265 266
    /* set current priority to init priority */
    thread->current_priority = thread->init_priority;
267

268
    /* calculate priority attribute */
269
#if RT_THREAD_PRIORITY_MAX > 32
270 271 272
    thread->number      = thread->current_priority >> 3;            /* 5bit */
    thread->number_mask = 1L << thread->number;
    thread->high_mask   = 1L << (thread->current_priority & 0x07);  /* 3bit */
273
#else
274
    thread->number_mask = 1L << thread->current_priority;
275 276
#endif

277
    RT_DEBUG_LOG(RT_DEBUG_THREAD, ("startup a thread:%s with priority:%d\n",
278
                                   thread->name, thread->init_priority));
279 280 281 282 283 284 285 286 287 288 289
    /* change thread stat */
    thread->stat = RT_THREAD_SUSPEND;
    /* then resume it */
    rt_thread_resume(thread);
    if (rt_thread_self() != RT_NULL)
    {
        /* do a scheduling */
        rt_schedule();
    }

    return RT_EOK;
290
}
291
RTM_EXPORT(rt_thread_startup);
292 293

/**
B
bernard.xiong@gmail.com 已提交
294 295
 * This function will detach a thread. The thread object will be removed from
 * thread queue and detached/deleted from system object management.
296 297 298
 *
 * @param thread the thread to be deleted
 *
B
bernard.xiong@gmail.com 已提交
299
 * @return the operation status, RT_EOK on OK, -RT_ERROR on error
300
 */
D
dzzxzz 已提交
301
rt_err_t rt_thread_detach(rt_thread_t thread)
302
{
303
    rt_base_t lock;
304

305 306
    /* thread check */
    RT_ASSERT(thread != RT_NULL);
307

308 309 310 311 312
    if (thread->stat != RT_THREAD_INIT)
    {
        /* remove from schedule */
        rt_schedule_remove_thread(thread);
    }
313

314 315
    /* release thread timer */
    rt_timer_detach(&(thread->thread_timer));
316

317 318
    /* change stat */
    thread->stat = RT_THREAD_CLOSE;
319

320 321
    /* detach object */
    rt_object_detach((rt_object_t)thread);
322

323 324 325 326
    if (thread->cleanup != RT_NULL)
    {
        /* disable interrupt */
        lock = rt_hw_interrupt_disable();
327

328 329
        /* insert to defunct thread list */
        rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));
330

331 332 333
        /* enable interrupt */
        rt_hw_interrupt_enable(lock);
    }
334

335
    return RT_EOK;
336
}
337 338
RTM_EXPORT(rt_thread_detach);

339 340

#ifdef RT_USING_HEAP
341 342 343 344 345 346 347 348 349 350 351 352 353 354
/**
 * This function will create a thread object and allocate thread object memory
 * and stack.
 *
 * @param name the name of thread, which shall be unique
 * @param entry the entry function of thread
 * @param parameter the parameter of thread enter function
 * @param stack_size the size of thread stack
 * @param priority the priority of thread
 * @param tick the time slice if there are same priority thread
 *
 * @return the created thread object
 */
rt_thread_t rt_thread_create(const char *name,
355 356 357 358 359
                             void (*entry)(void *parameter),
                             void       *parameter,
                             rt_uint32_t stack_size,
                             rt_uint8_t  priority,
                             rt_uint32_t tick)
360
{
361 362 363 364 365 366 367 368
    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;

B
Bernard Xiong 已提交
369
    stack_start = (void *)RT_KERNEL_MALLOC(stack_size);
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
    if (stack_start == RT_NULL)
    {
        /* allocate stack failure */
        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;
388
}
389
RTM_EXPORT(rt_thread_create);
390

391
/**
B
bernard.xiong@gmail.com 已提交
392
 * This function will delete a thread. The thread object will be removed from
393
 * thread queue and deleted from system object management in the idle thread.
394 395 396
 *
 * @param thread the thread to be deleted
 *
B
bernard.xiong@gmail.com 已提交
397
 * @return the operation status, RT_EOK on OK, -RT_ERROR on error
398
 */
D
dzzxzz 已提交
399
rt_err_t rt_thread_delete(rt_thread_t thread)
400
{
401
    rt_base_t lock;
402

403 404
    /* thread check */
    RT_ASSERT(thread != RT_NULL);
405

406 407 408 409 410
    if (thread->stat != RT_THREAD_INIT)
    {
        /* remove from schedule */
        rt_schedule_remove_thread(thread);
    }
411

412 413
    /* release thread timer */
    rt_timer_detach(&(thread->thread_timer));
414

415 416
    /* change stat */
    thread->stat = RT_THREAD_CLOSE;
417

418 419
    /* disable interrupt */
    lock = rt_hw_interrupt_disable();
420

421 422
    /* insert to defunct thread list */
    rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));
423

424 425
    /* enable interrupt */
    rt_hw_interrupt_enable(lock);
426

427
    return RT_EOK;
428
}
429
RTM_EXPORT(rt_thread_delete);
430 431 432
#endif

/**
B
bernard.xiong@gmail.com 已提交
433 434 435
 * This function will let current thread yield processor, and scheduler will
 * choose a highest thread to run. After yield processor, the current thread
 * is still in READY state.
436
 *
B
bernard.xiong@gmail.com 已提交
437
 * @return RT_EOK
438
 */
D
dzzxzz 已提交
439
rt_err_t rt_thread_yield(void)
440
{
441 442
    register rt_base_t level;
    struct rt_thread *thread;
443

444 445
    /* disable interrupt */
    level = rt_hw_interrupt_disable();
446

447 448
    /* set to current thread */
    thread = rt_current_thread;
449

450 451 452 453 454 455
    /* if the thread stat is READY and on ready queue list */
    if (thread->stat == RT_THREAD_READY &&
        thread->tlist.next != thread->tlist.prev)
    {
        /* remove thread from thread list */
        rt_list_remove(&(thread->tlist));
456

457 458 459
        /* put thread to end of ready queue */
        rt_list_insert_before(&(rt_thread_priority_table[thread->current_priority]),
                              &(thread->tlist));
460

461 462
        /* enable interrupt */
        rt_hw_interrupt_enable(level);
463

464
        rt_schedule();
465

466 467
        return RT_EOK;
    }
468

469 470
    /* enable interrupt */
    rt_hw_interrupt_enable(level);
471

472
    return RT_EOK;
473
}
474
RTM_EXPORT(rt_thread_yield);
475 476 477 478 479 480

/**
 * This function will let current thread sleep for some ticks.
 *
 * @param tick the sleep ticks
 *
B
bernard.xiong@gmail.com 已提交
481
 * @return RT_EOK
482
 */
D
dzzxzz 已提交
483
rt_err_t rt_thread_sleep(rt_tick_t tick)
484
{
485 486
    register rt_base_t temp;
    struct rt_thread *thread;
487

488 489 490 491 492
    /* disable interrupt */
    temp = rt_hw_interrupt_disable();
    /* set to current thread */
    thread = rt_current_thread;
    RT_ASSERT(thread != RT_NULL);
493

494 495
    /* suspend thread */
    rt_thread_suspend(thread);
496

497 498 499
    /* reset the timeout of thread timer and start it */
    rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &tick);
    rt_timer_start(&(thread->thread_timer));
500

501 502
    /* enable interrupt */
    rt_hw_interrupt_enable(temp);
503

504
    rt_schedule();
505

506 507 508
    /* clear error number of this thread to RT_EOK */
    if (thread->error == -RT_ETIMEOUT)
        thread->error = RT_EOK;
509

510
    return RT_EOK;
511 512 513 514 515 516 517
}

/**
 * This function will let current thread delay for some ticks.
 *
 * @param tick the delay ticks
 *
B
bernard.xiong@gmail.com 已提交
518
 * @return RT_EOK
519 520 521
 */
rt_err_t rt_thread_delay(rt_tick_t tick)
{
522
    return rt_thread_sleep(tick);
523
}
524
RTM_EXPORT(rt_thread_delay);
525

B
bernard.xiong@gmail.com 已提交
526 527 528 529 530
/**
 * This function will control thread behaviors according to control command.
 *
 * @param thread the specified thread to be controlled
 * @param cmd the control command, which includes
531
 *  RT_THREAD_CTRL_CHANGE_PRIORITY for changing priority level of thread;
B
bernard.xiong@gmail.com 已提交
532 533 534 535 536 537
 *  RT_THREAD_CTRL_STARTUP for starting a thread;
 *  RT_THREAD_CTRL_CLOSE for delete a thread.
 * @param arg the argument of control command
 *
 * @return RT_EOK
 */
D
dzzxzz 已提交
538
rt_err_t rt_thread_control(rt_thread_t thread, rt_uint8_t cmd, void *arg)
539
{
540
    register rt_base_t temp;
541

542 543
    /* thread check */
    RT_ASSERT(thread != RT_NULL);
544

545 546 547 548 549
    switch (cmd)
    {
    case RT_THREAD_CTRL_CHANGE_PRIORITY:
        /* disable interrupt */
        temp = rt_hw_interrupt_disable();
550

551 552 553 554 555
        /* for ready thread, change queue */
        if (thread->stat == RT_THREAD_READY)
        {
            /* remove thread from schedule queue first */
            rt_schedule_remove_thread(thread);
556

557 558
            /* change thread priority */
            thread->current_priority = *(rt_uint8_t *)arg;
559

560
            /* recalculate priority attribute */
561
#if RT_THREAD_PRIORITY_MAX > 32
562 563 564
            thread->number      = thread->current_priority >> 3;            /* 5bit */
            thread->number_mask = 1 << thread->number;
            thread->high_mask   = 1 << (thread->current_priority & 0x07);   /* 3bit */
565
#else
566
            thread->number_mask = 1 << thread->current_priority;
567 568
#endif

569 570 571 572 573 574
            /* insert thread to schedule queue again */
            rt_schedule_insert_thread(thread);
        }
        else
        {
            thread->current_priority = *(rt_uint8_t *)arg;
575

576
            /* recalculate priority attribute */
577
#if RT_THREAD_PRIORITY_MAX > 32
578 579 580
            thread->number      = thread->current_priority >> 3;            /* 5bit */
            thread->number_mask = 1 << thread->number;
            thread->high_mask   = 1 << (thread->current_priority & 0x07);   /* 3bit */
581
#else
582
            thread->number_mask = 1 << thread->current_priority;
583
#endif
584
        }
585

586 587 588
        /* enable interrupt */
        rt_hw_interrupt_enable(temp);
        break;
589

590 591
    case RT_THREAD_CTRL_STARTUP:
        return rt_thread_startup(thread);
592 593

#ifdef RT_USING_HEAP
594 595
    case RT_THREAD_CTRL_CLOSE:
        return rt_thread_delete(thread);
596 597
#endif

598 599 600
    default:
        break;
    }
601

602
    return RT_EOK;
603
}
604
RTM_EXPORT(rt_thread_control);
605 606 607 608 609 610

/**
 * This function will suspend the specified thread.
 *
 * @param thread the thread to be suspended
 *
B
bernard.xiong@gmail.com 已提交
611
 * @return the operation status, RT_EOK on OK, -RT_ERROR on error
612
 *
B
bernard.xiong@gmail.com 已提交
613 614
 * @note if suspend self thread, after this function call, the
 * rt_schedule() must be invoked.
615
 */
D
dzzxzz 已提交
616
rt_err_t rt_thread_suspend(rt_thread_t thread)
617
{
618
    register rt_base_t temp;
619

620 621
    /* thread check */
    RT_ASSERT(thread != RT_NULL);
622

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

625 626 627
    if (thread->stat != RT_THREAD_READY)
    {
        RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread suspend: thread disorder, %d\n",
628
                                       thread->stat));
B
Bernard Xiong 已提交
629

630 631
        return -RT_ERROR;
    }
632

633 634
    /* disable interrupt */
    temp = rt_hw_interrupt_disable();
635

636 637 638
    /* change thread stat */
    thread->stat = RT_THREAD_SUSPEND;
    rt_schedule_remove_thread(thread);
639

640 641 642
    /* stop thread timer anyway */
    rt_timer_stop(&(thread->thread_timer));

643 644
    /* enable interrupt */
    rt_hw_interrupt_enable(temp);
645

646
    RT_OBJECT_HOOK_CALL(rt_thread_suspend_hook,(thread));
647
    return RT_EOK;
648
}
649
RTM_EXPORT(rt_thread_suspend);
650 651 652 653 654 655

/**
 * This function will resume a thread and put it to system ready queue.
 *
 * @param thread the thread to be resumed
 *
B
bernard.xiong@gmail.com 已提交
656
 * @return the operation status, RT_EOK on OK, -RT_ERROR on error
657
 */
D
dzzxzz 已提交
658
rt_err_t rt_thread_resume(rt_thread_t thread)
659
{
660
    register rt_base_t temp;
661

662 663
    /* thread check */
    RT_ASSERT(thread != RT_NULL);
664

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

667 668 669
    if (thread->stat != RT_THREAD_SUSPEND)
    {
        RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread resume: thread disorder, %d\n",
670
                                       thread->stat));
671

672 673
        return -RT_ERROR;
    }
674

675 676
    /* disable interrupt */
    temp = rt_hw_interrupt_disable();
677

678 679
    /* remove from suspend list */
    rt_list_remove(&(thread->tlist));
680

681
    rt_timer_stop(&thread->thread_timer);
682

683 684
    /* enable interrupt */
    rt_hw_interrupt_enable(temp);
685

686 687
    /* insert to schedule ready list */
    rt_schedule_insert_thread(thread);
688

689
    RT_OBJECT_HOOK_CALL(rt_thread_resume_hook,(thread));
690
    return RT_EOK;
691
}
692
RTM_EXPORT(rt_thread_resume);
693 694

/**
B
bernard.xiong@gmail.com 已提交
695
 * This function is the timeout function for thread, normally which is invoked
696
 * when thread is timeout to wait some resource.
697 698 699
 *
 * @param parameter the parameter of thread timeout function
 */
D
dzzxzz 已提交
700
void rt_thread_timeout(void *parameter)
701
{
702
    struct rt_thread *thread;
703

704
    thread = (struct rt_thread *)parameter;
705

706 707 708
    /* thread check */
    RT_ASSERT(thread != RT_NULL);
    RT_ASSERT(thread->stat == RT_THREAD_SUSPEND);
709

710 711
    /* set error number */
    thread->error = -RT_ETIMEOUT;
712

713 714
    /* remove from suspend list */
    rt_list_remove(&(thread->tlist));
715

716 717
    /* insert to schedule ready list */
    rt_schedule_insert_thread(thread);
718

719 720
    /* do schedule */
    rt_schedule();
721
}
722
RTM_EXPORT(rt_thread_timeout);
723 724 725 726 727 728

/**
 * This function will find the specified thread.
 *
 * @param name the name of thread finding
 *
B
bernard.xiong@gmail.com 已提交
729 730 731
 * @return the found thread
 *
 * @note please don't invoke this function in interrupt status.
732
 */
D
dzzxzz 已提交
733
rt_thread_t rt_thread_find(char *name)
734
{
735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767
    struct rt_object_information *information;
    struct rt_object *object;
    struct rt_list_node *node;

    extern struct rt_object_information rt_object_container[];

    /* enter critical */
    if (rt_thread_self() != RT_NULL)
        rt_enter_critical();

    /* try to find device object */
    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)
        {
            /* leave critical */
            if (rt_thread_self() != RT_NULL)
                rt_exit_critical();

            return (rt_thread_t)object;
        }
    }

    /* leave critical */
    if (rt_thread_self() != RT_NULL)
        rt_exit_critical();

    /* not found */
    return RT_NULL;
768
}
769
RTM_EXPORT(rt_thread_find);
770

D
dogandog 已提交
771
/**@}*/