This is the mail archive of the
ecos-discuss@sourceware.org
mailing list for the eCos project.
Alarms and Threads Program Problem :: Help Required
- From: "R. Vamshi Krishna" <vamshi at cse dot iitb dot ac dot in>
- To: ecos-dicscuss at ecos dot sourceware dot org
- Cc: ecos-discuss at sources dot redhat dot com
- Date: Thu, 18 Aug 2005 22:09:37 +0530
- Subject: [ECOS] Alarms and Threads Program Problem :: Help Required
Hello,
I am trying to write a program that has 3 threads executing for 1,2,1
seconds each.
These threads must each execute every 5,6,4 seconds respectively.
(Actually in Program I have multiplied these by a factor of 40 ).
I have tried the following program. One might expect the timing to get
screwed up, but
actually the application hangs after saying the following :
"Thread 2A :: Time Before Execution is 1"
hal_isr_default(33) : data (0)
"Thread 2A :: Time After Execution is 27"
"Thread 3 finished at :: 27"
Then I get something like
$..thread .. and some weird numbers ...
PS : Note that it is Thread 3 that says it is finishing.
Can someone tell me where am I going wrong ??
- Vamshi
Misc Data :
- Using Bitmap Scheduler
- Template is Kernel
- Turned Cache Off
- i386 Target with Realtek NIC card.
#include <cyg/kernel/kapi.h>
#include <stdio.h>
#include <stdlib.h>
#define RVK 40
/*
Thread Data-Structure for 3 threads.
*/
cyg_thread thread_s[3];
/*
Stack Space for 3 threads
*/
char stack[3][4096];
/*
Handles for threads.
Also thread entry functions
*/
cyg_handle_t modeA_thread1, modeA_thread2, modeA_thread3;
cyg_thread_entry_t thread1A_entry, thread2A_entry, thread3A_entry;
/*
Forward-Definition of functions
*/
void thread1A_alarm_func(cyg_handle_t, cyg_addrword_t);
void thread2A_alarm_func(cyg_handle_t, cyg_addrword_t);
void thread3A_alarm_func(cyg_handle_t, cyg_addrword_t);
/*
Alarms and Counters related Data Structures
*/
cyg_handle_t thread_counter[3], system_clockH[3], thread_alarmH[3];
cyg_alarm thread_alarm[3];
/*
Kernel Flags
*/
cyg_flag_t flag[3];
/*
Starting the application.
*/
void cyg_user_start(void)
{
/*
Create 3 threads 1A, 2A, 3A .
*/
cyg_thread_create(6,thread1A_entry,(cyg_addrword_t) 0,"Mode A thread 1",
(void *) stack[0],4096,&modeA_thread1,&thread_s[0]);
cyg_thread_create(4,thread2A_entry,(cyg_addrword_t) 0,"Mode A thread 2",
(void *) stack[1],4096,&modeA_thread2,&thread_s[1]);
cyg_thread_create(5,thread3A_entry,(cyg_addrword_t) 0,"Mode A thread 3",
(void *) stack[2],4096,&modeA_thread3,&thread_s[2]);
/*
Intialize the Kernel Flags
*/
cyg_flag_init(&flag[0]);
cyg_flag_init(&flag[1]);
cyg_flag_init(&flag[2]);
/*
Initialize the alarms
Period of each thread is (200/240/120) ticks of real-time clock.
*/
cyg_thread_resume(modeA_thread1);
cyg_thread_resume(modeA_thread2);
cyg_thread_resume(modeA_thread3);
}
void thread1A_entry(cyg_addrword_t data)
{
int i,j,temp;
system_clockH[0] = cyg_real_time_clock();
cyg_clock_to_counter(system_clockH[0], &thread_counter[0]);
cyg_alarm_create(thread_counter[0],thread1A_alarm_func,
(cyg_addrword_t) 0, &thread_alarmH[0], &thread_alarm[0]);
cyg_alarm_initialize(thread_alarmH[0],cyg_current_time()+200,200);
for(;;)
{
/*
The following code executes for 40 ticks (approx) .
This was determined experimentally.
*/
diag_printf("Thread 1A :: Time Before Processing :: is %u\n",
(unsigned int) cyg_current_time());
for(i=0;i<4600;i++)
{
for(j=0;j<10000;j++)
{
;
}
}
diag_printf("Thread 1A :: Time After Processing :: %u\n",
(unsigned int) cyg_current_time());
/*
Wait for Kernel Flag to Signal.
*/
cyg_flag_wait(&flag[0],0x1,
CYG_FLAG_WAITMODE_AND | CYG_FLAG_WAITMODE_CLR);
}
}
void thread2A_entry(cyg_addrword_t data)
{
int i,j;
system_clockH[1] = cyg_real_time_clock();
cyg_clock_to_counter(system_clockH[1], &thread_counter[1]);
cyg_alarm_create(thread_counter[1],thread2A_alarm_func,
(cyg_addrword_t) 0, &thread_alarmH[1], &thread_alarm[1]);
cyg_alarm_initialize(thread_alarmH[1],cyg_current_time()+240,240);
for(;;)
{
/*
The following code executes for 80 ticks (approx) .
This was determined experimentally.
*/
diag_printf("Thread 2A :: Time Before Processing is %u \n",
(unsigned int) cyg_current_time());
for(i=0;i<9206;i++)
{
for(j=0;j<10000;j++)
{
;
}
}
diag_printf("Thread A2 :: Time After Processing is %u \n", (unsigned int) cyg_current_time());
/*
Wait for Kernel Flag to Signal.
*/
cyg_flag_wait(&flag[1],0x1,
CYG_FLAG_WAITMODE_AND | CYG_FLAG_WAITMODE_CLR);
}
}
void thread3A_entry(cyg_addrword_t data)
{
int i,j;
system_clockH[2] = cyg_real_time_clock();
cyg_clock_to_counter(system_clockH[2], &thread_counter[2]);
cyg_alarm_create(thread_counter[2],thread3A_alarm_func,
(cyg_addrword_t) 0, &thread_alarmH[2], &thread_alarm[2]);
cyg_alarm_initialize(thread_alarmH[2],cyg_current_time()+160,160);
for(;;)
{
/*
The following code executes for 40 ticks (approx) .
This was determined experimentally.
*/
diag_printf("Thread 3A :: Time Before Processing is %u \n",
(unsigned int) cyg_current_time());
for(i=0;i<4600;i++)
{
for(j=0;j<10000;j++)
{
;
}
}
diag_printf("Thread 3A :: Time After Processing is %u \n",
(unsigned int) cyg_current_time());
/*
Wait for Kernel Flag to Signal.
*/
cyg_flag_wait(&flag[2],0x1,
CYG_FLAG_WAITMODE_AND | CYG_FLAG_WAITMODE_CLR);
}
}
/*
Alarm-Handlers that suspend the various threads.
*/
void thread1A_alarm_func(cyg_handle_t alarm, cyg_addrword_t data)
{
diag_printf("Thread 1 finished at :: %u \n",
(unsigned int) cyg_current_time());
cyg_flag_setbits(&flag[0], 0x1);
}
void thread2A_alarm_func(cyg_handle_t alarm, cyg_addrword_t data)
{
diag_printf("Thread 2 finished at :: %u \n",
(unsigned int) cyg_current_time());
cyg_flag_setbits(&flag[1], 0x1);
}
void thread3A_alarm_func(cyg_handle_t alarm, cyg_addrword_t data)
{
diag_printf("Thread 3 finished at :: %u \n",
(unsigned int) cyg_current_time());
cyg_flag_setbits(&flag[2], 0x1);
}
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss