Preemption issue, memory problem or something else?

Gedare Bloom gedare at gwmail.gwu.edu
Fri Oct 21 13:54:54 UTC 2011


Create a struct that contains all the globals the file uses. Then for each
task, instantiate a copy of the struct (dynamic with malloc or with an array
of size num_tasks) and pass each task a pointer to a unique struct copy at
task start. You have to rewrite the global var accesses to instead use the
struct pointer, but that is pretty mechanical find-replace.

You can also statically make every global an array of size equal to number
of tasks and change each use to an array access indexed by task number. This
is common for small tests, but less effective if tasks are dynamic or memory
is tight.

-gedare
On Oct 21, 2011 3:54 AM, "Constantine "chicky" Giotopoulos" <
kotsosgiotopoulos at gmail.com> wrote:

> Thank you very much for your prompt answers.
>
> The semaphores didn't do the job, probably because it is not OK to share
> the global state among multiple tasks. Furthermore, from what I understand,
> the semaphores would limit the preemption between tasks, and if that's the
> case, this is not in my intentions.
>
> The second option you are mentioning, I guess involves the use of
> "task_variable_add();" directive? Are there any available examples of its
> use, or the implementation you are suggesting using a struct?
>
> On Wed, Oct 19, 2011 at 5:11 AM, Till Straumann <
> strauman at slac.stanford.edu> wrote:
>
>> **
>> Indeed. A quick look at 'stanford.c' reveals that there are plenty of
>> globals.
>> You have two options:
>>  - add a semaphore that protects the global variables and serialize access
>> to
>>    them, e.g., by taking the semaphore before calling 'stanford()' and
>> releasing
>>    it after return. This assumes that it is OK to share the global state
>> among
>>    multiple tasks.
>>  - modify 'stanford.c' to make it reentrant. Move all global variables to
>> a 'struct'
>>    and pass a pointer to this 'context information' to 'stanford()'. Each
>> task has
>>    it's own copy/instance of such a context. You probably also need to add
>> a routine
>>    for initializing a context.
>>
>> Note: IIRC rtems/newlib's 'rand()' is thread-safe, i.e., every thread has
>> it's own
>> 'rand-state'. Otherwise you'd have to think about that one, too.
>>
>> HTH
>> -- Till
>>
>>
>> On 10/18/2011 08:53 PM, Gedare Bloom wrote:
>>
>> Hi,
>>
>> The most likely answer is that global variables in the stanford.c file are
>> shared and not protected e.g. by semaphores.
>> On Oct 18, 2011 5:31 PM, "Constantine "chicky" Giotopoulos" <
>> kotsosgiotopoulos at gmail.com> wrote:
>>
>>>  Hello everyone.
>>>
>>> I am using RTEMS to create a number of tasks and run a set of functions
>>> performing mostly mathematical operations. These are included in a file
>>> named "stanford.c" (
>>> http://classes.engineering.wustl.edu/cse465/docs/BCCExamples/stanford.c). The problem is that when I enable preemption, for some reason the
>>> functions do not output the expected results.
>>>
>>> I initially create 100 tasks using the following lines of code:
>>>
>>> ----------------------------------------------------------------------------------------------------
>>> rtems_task Init( rtems_task_argument ignored )
>>> {
>>>   rtems_status_code status; rtems_id id;
>>>   int i;
>>>
>>> for (i=0;i<100;i++)
>>> {
>>>     srand(i*3);
>>>
>>>     status = rtems_task_create(
>>>     rtems_build_name( 'T', 'A', '2', ' ' ), rand()%254+1,
>>>     RTEMS_MINIMUM_STACK_SIZE, RTEMS_DEFAULT_MODES,
>>>     RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &id
>>>   );
>>>   assert( !status );
>>>
>>>   status = rtems_task_start( id, task2, id%1000 );
>>>   assert( !status );
>>> }
>>>
>>>   status = rtems_task_delete( RTEMS_SELF );
>>>
>>>   exit( 0 );
>>> }
>>>
>>> -----------------------------------------------------------------------------------------------------------------------------
>>> Then I state the functionality of the tasks.Each task executes the
>>> functions included in the "stanford.c" 5 times using a "for" loop. Each task
>>> is triggered with a "wake_after" directive that is set randomly before each
>>> execution and the priority is changed also randomly after each execution.The
>>> point in that is to get various tasks triggering at a random manner and
>>> taking over the CPU in a (somewwhat) random way:
>>>
>>> ---------------------------------------------------------------------------------------------------------------------------
>>> rtems_task task2( rtems_task_argument id_arg )
>>> {
>>>     rtems_status_code status;
>>>     int i;
>>>
>>>     for (i=0;i<5;i++)
>>>     {
>>>     srand(id_arg*i);
>>>     rtems_task_wake_after(rand()%1000);
>>>     printf("Task2-stanford with id=%d is executing. Iteration:%d\n",
>>> id_arg, i);
>>>     stanford();
>>>     printf("Task2-stanford with id=%d iteration:%d has finished.\n\n\n",
>>> id_arg, i);
>>>
>>>         rtems_task_set_priority(RTEMS_SELF, rand()%254+1, 1);
>>>     }
>>>     rtems_task_delete( RTEMS_SELF );
>>> }
>>>
>>> My configuration options are:
>>> #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
>>> #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
>>> #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
>>> #define CONFIGURE_MICROSECONDS_PER_TICK 100
>>> #define CONFIGURE_MAXIMUM_TASKS 105
>>> #define CONFIGURE_INIT
>>> #include <rtems/confdefs.h>
>>>
>>> --------------------------------------------------------------------------------------------------------------------------
>>> I have attached the code that is being executed (test.c-makefile)
>>>
>>> If I enable non-preemption, then the execution output is as expected, no
>>> error messages or anything out of the ordinary, for example:
>>>
>>> ------------------------------------------------------------------------------------------------------------------------
>>> Task2-stanford with id=698 is executing. Iteration:0
>>> Starting
>>>     Perm  Towers  Queens   Intmm      Mm  Puzzle   Quick  Bubble
>>> Tree     FFT
>>>        0       0       0       0       0       0       0       0
>>> 0       0
>>>
>>> Nonfloating point composite is          0
>>>
>>> Floating point composite is          0
>>> Task2-stanford with id=698 iteration:0 has finished.
>>>
>>>
>>> Task2-stanford with id=714 is executing. Iteration:0
>>> Starting
>>>     Perm  Towers  Queens   Intmm      Mm  Puzzle   Quick  Bubble
>>> Tree     FFT
>>>        0       0       0       0       0       0       0       0
>>> 0       0
>>>
>>> Nonfloating point composite is          0
>>>
>>> Floating point composite is          0
>>> Task2-stanford with id=714 iteration:0 has finished.
>>>
>>>
>>> Task2-stanford with id=730 is executing. Iteration:0
>>> Starting
>>>     Perm  Towers  Queens   Intmm      Mm  Puzzle   Quick  Bubble
>>> Tree     FFT
>>>        0       0       0       0       0       0       0       0
>>> 0       0
>>>
>>> Nonfloating point composite is          0
>>>
>>> Floating point composite is          0
>>> Task2-stanford with id=730 iteration:0 has finished.
>>>
>>> However, when I enable preemption, tasks start interrupting each
>>> other (depending on their priority). Especially when it comes to functions
>>> that use recursion, I am presented with errors. These do not occur everytime
>>> these functions are executed, but occasionally. These errors occur mostly
>>> when a task is interrupted by another task(s) of higher priority. The error
>>> messages are somewhat like that:
>>> "   Perm  Towers Error in Towers: nothing to pop
>>>  Error in Towers: nothing to pop
>>>  Error in Towers: disc size error
>>>  Error in Towers: disc size error
>>>  Error in Towers: nothing to pop
>>>  Error in Towers: nothing to pop
>>>  Error in Towers: disc size error"
>>>
>>> "Task2-stanford with id=714 is executing. Iteration:2
>>> Starting
>>> Task2-stanford with id=745 is executing. Iteration:3
>>> Starting
>>>     Perm  Towers  Queens   Intmm      Mm  Puzzle   Quick  Bubble
>>> Tree     FFT
>>>        0       0       0       0       0       0       0       0
>>> 0       0
>>>
>>> Nonfloating point composite is          0
>>>
>>> Floating point composite is          0
>>> Task2-stanford with id=745 iteration:3 has finished.
>>>
>>>
>>>    * Perm Error in Perm.
>>> *  Towers  Queens   Intmm      Mm  Puzzle   Quick  Bubble    Tree
>>> FFT
>>>        0       0       0       0       0       0       0       0
>>> 0       0
>>>
>>> Nonfloating point composite is          0
>>>
>>> Floating point composite is          0
>>> Task2-stanford with id=714 iteration:2 has finished.
>>>
>>>
>>>   *  Perm Error in Perm. *
>>> Task2-stanford with id=714 is executing. Iteration:3
>>> Starting
>>>     Perm  Towers  Queens   Intmm      Mm  Puzzle   Quick  Bubble
>>> Tree     FFT
>>>        0       0       0       0       0       0       0       0
>>> 0       0
>>>
>>> Nonfloating point composite is          0
>>>
>>> Floating point composite is          0
>>> Task2-stanford with id=714 iteration:3 has finished."
>>>
>>> -------------------------------------------------------------------------------------------------------------------------------------------------
>>>
>>> My question is, why are these errors produced when I enable preemption
>>> and are not produced when I disable preemption? Does the fact that this
>>> concerns only the recursive functions have to do anything with the problem?
>>> Could for some reason, when there is a context switch, the data in the
>>> registers of the task being interrupted are not stored correctly in the
>>> memory? Or that they are not being correctly transfered back to the
>>> registers when it's their turn to be executed again?
>>>
>>> Or could it be a memory issue? I have tried initializing the tasks with
>>> (RTEMS_MINIMUM_STACK_SIZE * 2) but the errors keep coming. I also tried to
>>> allocate more memory to the task stack by using the
>>> "CONFIGURE_EXTRA_TASK_STACKS", but when I checked if with the
>>> "rtems_stack_checker_report_usage" directive, for some reason it didn't have
>>> an impact at the available memory being used by the tasks.
>>>
>>> What I need, is for the program to execute with preemption enabled
>>> without presenting these errors.
>>> What am I missing out? Are there any options I could utilize, or
>>> debugging with gdb is the way to continue (I'd like to avoid that if
>>> possible)?
>>>
>>> Thank you in advance.
>>>
>>>
>>>
>>> _______________________________________________
>>> rtems-users mailing list
>>> rtems-users at rtems.org
>>> http://www.rtems.org/mailman/listinfo/rtems-users
>>>
>>>
>>
>
> _______________________________________________
> rtems-users mailing list
> rtems-users at rtems.org
> http://www.rtems.org/mailman/listinfo/rtems-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20111021/1680e03b/attachment-0001.html>


More information about the users mailing list