From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Kadi, Zafer" To: "'ecos-discuss@sourceware.cygnus.com'" Subject: [ECOS] Time trigger thread and 6 more Date: Wed, 14 Feb 2001 08:52:00 -0000 Message-id: <9678C2B4D848D41187450090276D1FAE04AD5762@FMSMSX32> X-SW-Source: 2001-02/msg00233.html Hello, Has any one had tried a time scheduler thread running with more than 6 other threads? In my case, I have the following C program: and if I have more than 5 threads and I am having problems ? Can anyone test it under their own environment or tell me what the problem may be. Any hints/help will be appreciated/. /******************************************* If you have 5 threads and a timer it works, the timer must be started at higher priority than the others? Thread 0 to 4 , with time being thread 8 ??? *********************************************/ #include #include #include #include #define NTHREADS 9 #define STACKSIZE 4096 static void alarm_prog( cyg_addrword_t data ); /* now declare (and allocate space for) some kernel objects, like the two threads we will use */ static cyg_thread thread_s[NTHREADS]; /* space for two thread objects */ static char stack[NTHREADS][STACKSIZE]; /* space for two 4K stacks */ /* now the handles for the threads */ static cyg_handle_t thread_timer; static cyg_handle_t simple_threadA, simple_threadB; static cyg_handle_t simple_threadAA, simple_threadBB; static cyg_handle_t simple_threadA1, simple_threadB1; static cyg_handle_t simple_threadAA1, simple_threadBB1; /* and now variables for the procedure which is the thread */ cyg_thread_entry_t simple_program; /* and now a mutex to protect calls to the C library */ cyg_mutex_t cliblock; /* we install our own startup routine which sets up threads */ void cyg_user_start(void) { int i; printf("Entering threads cyg_user_start() function\n"); cyg_mutex_init(&cliblock); /*************----------------------------------*******/ i=8; cyg_thread_create(1, alarm_prog, (cyg_addrword_t) i, "Time thread", (void *) stack[i], STACKSIZE, &thread_timer, &thread_s[i]); /************------------------------**************/ i=0; cyg_thread_create(i+2, simple_program, (cyg_addrword_t) i, "Thread A", (void *)stack[i], STACKSIZE, &simple_threadA, &thread_s[i]); i=1; cyg_thread_create(i+2, simple_program, (cyg_addrword_t) i, "Thread B", (void *) stack[i], STACKSIZE, &simple_threadB, &thread_s[i]); i=2; cyg_thread_create(i+2, simple_program, (cyg_addrword_t) i, "Thread AA", (void *) stack[i], STACKSIZE, &simple_threadAA, &thread_s[i]); i=3; cyg_thread_create(i+2, simple_program, (cyg_addrword_t) i, "Thread BB", (void *) stack[i], STACKSIZE, &simple_threadBB, &thread_s[i]); i=4; cyg_thread_create(i+2, simple_program, (cyg_addrword_t) i, "Thread A1", (void *) stack[i], STACKSIZE, &simple_threadA1, &thread_s[i]); /******* works untill I add the next few threads Remove the '/' below and it works under my version of eCos with only 5 threads and 1 time triger thread. ********/ i=5; cyg_thread_create(i+2, simple_program, (cyg_addrword_t) i, "Thread B1", (void *) stack[i], STACKSIZE, &simple_threadB1, &thread_s[i]); i=6; cyg_thread_create(i+2, simple_program, (cyg_addrword_t) i, "Thread AA1", (void *) stack[i], STACKSIZE, &simple_threadAA1, &thread_s[i]); i=7; cyg_thread_create(i+2, simple_program, (cyg_addrword_t) i, "Thread BB1", (void *) stack[i], STACKSIZE, &simple_threadBB1, &thread_s[i]); cyg_thread_resume(simple_threadBB1); cyg_thread_resume(simple_threadAA1); cyg_thread_resume(simple_threadB1); /*************************/ cyg_thread_resume(simple_threadA1); cyg_thread_resume(simple_threadBB); cyg_thread_resume(simple_threadAA); cyg_thread_resume(simple_threadB); cyg_thread_resume(simple_threadA); cyg_thread_resume(thread_timer); } /* this is a simple program which runs in a thread */ void simple_program(cyg_addrword_t data) { int message = (int) data; int delay; printf("Beginning execution; thread data is %d\n", message); cyg_thread_delay(1); for (;;) { delay = 1 + (rand() % 3); /* note: printf() must be protected by a call to cyg_mutex_lock() */ cyg_mutex_lock(&cliblock); { printf("Thread %d: and now a delay of %d clock ticks\n", message, delay); } cyg_mutex_unlock(&cliblock); cyg_thread_delay(delay); } } static cyg_alarm_t test_alarm_func; /* alarm_prog() is a thread which sets up an alarm which is then handled by test_alarm_func() */ static void alarm_prog(cyg_addrword_t data) { cyg_handle_t test_counterH, system_clockH, test_alarmH; cyg_tick_count_t ticks; cyg_alarm test_alarm; unsigned how_many_alarms = 0, prev_alarms = 0, tmp_how_many; system_clockH = cyg_real_time_clock(); cyg_clock_to_counter(system_clockH, &test_counterH); cyg_alarm_create(test_counterH, test_alarm_func, (cyg_addrword_t) &how_many_alarms, &test_alarmH, &test_alarm); cyg_alarm_initialize(test_alarmH, cyg_current_time()+1, 1); /* get in a loop in which we read the current time and print it out, just to have something scrolling by */ for (;;) { ticks = cyg_current_time(); cyg_mutex_lock(&cliblock); { printf("Time is %llu\n", ticks); } cyg_mutex_unlock(&cliblock); // note that we must lock access to how_many_alarms, since the // alarm handler might change it. this involves using the // annoying temporary variable tmp_how_many so that I can keep the // critical region short cyg_scheduler_lock(); tmp_how_many = how_many_alarms; cyg_scheduler_unlock(); if (prev_alarms != tmp_how_many) { cyg_mutex_lock(&cliblock); { printf(" ---> alarm calls so far: %u\n", tmp_how_many); } cyg_mutex_unlock(&cliblock); prev_alarms = tmp_how_many; } cyg_thread_delay(3); } } /* test_alarm_func() is invoked as an alarm handler, so it should be quick and simple. in this case it increments the data that is passed to it. */ void test_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data) { ++*((unsigned *) data); cyg_mutex_lock(&cliblock); { printf("Alarm Triggered\n");} cyg_mutex_unlock(&cliblock); } ============================================================================ ======================= Zafer