This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Time trigger thread and 6 more


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 <cyg/kernel/kapi.h>

#include <stdio.h>
#include <math.h>
#include <stdlib.h>


#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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]