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

📄 thread_gdb.c

📁 eCos1.31版
💻 C
字号:
//==========================================================================////        thread_gdb.c////        A test for thread support in GDB////==========================================================================//####COPYRIGHTBEGIN####//                                                                          // -------------------------------------------                              // The contents of this file are subject to the Red Hat eCos Public License // Version 1.1 (the "License"); you may not use this file except in         // compliance with the License.  You may obtain a copy of the License at    // http://www.redhat.com/                                                   //                                                                          // Software distributed under the License is distributed on an "AS IS"      // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the // License for the specific language governing rights and limitations under // the License.                                                             //                                                                          // The Original Code is eCos - Embedded Configurable Operating System,      // released September 30, 1998.                                             //                                                                          // The Initial Developer of the Original Code is Red Hat.                   // Portions created by Red Hat are                                          // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             // All Rights Reserved.                                                     // -------------------------------------------                              //                                                                          //####COPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):     nickg// Contributors:  nickg// Date:          1998-09-21// Description:   GDB thread support test.//####DESCRIPTIONEND####// #include <cyg/kernel/kapi.h>#include <cyg/infra/cyg_ass.h>#include <cyg/infra/testcase.h>#if defined(CYGFUN_KERNEL_API_C) && defined(CYGSEM_KERNEL_SCHED_MLQUEUE) &&\    (CYGNUM_KERNEL_SCHED_PRIORITIES > 26)#include <cyg/hal/hal_arch.h>           // for CYGNUM_HAL_STACK_SIZE_TYPICAL// -------------------------------------------------------------------------#define THREADS                 10#ifdef CYGNUM_HAL_STACK_SIZE_TYPICAL#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL#else#define STACKSIZE               (2*1024)#endif#define CONTROLLER_PRI_HI       0#define CONTROLLER_PRI_LO       25#define WORKER_PRI              3#define WORKER_PRI_RANGE        20// -------------------------------------------------------------------------// array of stacks for threadschar thread_stack[THREADS][STACKSIZE];// array of threads.cyg_thread thread[THREADS];cyg_handle_t thread_handle[THREADS];volatile cyg_uint8 worker_state;#define WORKER_STATE_WAIT       1#define WORKER_STATE_BREAK      2#define WORKER_STATE_EXIT       9cyg_mutex_t worker_mutex;cyg_cond_t worker_cv;cyg_count32 workers_asleep = 0;cyg_count32 thread_count[THREADS];cyg_priority_t thread_pri[THREADS];// -------------------------------------------------------------------------extern void breakme(void){}// -------------------------------------------------------------------------void worker( cyg_addrword_t id ){    for(;;)    {        thread_count[id]++;        thread_pri[id] = cyg_thread_get_priority( cyg_thread_self() );                switch( worker_state )        {        case WORKER_STATE_BREAK:            if( 0 == (id % 4) )                breakme();                    case WORKER_STATE_WAIT:            cyg_mutex_lock( &worker_mutex );            workers_asleep++;            cyg_cond_wait( &worker_cv );            workers_asleep--;            cyg_mutex_unlock( &worker_mutex );            break;        case WORKER_STATE_EXIT:            cyg_thread_exit();                    }    }}// -------------------------------------------------------------------------void controller( cyg_addrword_t id ){    cyg_priority_t pri;    int i;    cyg_mutex_init( &worker_mutex );    cyg_cond_init( &worker_cv, &worker_mutex );    // 1 thread, it is running, it calls BREAKME();//  +++ Thread status returned://  +++ 1 thread, running, is the current one        breakme();// Create N more threads; they are all suspended after creation.  Adjust// the priorities of all the threads to lower than the controlling thread.// Make them all be distinct priorities as far as possible.  BREAKME();//  +++ 1 thread, running, + N suspended ones of different prios.    for( i = 1; i < THREADS; i++ )    {        pri = CONTROLLER_PRI_HI + 1 + i % WORKER_PRI_RANGE;        cyg_thread_create(pri, worker, (cyg_addrword_t)i, "worker",                          (void *)(&thread_stack[i]), STACKSIZE,                          &thread_handle[i], &thread[i]);    }    breakme();// Adjust the priorities of all the threads to lower than the controlling// thread.  Make them all be THE SAME priority.  BREAKME();//  +++ 1 thread, running, + N suspended ones of same prio.    for( i = 1; i < THREADS; i++ )    {        cyg_thread_set_priority( thread_handle[i], WORKER_PRI );    }    breakme();    // Release all the N threads, BREAKME();//  +++ 1 thread, running, + N ready ones of same prio.    for( i = 1; i < THREADS; i++ )    {        cyg_thread_resume( thread_handle[i] );    }    breakme();// Adjust the priorities of all the threads, lower than the controlling// thread.  Make them all be distinct priorities as far as possible.// BREAKME();//  +++ 1 thread, running, + N ready ones of different prios.    for( i = 1; i < THREADS; i++ )    {        pri = CONTROLLER_PRI_HI + 1 + i % WORKER_PRI_RANGE;                cyg_thread_set_priority( thread_handle[i], pri );    }    breakme();    // Command all the N threads to sleep; switch my own priority to lower// than theirs so that they all run and sleep, then I get back in and// BREAKME();// +++ 1 thread, running, + N sleeping ones of different prios.    worker_state = WORKER_STATE_WAIT;    cyg_thread_set_priority( thread_handle[0], CONTROLLER_PRI_LO );    breakme();    // Make them all be THE SAME priority; BREAKME();//  +++ 1 thread, running, + N sleeping ones of same prio.    for( i = 1; i < THREADS; i++ )    {        cyg_thread_set_priority( thread_handle[i], WORKER_PRI );    }    breakme();// Wake them all up, they'll loop once and sleep again; I get in and// BREAKME();//  +++ 1 thread, running, + N sleeping ones of same prio.    cyg_cond_broadcast( &worker_cv );    breakme();// Adjust the priorities of all the threads, higher than the controlling// thread.  Make them all be distinct priorities as far as possible.// BREAKME();//  +++ 1 thread, running, + N sleeping ones of different prios.    for( i = 1; i < THREADS; i++ )    {        pri = CONTROLLER_PRI_HI + 1 + i % WORKER_PRI_RANGE;                cyg_thread_set_priority( thread_handle[i], pri );    }    breakme();// Wake them all up, they'll loop once and sleep again; I get in and// BREAKME();//  +++ 1 thread, running, + N sleeping ones of different prios.    cyg_cond_broadcast( &worker_cv );    breakme();// Set them all the same prio, set me to the same prio, BREAKME();//  +++ 1 running, + N sleeping, *all* the same prio.    for( i = 0; i < THREADS; i++ )    {        cyg_thread_set_priority( thread_handle[i], WORKER_PRI );    }    breakme();// Wake them all up, they'll loop once and sleep again; I get in and// BREAKME(); repeatedly until they have all slept again.//  +++ 1 running, + some sleeping, some ready, *all* the same prio.    cyg_cond_broadcast( &worker_cv );//    cyg_thread_yield();        do    {        breakme();            } while( workers_asleep != THREADS-1 );     breakme();    // Suspend some of the threads, BREAKME();//  +++ 1 running, + some sleeping, some suspended, *all* the same prio.    for( i = 1; i < THREADS; i++ )    {        // suspend every 3rd thread        if( 0 == (i % 3) ) cyg_thread_suspend( thread_handle[i] );    }    breakme();// Change the prios all different, change my prio to highest , BREAKME();//  +++ 1 running, + some sleeping, some suspended, different prios.    cyg_thread_set_priority( thread_handle[0], CONTROLLER_PRI_HI );            for( i = 1; i < THREADS; i++ )    {        pri = CONTROLLER_PRI_HI + 1 + i % WORKER_PRI_RANGE;                cyg_thread_set_priority( thread_handle[i], pri );    }    breakme();    // Wake up all the threads, BREAKME();//  +++ 1 running, + some ready, some suspended/ready, different prios.    cyg_cond_broadcast( &worker_cv );    breakme();// Change my prio to lowest, let all the threads run, BREAKME().//  +++ 1 running + some sleeping, some suspended/ready, different prios.    cyg_thread_set_priority( thread_handle[0], CONTROLLER_PRI_LO );        breakme();    // Resume all the threads, BREAKME();//  +++ 1 running, + N ready, different prios.    for( i = 1; i < THREADS; i++ )    {        cyg_thread_resume( thread_handle[i] );    }        breakme();    // Command some of the N threads to call BREAKME(); themselves (then sleep// again).  Change my prio to low, so that they all get to run and hit the// breakpoint.//  +++ A different one running every time, others in a mixture of//      ready and sleeping states.        worker_state = WORKER_STATE_BREAK;    cyg_cond_broadcast( &worker_cv );        cyg_thread_set_priority( thread_handle[0], CONTROLLER_PRI_LO );        breakme();    // Command all the threads to exit; switch my own priority to lower// than theirs so that they all run and exit, then I get back in and// BREAKME();//  +++ 1 thread, running, + N dormant ones.    worker_state = WORKER_STATE_EXIT;    cyg_cond_broadcast( &worker_cv );        breakme();#if 0// Cannot do this yet...    // Destroy some of the N threads to invalidate their IDs.  Re-create them// with new IDs, so that we get IDs 1,2,4,6,8,11,12,13,14,15 in use instead// of 1,2,3,4,5,6,7,8,9, if you see what I mean.  Do all the above again.// Loop forever, or whatever...#endif    breakme();        CYG_TEST_PASS_FINISH("GDB Thread test OK");    }// -------------------------------------------------------------------------externC voidcyg_start( void ){    CYG_TEST_INIT();        cyg_thread_create(CONTROLLER_PRI_HI, controller, (cyg_addrword_t)0, "controller",                      (void *)(&thread_stack[0]), STACKSIZE,                      &thread_handle[0], &thread[0]);        // resume it    cyg_thread_resume(thread_handle[0]);        // Get the world going    cyg_scheduler_start();    CYG_TEST_FAIL_FINISH("Not reached");    }#else /* def CYGFUN_KERNEL_API_C */externC voidcyg_start( void ){    CYG_TEST_INIT();    CYG_TEST_PASS_FINISH("Incorrect configuration for this test");}#endif /* def CYGFUN_KERNEL_API_C && ... */// -------------------------------------------------------------------------// EOF thread_gdb.c

⌨️ 快捷键说明

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