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

📄 stress_threads.c

📁 ecos为实时嵌入式操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
//==========================================================================////        stress_threads.cxx////        Basic thread stress test////==========================================================================//####COPYRIGHTBEGIN####//// -------------------------------------------// The contents of this file are subject to the Cygnus eCos Public License// Version 1.0 (the "License"); you may not use this file except in// compliance with the License.  You may obtain a copy of the License at// http://sourceware.cygnus.com/ecos// // 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 Cygnus Operating System, released// September 30, 1998.// // The Initial Developer of the Original Code is Cygnus.  Portions created// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions.  All Rights Reserved.// -------------------------------------------////####COPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):     rosalia// Contributors:  rosalia// Date:          1999-04-13// Description:   Very simple thread stress test, with some memory//                allocation and alarm handling.//####DESCRIPTIONEND#####include <pkgconf/system.h>#include <cyg/infra/testcase.h>#include <cyg/hal/hal_arch.h>#if defined(CYGPKG_KERNEL) && defined(CYGPKG_IO) && defined(CYGPKG_LIBC)#include <pkgconf/kernel.h>#include <pkgconf/libc.h>#if defined(CYGFUN_KERNEL_API_C)#include <cyg/kernel/kapi.h>#ifdef CYGPKG_LIBC_STDIO#include <stdio.h>#include <stdlib.h>#if defined(CYGPKG_LIBM)#include <math.h>#include <assert.h>#if defined(CYGFUN_KERNEL_THREADS_TIMER)#if defined(CYGPKG_LIBC_MALLOC)/* if TIME_LIMIT is defined, it represents the number of seconds this   test should last; if it is undefined the test will go forever */#define DEATH_TIME_LIMIT 15/*  #undef DEATH_TIME_LIMIT */#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL)#define STACK_SIZE2 (8*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL)#define N_CLIENTS 4#define N_LISTENERS 4#define MAX_HANDLERS 19#if (CYGNUM_KERNEL_SCHED_PRIORITIES < (N_CLIENTS+N_LISTENERS+MAX_HANDLERS))# error "not enough priorities available"#endif/* if we use the bitmap scheduler we must make sure we don't use the   same priority more than once, so we must store those already in use */static char priority_in_use[N_CLIENTS+N_LISTENERS+MAX_HANDLERS];/* now declare (and allocate space for) some kernel objects, like the   threads we will use */cyg_thread client_thread_s[N_CLIENTS];cyg_thread listener_thread_s[N_LISTENERS];cyg_thread handler_thread_s[MAX_HANDLERS];/* space for stacks for all threads */char client_stack[N_CLIENTS][STACK_SIZE];char listener_stack[N_LISTENERS][STACK_SIZE];char handler_stack[MAX_HANDLERS][STACK_SIZE2];/* now the handles for the threads */cyg_handle_t clientH[N_CLIENTS];cyg_handle_t listenerH[N_LISTENERS];cyg_handle_t handlerH[MAX_HANDLERS];#ifdef DEATH_TIME_LIMIT/* how many client threads have been killed by the death handler */int n_clients_killed = 0;#endif /* DEATH_TIME_LIMIT *//* and now variables for the procedure which is the thread */cyg_thread_entry_t client_program, listener_program, handler_program;/* a few mutexes used in the code */cyg_mutex_t client_request_lock, handler_slot_lock, statistics_print_lock;/* a global variable with which the client and server coordinate */int client_makes_request = 0;/* indicates that it's time to print out a report */int time_to_report = 0;/*** now application-specific variables ***//* an array that stores whether the handler threads are in use */int handler_thread_in_use[MAX_HANDLERS];/***** statistics-gathering variables *****/struct s_statistics {  /* store the number of times each handler has been invoked */  unsigned long handler_invocation_histogram[MAX_HANDLERS];  /* store how many times malloc has been attempted and how many times     it has failed */  unsigned long malloc_tries, malloc_failures;  /* how many threads have been created */  unsigned long thread_creations, thread_exits;};struct s_statistics statistics;/* some function prototypes; those with the sc_ prefix are   "statistics-collecting" versions of the cyg_ primitives */void sc_thread_create(    cyg_addrword_t        sched_info,           /* scheduling info (eg pri)  */    cyg_thread_entry_t  *entry,                 /* entry point function      */    cyg_addrword_t        entry_data,           /* entry data                */    char                *name,                  /* optional thread name      */    void                *stack_base,            /* stack base, NULL = alloc  */    cyg_ucount32        stack_size,             /* stack size, 0 = default   */    cyg_handle_t        *handle,                /* returned thread handle    */    cyg_thread          *thread                 /* put thread here           */);void sc_thread_exit(void);int get_handler_slot(cyg_handle_t current_threadH);void perform_stressful_tasks(void);void permute_array(char a[], int size, int seed);void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp,                       cyg_alarm *death_alarm_p, int *killed_p);void handle_death(cyg_handle_t deathH, cyg_handle_t alarmH);void print_statistics(void);/* we need to declare the alarm handling function (which is defined   below), so that we can pass it to cyg_alarm_initialize() */cyg_alarm_t report_alarm_func, death_alarm_func;/* handle and alarm for the report alarm */cyg_handle_t report_alarmH, counterH, system_clockH;cyg_alarm report_alarm;/* we install our own startup routine which sets up threads */void cyg_user_start(void){  int i;  CYG_TEST_INIT();  CYG_TEST_INFO("# Entering stress's cyg_user_start() function");  cyg_mutex_init(&client_request_lock);  cyg_mutex_init(&statistics_print_lock);  /* initialize statistics */  memset(&statistics, 0, sizeof(statistics));  /* initialize all handler threads to not be in use */  for (i = 0; i < MAX_HANDLERS; ++i) {    handler_thread_in_use[i] = 0;  }  for (i = 0; i < N_CLIENTS; ++i) {    int prio;    char thread_name[20];    sprintf(thread_name, "client-%02d", i);    prio = i;    sc_thread_create(prio, client_program, (cyg_addrword_t) i,                      thread_name, (void *) client_stack[i], STACK_SIZE,                      &(clientH[i]), &client_thread_s[i]);    priority_in_use[prio] = 1;  }  for (i = 0; i < N_LISTENERS; ++i) {    int prio;    char thread_name[20];    sprintf(thread_name, "listener-%02d", i);    prio = N_CLIENTS + i;    sc_thread_create(prio, listener_program, (cyg_addrword_t) i,                      thread_name, (void *) listener_stack[i], STACK_SIZE,                      &listenerH[i], &listener_thread_s[i]);    priority_in_use[prio] = 1;  }  for (i = 0; i < N_CLIENTS; ++i) {    cyg_thread_resume(clientH[i]);  }  for (i = 0; i < N_LISTENERS; ++i) {    cyg_thread_resume(listenerH[i]);  }  /* set up the alarm which gives periodic wakeups to say "time to     print a report */  system_clockH = cyg_real_time_clock();  cyg_clock_to_counter(system_clockH, &counterH);  cyg_alarm_create(counterH, report_alarm_func,                   (cyg_addrword_t) 4000,                   &report_alarmH, &report_alarm);  if (cyg_test_is_simulator) {    cyg_alarm_initialize(report_alarmH, cyg_current_time()+300, 400);  } else {    cyg_alarm_initialize(report_alarmH, cyg_current_time()+300, 4000);  }}/* client_program() -- an obnoxious client which makes a lot of requests */void client_program(cyg_addrword_t data){  int delay;  cyg_handle_t counterH, deathH, system_clockH;  cyg_alarm death_alarm;  int is_dead = 0;  setup_death_alarm(data, &deathH, &death_alarm, &is_dead);  printf("# Starting client-%d\n", (int) data);  system_clockH = cyg_real_time_clock();  cyg_clock_to_counter(system_clockH, &counterH);  for (;;) {    delay = (rand() % 3);    /* now send a request to the server */    cyg_mutex_lock(&client_request_lock); {      ++client_makes_request;/*        printf("client_makes_request        %d\n", client_makes_request); */    } cyg_mutex_unlock(&client_request_lock);    cyg_thread_delay(10+delay);/*      cyg_thread_delay(0); */#ifdef DEATH_TIME_LIMIT    if (is_dead) {      handle_death(deathH, report_alarmH);    }#endif /* DEATH_TIME_LIMIT */  }}/* listener_program() -- listens for a request and spawns a handler to   take care of the request */void listener_program(cyg_addrword_t data){/*   int message = (int) data; */  int handler_slot;  printf("# Beginning execution; thread data is %d\n", (int) data);  for (;;) {#ifdef DEATH_TIME_LIMIT    /* as an extra task, the listener sees if all clients have been       killed off, so it can report that the test is over */    if (n_clients_killed == N_CLIENTS) {      n_clients_killed = -1;    /* so we don't call this again */      CYG_TEST_PASS_FINISH("Kernel thread stress test OK");

⌨️ 快捷键说明

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