forked from Imagelibrary/rtems
@@ -203,71 +203,6 @@ package body RTEMS.Tasks is
|
||||
|
||||
end Mode;
|
||||
|
||||
procedure Variable_Add
|
||||
(ID : in RTEMS.ID;
|
||||
Task_Variable : in RTEMS.Address;
|
||||
Dtor : in Variable_Dtor;
|
||||
Result : out RTEMS.Status_Codes)
|
||||
is
|
||||
function Variable_Add_Base
|
||||
(ID : RTEMS.ID;
|
||||
Task_Variable : RTEMS.Address;
|
||||
Dtor : Variable_Dtor)
|
||||
return RTEMS.Status_Codes;
|
||||
pragma Import (C, Variable_Add_Base, "rtems_task_variable_add");
|
||||
begin
|
||||
|
||||
Result := Variable_Add_Base (ID, Task_Variable, Dtor);
|
||||
|
||||
end Variable_Add;
|
||||
|
||||
procedure Variable_Get
|
||||
(ID : in RTEMS.ID;
|
||||
Task_Variable : out RTEMS.Address;
|
||||
Task_Variable_Value : out RTEMS.Address;
|
||||
Result : out RTEMS.Status_Codes)
|
||||
is
|
||||
function Variable_Get_Base
|
||||
(ID : RTEMS.ID;
|
||||
Task_Variable : access RTEMS.Address;
|
||||
Task_Variable_Value : access RTEMS.Address)
|
||||
return RTEMS.Status_Codes;
|
||||
pragma Import (C, Variable_Get_Base, "rtems_task_variable_get");
|
||||
Task_Variable_Base : aliased RTEMS.Address;
|
||||
Task_Variable_Value_Base : aliased RTEMS.Address;
|
||||
begin
|
||||
|
||||
Result :=
|
||||
Variable_Get_Base
|
||||
(ID,
|
||||
Task_Variable_Base'Access,
|
||||
Task_Variable_Value_Base'Access);
|
||||
Task_Variable := Task_Variable_Base;
|
||||
Task_Variable_Value := Task_Variable_Value_Base;
|
||||
|
||||
end Variable_Get;
|
||||
|
||||
procedure Variable_Delete
|
||||
(ID : in RTEMS.ID;
|
||||
Task_Variable : out RTEMS.Address;
|
||||
Result : out RTEMS.Status_Codes)
|
||||
is
|
||||
function Variable_Delete_Base
|
||||
(ID : RTEMS.ID;
|
||||
Task_Variable : access RTEMS.Address)
|
||||
return RTEMS.Status_Codes;
|
||||
pragma Import
|
||||
(C,
|
||||
Variable_Delete_Base,
|
||||
"rtems_task_variable_delete");
|
||||
Task_Variable_Base : aliased RTEMS.Address;
|
||||
begin
|
||||
|
||||
Result := Variable_Delete_Base (ID, Task_Variable_Base'Access);
|
||||
Task_Variable := Task_Variable_Base;
|
||||
|
||||
end Variable_Delete;
|
||||
|
||||
procedure Wake_When
|
||||
(Time_Buffer : in RTEMS.Time_Of_Day;
|
||||
Result : out RTEMS.Status_Codes)
|
||||
|
||||
@@ -117,31 +117,6 @@ package RTEMS.Tasks is
|
||||
Result : out RTEMS.Status_Codes
|
||||
);
|
||||
|
||||
type Variable_Dtor is access procedure (
|
||||
Argument : in RTEMS.Address
|
||||
);
|
||||
pragma Convention (C, Variable_Dtor);
|
||||
|
||||
procedure Variable_Add (
|
||||
ID : in RTEMS.ID;
|
||||
Task_Variable : in RTEMS.Address;
|
||||
Dtor : in Variable_Dtor;
|
||||
Result : out RTEMS.Status_Codes
|
||||
);
|
||||
|
||||
procedure Variable_Get (
|
||||
ID : in RTEMS.ID;
|
||||
Task_Variable : out RTEMS.Address;
|
||||
Task_Variable_Value : out RTEMS.Address;
|
||||
Result : out RTEMS.Status_Codes
|
||||
);
|
||||
|
||||
procedure Variable_Delete (
|
||||
ID : in RTEMS.ID;
|
||||
Task_Variable : out RTEMS.Address;
|
||||
Result : out RTEMS.Status_Codes
|
||||
);
|
||||
|
||||
procedure Wake_When (
|
||||
Time_Buffer : in RTEMS.Time_Of_Day;
|
||||
Result : out RTEMS.Status_Codes
|
||||
|
||||
@@ -104,13 +104,6 @@ librtems_a_SOURCES += src/taskstart.c
|
||||
librtems_a_SOURCES += src/tasksuspend.c
|
||||
librtems_a_SOURCES += src/taskwakeafter.c
|
||||
librtems_a_SOURCES += src/taskwakewhen.c
|
||||
if HAS_SMP
|
||||
else
|
||||
librtems_a_SOURCES += src/taskvariableadd.c
|
||||
librtems_a_SOURCES += src/taskvariabledelete.c
|
||||
librtems_a_SOURCES += src/taskvariableget.c
|
||||
librtems_a_SOURCES += src/taskvariable_invoke_dtor.c
|
||||
endif
|
||||
librtems_a_SOURCES += src/schedulergetprocessorset.c
|
||||
librtems_a_SOURCES += src/schedulerident.c
|
||||
|
||||
|
||||
@@ -372,52 +372,6 @@ rtems_status_code rtems_task_is_suspended(
|
||||
rtems_id id
|
||||
);
|
||||
|
||||
#if !defined(RTEMS_SMP)
|
||||
/**
|
||||
* @brief RTEMS Add Task Variable
|
||||
*
|
||||
* @deprecated Task variables are deprecated.
|
||||
*
|
||||
* This directive adds a per task variable.
|
||||
*
|
||||
* @note This service is not available in SMP configurations.
|
||||
*/
|
||||
rtems_status_code rtems_task_variable_add(
|
||||
rtems_id tid,
|
||||
void **ptr,
|
||||
void (*dtor)(void *)
|
||||
) RTEMS_DEPRECATED;
|
||||
|
||||
/**
|
||||
* @brief Get a per-task variable
|
||||
*
|
||||
* @deprecated Task variables are deprecated.
|
||||
*
|
||||
* This directive gets the value of a task variable.
|
||||
*
|
||||
* @note This service is not available in SMP configurations.
|
||||
*/
|
||||
rtems_status_code rtems_task_variable_get(
|
||||
rtems_id tid,
|
||||
void **ptr,
|
||||
void **result
|
||||
) RTEMS_DEPRECATED;
|
||||
|
||||
/**
|
||||
* @brief RTEMS Delete Task Variable
|
||||
*
|
||||
* @deprecated Task variables are deprecated.
|
||||
*
|
||||
* This directive removes a per task variable.
|
||||
*
|
||||
* @note This service is not available in SMP configurations.
|
||||
*/
|
||||
rtems_status_code rtems_task_variable_delete(
|
||||
rtems_id tid,
|
||||
void **ptr
|
||||
) RTEMS_DEPRECATED;
|
||||
#endif
|
||||
|
||||
#if defined(__RTEMS_HAVE_SYS_CPUSET_H__)
|
||||
/**
|
||||
* @brief Gets the processor affinity set of a task.
|
||||
|
||||
@@ -47,21 +47,6 @@ extern Thread_Information _RTEMS_tasks_Information;
|
||||
*/
|
||||
void _RTEMS_tasks_Initialize_user_tasks( void );
|
||||
|
||||
#if !defined(RTEMS_SMP)
|
||||
/**
|
||||
* @brief RTEMS Tasks Invoke Task Variable Destructor
|
||||
*
|
||||
* @deprecated Task variables are deprecated.
|
||||
*
|
||||
* This routine invokes the optional user provided destructor on the
|
||||
* task variable and frees the memory for the task variable.
|
||||
*/
|
||||
void _RTEMS_Tasks_Invoke_task_variable_dtor(
|
||||
Thread_Control *the_thread,
|
||||
rtems_task_variable_t *tvp
|
||||
) RTEMS_DEPRECATED;
|
||||
#endif
|
||||
|
||||
RTEMS_INLINE_ROUTINE Thread_Control *_RTEMS_tasks_Allocate(void)
|
||||
{
|
||||
_Objects_Allocator_lock();
|
||||
|
||||
@@ -856,40 +856,10 @@
|
||||
*
|
||||
* @section ClassicTasksSecPerTaskVariables Per Task Variables
|
||||
*
|
||||
* Per task variables are used to support global variables whose value may be
|
||||
* unique to a task. After indicating that a variable should be treated as
|
||||
* private (i.e. per-task) the task can access and modify the variable, but the
|
||||
* modifications will not appear to other tasks, and other tasks' modifications
|
||||
* to that variable will not affect the value seen by the task. This is
|
||||
* accomplished by saving and restoring the variable's value each time a task
|
||||
* switch occurs to or from the calling task.
|
||||
*
|
||||
* The value seen by other tasks, including those which have not added the
|
||||
* variable to their set and are thus accessing the variable as a common
|
||||
* location shared among tasks, can not be affected by a task once it has added
|
||||
* a variable to its local set. Changes made to the variable by other tasks
|
||||
* will not affect the value seen by a task which has added the variable to its
|
||||
* private set.
|
||||
*
|
||||
* This feature can be used when a routine is to be spawned repeatedly as
|
||||
* several independent tasks. Although each task will have its own stack, and
|
||||
* thus separate stack variables, they will all share the same static and
|
||||
* global variables. To make a variable not shareable (i.e. a "global" variable
|
||||
* that is specific to a single task), the tasks can call
|
||||
* rtems_task_variable_add() to make a separate copy of the variable for each
|
||||
* task, but all at the same physical address.
|
||||
*
|
||||
* Task variables increase the context switch time to and from the tasks that
|
||||
* own them so it is desirable to minimize the number of task variables. One
|
||||
* efficient method is to have a single task variable that is a pointer to a
|
||||
* dynamically allocated structure containing the task's private "global" data.
|
||||
*
|
||||
* A critical point with per-task variables is that each task must separately
|
||||
* request that the same global variable is per-task private.
|
||||
*
|
||||
* @b {WARNING}: Per-task variables are fundamentally incorrect in SMP
|
||||
* systems and should not be used in SMP applications. They
|
||||
* are disabled.
|
||||
* Per task variables are no longer available. In particular the
|
||||
* rtems_task_variable_add(), rtems_task_variable_get() and
|
||||
* rtems_task_variable_delete() functions are neither declared nor defined
|
||||
* anymore. Use thread local storage or POSIX Keys instead.
|
||||
*
|
||||
* @section ClassicTasksSecBuildingTaskAttributeSet Building a Task Attribute Set
|
||||
*
|
||||
|
||||
@@ -18,20 +18,13 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/config.h>
|
||||
#include <rtems/sysinit.h>
|
||||
#include <rtems/rtems/asrimpl.h>
|
||||
#include <rtems/rtems/eventimpl.h>
|
||||
#include <rtems/rtems/signalimpl.h>
|
||||
#include <rtems/rtems/status.h>
|
||||
#include <rtems/rtems/support.h>
|
||||
#include <rtems/rtems/modes.h>
|
||||
#include <rtems/rtems/tasksimpl.h>
|
||||
#include <rtems/score/stack.h>
|
||||
#include <rtems/score/threadimpl.h>
|
||||
#include <rtems/score/userextimpl.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
|
||||
Thread_Information _RTEMS_tasks_Information;
|
||||
|
||||
@@ -91,87 +84,12 @@ static void _RTEMS_tasks_Delete_extension(
|
||||
_ASR_Destroy( &api->Signal );
|
||||
}
|
||||
|
||||
static void _RTEMS_tasks_Terminate_extension(
|
||||
Thread_Control *executing
|
||||
)
|
||||
{
|
||||
/*
|
||||
* Free per task variable memory
|
||||
*
|
||||
* Per Task Variables are only enabled in uniprocessor configurations.
|
||||
*/
|
||||
#if !defined(RTEMS_SMP)
|
||||
/*
|
||||
* We know this is deprecated and don't want a warning on every BSP built.
|
||||
*/
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
do {
|
||||
rtems_task_variable_t *tvp, *next;
|
||||
|
||||
tvp = executing->task_variables;
|
||||
executing->task_variables = NULL;
|
||||
while (tvp) {
|
||||
next = (rtems_task_variable_t *)tvp->next;
|
||||
_RTEMS_Tasks_Invoke_task_variable_dtor( executing, tvp );
|
||||
tvp = next;
|
||||
}
|
||||
} while (0);
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(RTEMS_SMP)
|
||||
/*
|
||||
* _RTEMS_tasks_Switch_extension
|
||||
*
|
||||
* This extension routine is invoked at each context switch.
|
||||
*
|
||||
* @note Since this only needs to address per-task variables, it is
|
||||
* disabled entirely for SMP configurations.
|
||||
*/
|
||||
static void _RTEMS_tasks_Switch_extension(
|
||||
Thread_Control *executing,
|
||||
Thread_Control *heir
|
||||
)
|
||||
{
|
||||
rtems_task_variable_t *tvp;
|
||||
|
||||
/*
|
||||
* Per Task Variables are only enabled in uniprocessor configurations
|
||||
*/
|
||||
|
||||
tvp = executing->task_variables;
|
||||
while (tvp) {
|
||||
tvp->tval = *tvp->ptr;
|
||||
*tvp->ptr = tvp->gval;
|
||||
tvp = (rtems_task_variable_t *)tvp->next;
|
||||
}
|
||||
|
||||
tvp = heir->task_variables;
|
||||
while (tvp) {
|
||||
tvp->gval = *tvp->ptr;
|
||||
*tvp->ptr = tvp->tval;
|
||||
tvp = (rtems_task_variable_t *)tvp->next;
|
||||
}
|
||||
}
|
||||
#define RTEMS_TASKS_SWITCH_EXTENSION _RTEMS_tasks_Switch_extension
|
||||
#else
|
||||
#define RTEMS_TASKS_SWITCH_EXTENSION NULL
|
||||
#endif
|
||||
|
||||
User_extensions_Control _RTEMS_tasks_User_extensions = {
|
||||
{ NULL, NULL },
|
||||
{ { NULL, NULL }, RTEMS_TASKS_SWITCH_EXTENSION },
|
||||
{ _RTEMS_tasks_Create_extension, /* create */
|
||||
_RTEMS_tasks_Start_extension, /* start */
|
||||
_RTEMS_tasks_Start_extension, /* restart */
|
||||
_RTEMS_tasks_Delete_extension, /* delete */
|
||||
RTEMS_TASKS_SWITCH_EXTENSION, /* switch */
|
||||
NULL, /* begin */
|
||||
NULL, /* exitted */
|
||||
NULL, /* fatal */
|
||||
_RTEMS_tasks_Terminate_extension /* terminate */
|
||||
.Callouts = {
|
||||
.thread_create = _RTEMS_tasks_Create_extension,
|
||||
.thread_start = _RTEMS_tasks_Start_extension,
|
||||
.thread_restart = _RTEMS_tasks_Start_extension,
|
||||
.thread_delete = _RTEMS_tasks_Delete_extension
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief RTEMS Tasks Invoke Task Variable Destructor
|
||||
* @ingroup ClassicTasks
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2014.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if !defined(RTEMS_SMP)
|
||||
#include <rtems/rtems/tasksimpl.h>
|
||||
#include <rtems/score/threadimpl.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
|
||||
/*
|
||||
* We know this is deprecated and don't want a warning on every BSP built.
|
||||
*/
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
void _RTEMS_Tasks_Invoke_task_variable_dtor(
|
||||
Thread_Control *the_thread,
|
||||
rtems_task_variable_t *tvp
|
||||
)
|
||||
{
|
||||
void (*dtor)(void *);
|
||||
void *value;
|
||||
|
||||
dtor = tvp->dtor;
|
||||
if (_Thread_Get_executing() == the_thread) {
|
||||
value = *tvp->ptr;
|
||||
*tvp->ptr = tvp->gval;
|
||||
} else {
|
||||
value = tvp->tval;
|
||||
}
|
||||
|
||||
if ( dtor )
|
||||
(*dtor)(value);
|
||||
|
||||
_Workspace_Free(tvp);
|
||||
}
|
||||
#endif
|
||||
@@ -1,97 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief RTEMS Add Task Variable
|
||||
* @ingroup ClassicTasks
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2014.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if !defined(RTEMS_SMP)
|
||||
#include <rtems/rtems/tasks.h>
|
||||
#include <rtems/score/threadimpl.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#include <rtems/config.h>
|
||||
|
||||
/*
|
||||
* We know this is deprecated and don't want a warning on every BSP built.
|
||||
*/
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
rtems_status_code rtems_task_variable_add(
|
||||
rtems_id tid,
|
||||
void **ptr,
|
||||
void (*dtor)(void *)
|
||||
)
|
||||
{
|
||||
Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
rtems_task_variable_t *tvp, *new;
|
||||
|
||||
#if defined( RTEMS_SMP )
|
||||
if ( rtems_configuration_is_smp_enabled() ) {
|
||||
return RTEMS_NOT_IMPLEMENTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( !ptr )
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
|
||||
the_thread = _Thread_Get (tid, &location);
|
||||
switch (location) {
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
/*
|
||||
* Figure out if the variable is already in this task's list.
|
||||
*/
|
||||
tvp = the_thread->task_variables;
|
||||
while (tvp) {
|
||||
if (tvp->ptr == ptr) {
|
||||
tvp->dtor = dtor;
|
||||
_Objects_Put( &the_thread->Object );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
tvp = (rtems_task_variable_t *)tvp->next;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now allocate memory for this task variable.
|
||||
*/
|
||||
new = (rtems_task_variable_t *)
|
||||
_Workspace_Allocate(sizeof(rtems_task_variable_t));
|
||||
if (new == NULL) {
|
||||
_Objects_Put( &the_thread->Object );
|
||||
return RTEMS_NO_MEMORY;
|
||||
}
|
||||
new->gval = *ptr;
|
||||
new->ptr = ptr;
|
||||
new->dtor = dtor;
|
||||
|
||||
new->next = (struct rtems_task_variable_tt *)the_thread->task_variables;
|
||||
the_thread->task_variables = new;
|
||||
_Objects_Put( &the_thread->Object );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
case OBJECTS_REMOTE:
|
||||
_Thread_Dispatch();
|
||||
return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
|
||||
#endif
|
||||
|
||||
case OBJECTS_ERROR:
|
||||
break;
|
||||
}
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
@@ -1,86 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief RTEMS Delete Task Variable
|
||||
* @ingroup ClassicTasks
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2014.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if !defined(RTEMS_SMP)
|
||||
#include <rtems/rtems/tasksimpl.h>
|
||||
#include <rtems/score/threadimpl.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#include <rtems/config.h>
|
||||
|
||||
/*
|
||||
* We know this is deprecated and don't want a warning on every BSP built.
|
||||
*/
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
rtems_status_code rtems_task_variable_delete(
|
||||
rtems_id tid,
|
||||
void **ptr
|
||||
)
|
||||
{
|
||||
Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
rtems_task_variable_t *tvp, *prev;
|
||||
|
||||
#if defined( RTEMS_SMP )
|
||||
if ( rtems_configuration_is_smp_enabled() ) {
|
||||
return RTEMS_NOT_IMPLEMENTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( !ptr )
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
|
||||
prev = NULL;
|
||||
|
||||
the_thread = _Thread_Get (tid, &location);
|
||||
switch (location) {
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
tvp = the_thread->task_variables;
|
||||
while (tvp) {
|
||||
if (tvp->ptr == ptr) {
|
||||
if (prev)
|
||||
prev->next = tvp->next;
|
||||
else
|
||||
the_thread->task_variables = (rtems_task_variable_t *)tvp->next;
|
||||
|
||||
_RTEMS_Tasks_Invoke_task_variable_dtor( the_thread, tvp );
|
||||
_Objects_Put( &the_thread->Object );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
prev = tvp;
|
||||
tvp = (rtems_task_variable_t *)tvp->next;
|
||||
}
|
||||
_Objects_Put( &the_thread->Object );
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
case OBJECTS_REMOTE:
|
||||
_Thread_Dispatch();
|
||||
return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
|
||||
#endif
|
||||
|
||||
case OBJECTS_ERROR:
|
||||
break;
|
||||
}
|
||||
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
@@ -1,88 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief Get a per-task variable
|
||||
* @ingroup ClassicTasks Tasks
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2014.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if !defined(RTEMS_SMP)
|
||||
#include <rtems/rtems/tasksimpl.h>
|
||||
#include <rtems/score/threadimpl.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#include <rtems/config.h>
|
||||
|
||||
/*
|
||||
* We know this is deprecated and don't want a warning on every BSP built.
|
||||
*/
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
rtems_status_code rtems_task_variable_get(
|
||||
rtems_id tid,
|
||||
void **ptr,
|
||||
void **result
|
||||
)
|
||||
{
|
||||
Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
rtems_task_variable_t *tvp;
|
||||
|
||||
#if defined( RTEMS_SMP )
|
||||
if ( rtems_configuration_is_smp_enabled() ) {
|
||||
return RTEMS_NOT_IMPLEMENTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( !ptr )
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
|
||||
if ( !result )
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
|
||||
the_thread = _Thread_Get (tid, &location);
|
||||
switch (location) {
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
/*
|
||||
* Figure out if the variable is in this task's list.
|
||||
*/
|
||||
tvp = the_thread->task_variables;
|
||||
while (tvp) {
|
||||
if (tvp->ptr == ptr) {
|
||||
/*
|
||||
* Should this return the current (i.e not the
|
||||
* saved) value if `tid' is the current task?
|
||||
*/
|
||||
*result = tvp->tval;
|
||||
_Objects_Put( &the_thread->Object );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
tvp = (rtems_task_variable_t *)tvp->next;
|
||||
}
|
||||
_Objects_Put( &the_thread->Object );
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
case OBJECTS_REMOTE:
|
||||
_Thread_Dispatch();
|
||||
return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
|
||||
#endif
|
||||
|
||||
case OBJECTS_ERROR:
|
||||
break;
|
||||
}
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
@@ -2100,42 +2100,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
|
||||
#define CONFIGURE_TASKS \
|
||||
(CONFIGURE_MAXIMUM_TASKS + CONFIGURE_LIBBLOCK_TASKS)
|
||||
|
||||
/**
|
||||
* This macro calculates the memory required for task variables.
|
||||
*
|
||||
* @deprecated Task variables are deprecated.
|
||||
*
|
||||
* Each task variable is individually allocated from the Workspace.
|
||||
* Hence, we do the multiplication on the configured size.
|
||||
*
|
||||
* @note Per-task variables are disabled for SMP configurations.
|
||||
*/
|
||||
#if defined(RTEMS_SMP)
|
||||
#ifdef CONFIGURE_MAXIMUM_TASK_VARIABLES
|
||||
#warning "Per-Task Variables are deprecated and will be removed."
|
||||
#error "Per-Task Variables are not safe for SMP systems and disabled."
|
||||
#endif
|
||||
#define CONFIGURE_MAXIMUM_TASK_VARIABLES 0
|
||||
#define CONFIGURE_MEMORY_FOR_TASK_VARIABLES(_task_variables) 0
|
||||
#else
|
||||
#ifndef CONFIGURE_MAXIMUM_TASK_VARIABLES
|
||||
/** This macro specifies the maximum number of task variables. */
|
||||
#define CONFIGURE_MAXIMUM_TASK_VARIABLES 0
|
||||
/**
|
||||
* This macro is calculated to specify the memory required for task
|
||||
* variables.
|
||||
*
|
||||
* This is an internal parameter.
|
||||
*/
|
||||
#define CONFIGURE_MEMORY_FOR_TASK_VARIABLES(_task_variables) 0
|
||||
#else
|
||||
#warning "Per-Task Variables are deprecated and will be removed."
|
||||
#define CONFIGURE_MEMORY_FOR_TASK_VARIABLES(_task_variables) \
|
||||
(_task_variables) * \
|
||||
_Configure_From_workspace(sizeof(rtems_task_variable_t))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIGURE_MAXIMUM_TIMERS
|
||||
/** This specifies the maximum number of Classic API timers. */
|
||||
#define CONFIGURE_MAXIMUM_TIMERS 0
|
||||
@@ -2818,9 +2782,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
|
||||
#define CONFIGURE_MAXIMUM_GOROUTINES 400
|
||||
#endif
|
||||
|
||||
#define CONFIGURE_GOROUTINES_TASK_VARIABLES \
|
||||
(2 * CONFIGURE_MAXIMUM_GOROUTINES)
|
||||
|
||||
#ifndef CONFIGURE_MAXIMUM_GO_CHANNELS
|
||||
#define CONFIGURE_MAXIMUM_GO_CHANNELS 500
|
||||
#endif
|
||||
@@ -2845,9 +2806,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
|
||||
/** This specifies the maximum number of Go co-routines. */
|
||||
#define CONFIGURE_MAXIMUM_GOROUTINES 0
|
||||
|
||||
/** This specifies the maximum number of Go per-task variables required. */
|
||||
#define CONFIGURE_GOROUTINES_TASK_VARIABLES 0
|
||||
|
||||
/** This specifies the maximum number of Go channels required. */
|
||||
#define CONFIGURE_MAXIMUM_GO_CHANNELS 0
|
||||
#endif
|
||||
@@ -3068,9 +3026,7 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
|
||||
* Classic API as configured.
|
||||
*/
|
||||
#define CONFIGURE_MEMORY_FOR_CLASSIC \
|
||||
(CONFIGURE_MEMORY_FOR_TASK_VARIABLES(CONFIGURE_MAXIMUM_TASK_VARIABLES + \
|
||||
CONFIGURE_GOROUTINES_TASK_VARIABLES) + \
|
||||
CONFIGURE_MEMORY_FOR_TIMERS(CONFIGURE_MAXIMUM_TIMERS + \
|
||||
(CONFIGURE_MEMORY_FOR_TIMERS(CONFIGURE_MAXIMUM_TIMERS + \
|
||||
CONFIGURE_TIMER_FOR_SHARED_MEMORY_DRIVER ) + \
|
||||
CONFIGURE_MEMORY_FOR_SEMAPHORES(CONFIGURE_SEMAPHORES) + \
|
||||
CONFIGURE_MEMORY_FOR_MESSAGE_QUEUES(CONFIGURE_MAXIMUM_MESSAGE_QUEUES) + \
|
||||
@@ -3581,7 +3537,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
|
||||
|
||||
/* Classic API Pieces */
|
||||
uint32_t CLASSIC_TASKS;
|
||||
uint32_t TASK_VARIABLES;
|
||||
uint32_t TIMERS;
|
||||
uint32_t SEMAPHORES;
|
||||
uint32_t MESSAGE_QUEUES;
|
||||
@@ -3635,8 +3590,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
|
||||
|
||||
/* Classic API Pieces */
|
||||
CONFIGURE_MEMORY_FOR_TASKS(CONFIGURE_MAXIMUM_TASKS, 0),
|
||||
CONFIGURE_MEMORY_FOR_TASK_VARIABLES(CONFIGURE_MAXIMUM_TASK_VARIABLES +
|
||||
CONFIGURE_GOROUTINES_TASK_VARIABLES),
|
||||
CONFIGURE_MEMORY_FOR_TIMERS(CONFIGURE_MAXIMUM_TIMERS),
|
||||
CONFIGURE_MEMORY_FOR_SEMAPHORES(CONFIGURE_SEMAPHORES),
|
||||
CONFIGURE_MEMORY_FOR_MESSAGE_QUEUES(CONFIGURE_MAXIMUM_MESSAGE_QUEUES),
|
||||
|
||||
@@ -173,35 +173,6 @@ typedef enum {
|
||||
*/
|
||||
typedef void (*Thread_CPU_budget_algorithm_callout )( Thread_Control * );
|
||||
|
||||
#if !defined(RTEMS_SMP)
|
||||
/**
|
||||
* @brief Forward reference to the per task variable structure..
|
||||
*
|
||||
* Forward reference to the per task variable structure.
|
||||
*/
|
||||
struct rtems_task_variable_tt;
|
||||
|
||||
/**
|
||||
* @brief Internal structure used to manager per task variables.
|
||||
*
|
||||
* This is the internal structure used to manager per Task Variables.
|
||||
*/
|
||||
typedef struct {
|
||||
/** This field points to the next per task variable for this task. */
|
||||
struct rtems_task_variable_tt *next;
|
||||
/** This field points to the physical memory location of this per
|
||||
* task variable.
|
||||
*/
|
||||
void **ptr;
|
||||
/** This field is to the global value for this per task variable. */
|
||||
void *gval;
|
||||
/** This field is to this thread's value for this per task variable. */
|
||||
void *tval;
|
||||
/** This field points to the destructor for this per task variable. */
|
||||
void (*dtor)(void *);
|
||||
} rtems_task_variable_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The following structure contains the information which defines
|
||||
* the starting state of a thread.
|
||||
@@ -870,11 +841,6 @@ struct _Thread_Control {
|
||||
/** This array contains the API extension area pointers. */
|
||||
void *API_Extensions[ THREAD_API_LAST + 1 ];
|
||||
|
||||
#if !defined(RTEMS_SMP)
|
||||
/** This field points to the set of per task variables. */
|
||||
rtems_task_variable_t *task_variables;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The POSIX Keys information.
|
||||
*/
|
||||
|
||||
@@ -57,9 +57,6 @@ const char rtems_test_name[] = "PSXCONFIG 1";
|
||||
#define CONFIGURE_MAXIMUM_REGIONS 43
|
||||
#define CONFIGURE_MAXIMUM_SEMAPHORES 47
|
||||
#define CONFIGURE_MAXIMUM_TASKS 11
|
||||
#if !defined(RTEMS_SMP)
|
||||
#define CONFIGURE_MAXIMUM_TASK_VARIABLES 13
|
||||
#endif
|
||||
#define CONFIGURE_MAXIMUM_TIMERS 59
|
||||
#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 17
|
||||
|
||||
@@ -202,10 +199,6 @@ typedef struct {
|
||||
|
||||
static char posix_name [_POSIX_PATH_MAX + 1];
|
||||
|
||||
#if !defined(RTEMS_SMP)
|
||||
static void *task_var;
|
||||
#endif
|
||||
|
||||
static char *get_posix_name(char a, char b, char c, int i)
|
||||
{
|
||||
posix_name [_POSIX_PATH_MAX - 4] = a;
|
||||
@@ -216,13 +209,6 @@ static char *get_posix_name(char a, char b, char c, int i)
|
||||
return posix_name;
|
||||
}
|
||||
|
||||
#if !defined(RTEMS_SMP)
|
||||
static void task_var_dtor(void *var RTEMS_UNUSED)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *posix_thread(void *arg RTEMS_UNUSED)
|
||||
{
|
||||
rtems_test_assert(0);
|
||||
@@ -435,21 +421,6 @@ static rtems_task Init(rtems_task_argument argument)
|
||||
);
|
||||
#endif
|
||||
|
||||
#if !defined(RTEMS_SMP)
|
||||
#ifdef CONFIGURE_MAXIMUM_TASK_VARIABLES
|
||||
/*
|
||||
* We know this is deprecated and don't want a warning on every BSP built.
|
||||
*/
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
for (i = 0; i < CONFIGURE_MAXIMUM_TASK_VARIABLES; ++i) {
|
||||
sc = rtems_task_variable_add(RTEMS_SELF, &task_var, task_var_dtor);
|
||||
directive_failed(sc, "rtems_task_variable_add");
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIGURE_MAXIMUM_TIMERS
|
||||
for (i = 0; i < CONFIGURE_MAXIMUM_TIMERS; ++i) {
|
||||
sc = rtems_timer_create(name, &id);
|
||||
|
||||
@@ -107,7 +107,6 @@ sp25/Makefile
|
||||
sp26/Makefile
|
||||
sp27/Makefile
|
||||
sp27a/Makefile
|
||||
sp28/Makefile
|
||||
sp29/Makefile
|
||||
sp30/Makefile
|
||||
sp31/Makefile
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
rtems_tests_PROGRAMS = sp28
|
||||
sp28_SOURCES = init.c
|
||||
|
||||
dist_rtems_tests_DATA = sp28.scn
|
||||
dist_rtems_tests_DATA += sp28.doc
|
||||
|
||||
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
||||
include $(top_srcdir)/../automake/compile.am
|
||||
include $(top_srcdir)/../automake/leaf.am
|
||||
|
||||
|
||||
AM_CPPFLAGS += -I$(top_srcdir)/../support/include
|
||||
|
||||
LINK_OBJS = $(sp28_OBJECTS)
|
||||
LINK_LIBS = $(sp28_LDLIBS)
|
||||
|
||||
sp28$(EXEEXT): $(sp28_OBJECTS) $(sp28_DEPENDENCIES)
|
||||
@rm -f sp28$(EXEEXT)
|
||||
$(make-exe)
|
||||
|
||||
include $(top_srcdir)/../automake/local.am
|
||||
@@ -1,439 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2012.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <tmacros.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <rtems/error.h>
|
||||
#include <stdio.h>
|
||||
|
||||
const char rtems_test_name[] = "SP 28";
|
||||
|
||||
/* forward declarations to avoid warnings */
|
||||
rtems_task Init(rtems_task_argument argument);
|
||||
rtems_task subtask(rtems_task_argument arg);
|
||||
rtems_task Task_variable_deleter(rtems_task_argument ignored);
|
||||
void starttask(int arg);
|
||||
void test_errors(void);
|
||||
void test_dtor(void *pointer);
|
||||
void test_multiple_taskvars(void);
|
||||
void test_out_of_memory(void);
|
||||
rtems_task Other_Task(rtems_task_argument ignored);
|
||||
void test_delete_from_other_task(void);
|
||||
void test_delete_as_side_effect(void);
|
||||
|
||||
volatile void *taskvar;
|
||||
volatile int nRunning;
|
||||
volatile int nDeleted;
|
||||
|
||||
rtems_task
|
||||
subtask (rtems_task_argument arg)
|
||||
{
|
||||
uintptr_t localvar = arg;
|
||||
int i;
|
||||
rtems_status_code sc;
|
||||
|
||||
nRunning++;
|
||||
while (nRunning != 3)
|
||||
rtems_task_wake_after (0);
|
||||
|
||||
sc = rtems_task_variable_add(RTEMS_SELF, (void **)&taskvar, NULL);
|
||||
directive_failed( sc, "task variable add" );
|
||||
|
||||
taskvar = (void *)localvar;
|
||||
while (localvar < 1000) {
|
||||
localvar++;
|
||||
rtems_task_wake_after (0);
|
||||
taskvar = (void *)((uintptr_t)taskvar + 1);
|
||||
rtems_task_wake_after (0);
|
||||
if ((uintptr_t)taskvar != localvar) {
|
||||
printf(
|
||||
"Task:%" PRIdrtems_task_argument " taskvar:%" PRIuPTR
|
||||
" localvar:%" PRIuPTR "\n",
|
||||
arg,
|
||||
(uintptr_t)taskvar,
|
||||
localvar
|
||||
);
|
||||
rtems_task_suspend (RTEMS_SELF);
|
||||
}
|
||||
}
|
||||
sc = rtems_task_variable_delete(RTEMS_SELF, (void **)&taskvar);
|
||||
nDeleted++;
|
||||
directive_failed( sc, "task variable delete" );
|
||||
|
||||
if ((uintptr_t)taskvar == localvar) {
|
||||
printf(
|
||||
"Task:%" PRIdrtems_task_argument " deleted taskvar:%" PRIuPTR
|
||||
" localvar:%" PRIuPTR "\n",
|
||||
arg,
|
||||
(uintptr_t)taskvar,
|
||||
localvar
|
||||
);
|
||||
nRunning--;
|
||||
rtems_task_suspend (RTEMS_SELF);
|
||||
}
|
||||
while (nDeleted != 3)
|
||||
rtems_task_wake_after (0);
|
||||
for (i = 0 ; i < 1000 ; i++) {
|
||||
taskvar = (void *)(localvar = 100 * arg);
|
||||
rtems_task_wake_after(0);
|
||||
if (nRunning <= 1)
|
||||
break;
|
||||
if ((uintptr_t)taskvar == localvar) {
|
||||
printf(
|
||||
"Task:%" PRIdrtems_task_argument " taskvar:%" PRIuPTR
|
||||
" localvar:%" PRIuPTR "\n",
|
||||
arg,
|
||||
(uintptr_t)taskvar,
|
||||
localvar
|
||||
);
|
||||
nRunning--;
|
||||
rtems_task_suspend(RTEMS_SELF);
|
||||
}
|
||||
}
|
||||
nRunning--;
|
||||
while (nRunning)
|
||||
rtems_task_wake_after(0);
|
||||
|
||||
TEST_END();
|
||||
rtems_test_exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
starttask (int arg)
|
||||
{
|
||||
rtems_id tid;
|
||||
rtems_status_code sc;
|
||||
|
||||
sc = rtems_task_create(rtems_build_name ('S', 'R', 'V', arg + 'A'),
|
||||
RTEMS_MAXIMUM_PRIORITY - 1u,
|
||||
RTEMS_MINIMUM_STACK_SIZE,
|
||||
RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
|
||||
RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL,
|
||||
&tid
|
||||
);
|
||||
directive_failed( sc, "task create" );
|
||||
|
||||
sc = rtems_task_start(tid, subtask, arg);
|
||||
directive_failed( sc, "task start" );
|
||||
}
|
||||
|
||||
volatile void *taskvar1;
|
||||
volatile void *taskvar2;
|
||||
volatile void *taskvar3;
|
||||
|
||||
void test_errors(void)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
void *value;
|
||||
|
||||
/*
|
||||
* task variable add error status codes
|
||||
*/
|
||||
puts( "task variable add - NULL pointer - RTEMS_INVALID_ADDRESS" );
|
||||
sc = rtems_task_variable_add(RTEMS_SELF, NULL, NULL );
|
||||
fatal_directive_status( sc, RTEMS_INVALID_ADDRESS, "add NULL pointer" );
|
||||
|
||||
/*
|
||||
* task variable get error status codes
|
||||
*/
|
||||
puts( "task variable get - bad Id - RTEMS_INVALID_ID" );
|
||||
sc = rtems_task_variable_get(
|
||||
rtems_task_self() + 10,
|
||||
(void **)&taskvar1,
|
||||
&value
|
||||
);
|
||||
fatal_directive_status( sc, RTEMS_INVALID_ID, "bad Id" );
|
||||
|
||||
puts( "task variable get - NULL pointer - RTEMS_INVALID_ADDRESS" );
|
||||
sc = rtems_task_variable_get(RTEMS_SELF, NULL, &value );
|
||||
fatal_directive_status( sc, RTEMS_INVALID_ADDRESS, "get NULL pointer" );
|
||||
|
||||
puts( "task variable get - bad result - RTEMS_INVALID_ADDRESS" );
|
||||
sc = rtems_task_variable_get(RTEMS_SELF, (void **)&taskvar1, NULL);
|
||||
fatal_directive_status( sc, RTEMS_INVALID_ADDRESS, "get bad result" );
|
||||
|
||||
puts( "task variable get - bad pointer - RTEMS_INVALID_ADDRESS" );
|
||||
sc = rtems_task_variable_get(RTEMS_SELF, (void **)&taskvar1, &value);
|
||||
fatal_directive_status( sc, RTEMS_INVALID_ADDRESS, "get bad pointer" );
|
||||
|
||||
/*
|
||||
* task variable delete error status codes
|
||||
*/
|
||||
puts( "task variable delete - bad Id - RTEMS_INVALID_ID" );
|
||||
sc = rtems_task_variable_delete( rtems_task_self() + 10, (void **)&taskvar1 );
|
||||
fatal_directive_status( sc, RTEMS_INVALID_ID, "bad Id" );
|
||||
|
||||
puts( "task variable delete - NULL pointer - RTEMS_INVALID_ADDRESS" );
|
||||
sc = rtems_task_variable_delete(RTEMS_SELF, NULL);
|
||||
fatal_directive_status( sc, RTEMS_INVALID_ADDRESS, "delete NULL pointer" );
|
||||
|
||||
puts( "task variable delete - bad pointer - RTEMS_INVALID_ADDRESS" );
|
||||
sc = rtems_task_variable_delete(RTEMS_SELF, (void **)&taskvar1);
|
||||
fatal_directive_status( sc, RTEMS_INVALID_ADDRESS, "delete bad pointer" );
|
||||
|
||||
}
|
||||
|
||||
volatile uint32_t test_dtor_ran;
|
||||
|
||||
void test_dtor(void *pointer)
|
||||
{
|
||||
test_dtor_ran++;
|
||||
}
|
||||
|
||||
|
||||
void test_multiple_taskvars(void)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
void *value;
|
||||
|
||||
test_dtor_ran = 0;
|
||||
|
||||
/*
|
||||
* Add multiple task variables and add each twice to
|
||||
* verify that behavior is OK
|
||||
*/
|
||||
puts( "task variable add - bad Id - RTEMS_INVALID_ID" );
|
||||
sc = rtems_task_variable_add(
|
||||
rtems_task_self() + 10,
|
||||
(void **)&taskvar1,
|
||||
NULL
|
||||
);
|
||||
fatal_directive_status( sc, RTEMS_INVALID_ID, "bad Id" );
|
||||
|
||||
puts( "Adding multiple task variables" );
|
||||
sc = rtems_task_variable_add(RTEMS_SELF, (void **)&taskvar1, NULL);
|
||||
directive_failed( sc, "add multiple #1" );
|
||||
|
||||
sc = rtems_task_variable_add(RTEMS_SELF, (void **)&taskvar1, test_dtor);
|
||||
directive_failed( sc, "add multiple #2" );
|
||||
|
||||
sc = rtems_task_variable_add(RTEMS_SELF, (void **)&taskvar2, test_dtor);
|
||||
directive_failed( sc, "add multiple #3" );
|
||||
|
||||
sc = rtems_task_variable_add(RTEMS_SELF, (void **)&taskvar2, NULL);
|
||||
directive_failed( sc, "add multiple #4" );
|
||||
|
||||
sc = rtems_task_variable_add(RTEMS_SELF, (void **)&taskvar3, NULL);
|
||||
directive_failed( sc, "add multiple #5" );
|
||||
|
||||
sc = rtems_task_variable_add(RTEMS_SELF, (void **)&taskvar3, test_dtor);
|
||||
directive_failed( sc, "add multiple #6" );
|
||||
|
||||
/*
|
||||
* Obtain task variables in various spots on the chain
|
||||
*/
|
||||
puts( "Obtaining multiple task variables" );
|
||||
sc = rtems_task_variable_get( RTEMS_SELF, (void **)&taskvar3, &value );
|
||||
directive_failed( sc, "get multiple #1" );
|
||||
sc = rtems_task_variable_get( RTEMS_SELF, (void **)&taskvar2, &value );
|
||||
directive_failed( sc, "get multiple #2" );
|
||||
sc = rtems_task_variable_get( RTEMS_SELF, (void **)&taskvar1, &value );
|
||||
directive_failed( sc, "get multiple #2" );
|
||||
|
||||
/*
|
||||
* Delete task variables in various spots on the chain
|
||||
*/
|
||||
|
||||
/* to trip the destructors */
|
||||
taskvar1 = (void *)1;
|
||||
taskvar2 = (void *)2;
|
||||
taskvar3 = (void *)3;
|
||||
|
||||
puts( "Deleting multiple task variables" );
|
||||
sc = rtems_task_variable_delete(RTEMS_SELF, (void **)&taskvar2);
|
||||
directive_failed( sc, "delete multiple #1" );
|
||||
sc = rtems_task_variable_delete(RTEMS_SELF, (void **)&taskvar3);
|
||||
directive_failed( sc, "delete multiple #2" );
|
||||
sc = rtems_task_variable_delete(RTEMS_SELF, (void **)&taskvar1);
|
||||
directive_failed( sc, "delete multiple #3" );
|
||||
|
||||
if ( test_dtor_ran != 2 ) {
|
||||
printf(
|
||||
"Test dtor ran %" PRIu32 " times not 2 times as expected\n",
|
||||
test_dtor_ran
|
||||
);
|
||||
rtems_test_exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_VARS 4096
|
||||
|
||||
void *Pointers[MAX_VARS];
|
||||
|
||||
void test_out_of_memory(void)
|
||||
{
|
||||
int i;
|
||||
int max;
|
||||
rtems_status_code sc;
|
||||
int ran_out = 0;
|
||||
void **base;
|
||||
|
||||
base = Pointers;
|
||||
|
||||
for (i=0 ; i<MAX_VARS ; i++ ) {
|
||||
sc = rtems_task_variable_add(RTEMS_SELF, &base[i], NULL);
|
||||
if ( sc == RTEMS_NO_MEMORY ) {
|
||||
puts( "task_variable_add - returns NO_MEMORY" );
|
||||
max = i;
|
||||
ran_out = 1;
|
||||
break;
|
||||
}
|
||||
directive_failed( sc, "add loop until out of memory" );
|
||||
}
|
||||
|
||||
if ( !ran_out ) {
|
||||
puts( "ERROR!!! did not run out of memory adding task variables!" );
|
||||
rtems_test_exit(0);
|
||||
}
|
||||
|
||||
for (i=0 ; i<max ; i++ ) {
|
||||
sc = rtems_task_variable_delete(RTEMS_SELF, &base[i]);
|
||||
directive_failed( sc, "delete loop until out of memory" );
|
||||
}
|
||||
}
|
||||
|
||||
rtems_id main_task;
|
||||
rtems_id other_task;
|
||||
|
||||
rtems_task Other_Task(rtems_task_argument ignored)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
|
||||
puts( "Deleting task variables in another task" );
|
||||
sc = rtems_task_variable_delete(main_task, (void **)&taskvar1);
|
||||
directive_failed( sc, "delete loop for other task" );
|
||||
|
||||
(void) rtems_task_delete( RTEMS_SELF );
|
||||
}
|
||||
|
||||
void test_delete_from_other_task(void)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
|
||||
test_dtor_ran = 0;
|
||||
|
||||
sc = rtems_task_ident( RTEMS_SELF, 0, &main_task );
|
||||
directive_failed( sc, "task ident" );
|
||||
|
||||
sc = rtems_task_variable_add(RTEMS_SELF, (void **)&taskvar1, test_dtor);
|
||||
directive_failed( sc, "add for other task case" );
|
||||
|
||||
sc = rtems_task_create(rtems_build_name ('O', 'T', 'H', 'R'),
|
||||
RTEMS_MAXIMUM_PRIORITY - 1u,
|
||||
RTEMS_MINIMUM_STACK_SIZE,
|
||||
RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
|
||||
RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL,
|
||||
&other_task
|
||||
);
|
||||
directive_failed( sc, "task create other" );
|
||||
|
||||
sc = rtems_task_start(other_task, Other_Task, 0);
|
||||
directive_failed( sc, "task start other" );
|
||||
|
||||
rtems_task_wake_after( 100 );
|
||||
|
||||
if ( test_dtor_ran != 1 ) {
|
||||
printf(
|
||||
"Test dtor ran %" PRIu32 " times not 1 times as expected\n",
|
||||
test_dtor_ran
|
||||
);
|
||||
rtems_test_exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Task which adds task variables just to delete them
|
||||
*/
|
||||
rtems_task Task_variable_deleter(rtems_task_argument ignored)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
|
||||
puts( "Adding multiple task variables to delete implicitly" );
|
||||
sc = rtems_task_variable_add(RTEMS_SELF, (void **)&taskvar1, test_dtor);
|
||||
directive_failed( sc, "add multiple for delete #1" );
|
||||
|
||||
sc = rtems_task_variable_add(RTEMS_SELF, (void **)&taskvar2, NULL);
|
||||
directive_failed( sc, "add multiple for delete #2" );
|
||||
|
||||
sc = rtems_task_variable_add(RTEMS_SELF, (void **)&taskvar3, test_dtor);
|
||||
directive_failed( sc, "add multiple for delete #3" );
|
||||
|
||||
(void) rtems_task_delete( RTEMS_SELF );
|
||||
}
|
||||
|
||||
void test_delete_as_side_effect(void)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
rtems_id deleter_task;
|
||||
|
||||
test_dtor_ran = 0;
|
||||
|
||||
sc = rtems_task_create(rtems_build_name ('O', 'T', 'H', 'R'),
|
||||
RTEMS_MAXIMUM_PRIORITY - 1u,
|
||||
RTEMS_MINIMUM_STACK_SIZE,
|
||||
RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
|
||||
RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL,
|
||||
&deleter_task
|
||||
);
|
||||
directive_failed( sc, "task create deleter" );
|
||||
|
||||
sc = rtems_task_start(deleter_task, Task_variable_deleter, 0);
|
||||
directive_failed( sc, "task start deleter" );
|
||||
|
||||
rtems_task_wake_after( 100 );
|
||||
|
||||
if ( test_dtor_ran != 2 ) {
|
||||
printf(
|
||||
"Test dtor ran %" PRIu32 " times not 2 times as expected\n",
|
||||
test_dtor_ran
|
||||
);
|
||||
rtems_test_exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
rtems_task Init (rtems_task_argument ignored)
|
||||
{
|
||||
TEST_BEGIN();
|
||||
|
||||
test_errors();
|
||||
|
||||
test_multiple_taskvars();
|
||||
|
||||
test_delete_as_side_effect();
|
||||
|
||||
test_delete_from_other_task();
|
||||
|
||||
starttask (1);
|
||||
starttask (2);
|
||||
starttask (3);
|
||||
|
||||
test_out_of_memory();
|
||||
|
||||
rtems_task_suspend (RTEMS_SELF);
|
||||
}
|
||||
|
||||
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
|
||||
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
|
||||
#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 2
|
||||
|
||||
#define CONFIGURE_MAXIMUM_TASKS 4
|
||||
#define CONFIGURE_MAXIMUM_TASK_VARIABLES (4)
|
||||
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||
|
||||
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
||||
#define CONFIGURE_MICROSECONDS_PER_TICK 10000
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
#include <rtems/confdefs.h>
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
*** START OF TEST 28 ***
|
||||
task variable add - NULL pointer - RTEMS_INVALID_ADDRESS
|
||||
task variable get - bad Id - RTEMS_INVALID_ID
|
||||
task variable get - NULL pointer - RTEMS_INVALID_ADDRESS
|
||||
task variable get - bad result - RTEMS_INVALID_ADDRESS
|
||||
task variable get - bad pointer - RTEMS_INVALID_ADDRESS
|
||||
task variable delete - bad Id - RTEMS_INVALID_ID
|
||||
task variable delete - NULL pointer - RTEMS_INVALID_ADDRESS
|
||||
task variable delete - bad pointer - RTEMS_INVALID_ADDRESS
|
||||
task variable add - bad Id - RTEMS_INVALID_ID
|
||||
Adding multiple task variables
|
||||
Obtaining multiple task variables
|
||||
Deleting multiple task variables
|
||||
Adding multiple task variables to delete implicitly
|
||||
Deleting task variables in another task
|
||||
task_variable_add - returns NO_MEMORY
|
||||
*** END OF TEST 28 ***
|
||||
Reference in New Issue
Block a user