From c941a980ccbd8def1d925fc5c69a22f40e1e5060 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 21 Jan 2000 15:07:55 +0000 Subject: Patch from Eric Norum to implement this: I'd like to propose a change to RTEMS task variables that I think would make them more useful. I think that it is early enough in their existence to still make changes to their API. 1) Change type from `int' to `void *'. 2) Add extra argument to task_variable_add -- if non-NULL, a pointer to a `destructor' function to be called when the task exits. This function would be called with that task's value of the task variable as its argument. In many cases, the `dtor' function could be `free'. rtems_status_code rtems_task_variable_add ( rtems_id tid, void **ptr, void (*dtor)(void *)); rtems_status_code rtems_task_variable_delete (rtems_id tid, void **ptr); This would be all we'd need to cleanly and efficiently support C++ per-thread exception information without dragging in all that POSIX API stuff. --- c/src/exec/rtems/include/rtems/rtems/tasks.h | 5 +++-- c/src/exec/rtems/src/tasks.c | 2 ++ c/src/exec/rtems/src/taskvariableadd.c | 6 ++++-- c/src/exec/rtems/src/taskvariabledelete.c | 2 +- c/src/exec/score/include/rtems/score/thread.h | 5 +++-- c/src/tests/sptests/sp28/init.c | 26 ++++++++++++-------------- cpukit/rtems/include/rtems/rtems/tasks.h | 5 +++-- cpukit/rtems/src/tasks.c | 2 ++ cpukit/rtems/src/taskvariableadd.c | 6 ++++-- cpukit/rtems/src/taskvariabledelete.c | 2 +- cpukit/score/include/rtems/score/thread.h | 5 +++-- testsuites/sptests/sp28/init.c | 26 ++++++++++++-------------- 12 files changed, 50 insertions(+), 42 deletions(-) diff --git a/c/src/exec/rtems/include/rtems/rtems/tasks.h b/c/src/exec/rtems/include/rtems/rtems/tasks.h index fa574bba8a..f9234e6e89 100644 --- a/c/src/exec/rtems/include/rtems/rtems/tasks.h +++ b/c/src/exec/rtems/include/rtems/rtems/tasks.h @@ -412,7 +412,8 @@ rtems_status_code rtems_task_is_suspended( rtems_status_code rtems_task_variable_add( rtems_id tid, - int *ptr + void **ptr, + void (*dtor)(void *) ); /* @@ -423,7 +424,7 @@ rtems_status_code rtems_task_variable_add( rtems_status_code rtems_task_variable_delete( rtems_id tid, - int *ptr + void **ptr ); /* diff --git a/c/src/exec/rtems/src/tasks.c b/c/src/exec/rtems/src/tasks.c index bbd9ff0dd8..5fdff2db18 100644 --- a/c/src/exec/rtems/src/tasks.c +++ b/c/src/exec/rtems/src/tasks.c @@ -103,6 +103,8 @@ User_extensions_routine _RTEMS_tasks_Delete_extension( deleted->task_variables = NULL; while (tvp) { next = tvp->next; + if (tvp->dtor) + (*tvp->dtor)( tvp->ptr ); _Workspace_Free( tvp ); tvp = next; } diff --git a/c/src/exec/rtems/src/taskvariableadd.c b/c/src/exec/rtems/src/taskvariableadd.c index 4ba8b7b21b..0f1ae0895e 100644 --- a/c/src/exec/rtems/src/taskvariableadd.c +++ b/c/src/exec/rtems/src/taskvariableadd.c @@ -24,7 +24,8 @@ rtems_status_code rtems_task_variable_add( rtems_id tid, - int *ptr + void **ptr, + void (*dtor)(void *) ) { Thread_Control *the_thread; @@ -54,6 +55,7 @@ rtems_status_code rtems_task_variable_add( tvp = the_thread->task_variables; while (tvp) { if (tvp->ptr == ptr) { + tvp->dtor = dtor; _Thread_Enable_dispatch(); return RTEMS_SUCCESSFUL; } @@ -72,6 +74,7 @@ rtems_status_code rtems_task_variable_add( } new->var = 0; new->ptr = ptr; + new->dtor = dtor; new->next = the_thread->task_variables; the_thread->task_variables = new; @@ -80,4 +83,3 @@ rtems_status_code rtems_task_variable_add( } return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ } - diff --git a/c/src/exec/rtems/src/taskvariabledelete.c b/c/src/exec/rtems/src/taskvariabledelete.c index eddaf1903d..c760f9ba39 100644 --- a/c/src/exec/rtems/src/taskvariabledelete.c +++ b/c/src/exec/rtems/src/taskvariabledelete.c @@ -24,7 +24,7 @@ rtems_status_code rtems_task_variable_delete( rtems_id tid, - int *ptr + void **ptr ) { Thread_Control *the_thread; diff --git a/c/src/exec/score/include/rtems/score/thread.h b/c/src/exec/score/include/rtems/score/thread.h index 0e2802bbac..ec48864a9f 100644 --- a/c/src/exec/score/include/rtems/score/thread.h +++ b/c/src/exec/score/include/rtems/score/thread.h @@ -93,8 +93,9 @@ struct rtems_task_variable_tt; struct rtems_task_variable_tt { struct rtems_task_variable_tt *next; - int *ptr; - int var; + void **ptr; + void *var; + void (*dtor)(void *); }; typedef struct rtems_task_variable_tt rtems_task_variable_t; diff --git a/c/src/tests/sptests/sp28/init.c b/c/src/tests/sptests/sp28/init.c index d058f79ef6..f6f7d70218 100644 --- a/c/src/tests/sptests/sp28/init.c +++ b/c/src/tests/sptests/sp28/init.c @@ -22,7 +22,7 @@ rtems_task Init(rtems_task_argument argument); #include #include -volatile int taskvar; +volatile void *taskvar; rtems_task subtask (rtems_task_argument arg) @@ -31,37 +31,36 @@ subtask (rtems_task_argument arg) int i; rtems_status_code sc; - sc = rtems_task_variable_add (RTEMS_SELF, (void *) &taskvar); + sc = rtems_task_variable_add (RTEMS_SELF, &taskvar, NULL); if (sc != RTEMS_SUCCESSFUL) { printf ("Can't add task variable: %s\n", rtems_status_text (sc)); rtems_task_suspend (RTEMS_SELF); } - taskvar = localvar; + taskvar = (void *)localvar; while (localvar < 1000) { localvar++; rtems_task_wake_after (0); - taskvar++; + taskvar = (void *)((int)taskvar + 1); rtems_task_wake_after (0); - if (taskvar != localvar) { - printf ("Task:%d taskvar:%d localvar:%d\n", arg, taskvar, localvar); + if ((int)taskvar != localvar) { + printf ("Task:%d taskvar:%d localvar:%d\n", arg, (int)taskvar, localvar); rtems_task_suspend (RTEMS_SELF); } } - sc = rtems_task_variable_delete (RTEMS_SELF, (void *) &taskvar); + sc = rtems_task_variable_delete (RTEMS_SELF, &taskvar); if (sc != RTEMS_SUCCESSFUL) { printf ("Can't delete task variable: %s\n", rtems_status_text (sc)); rtems_task_suspend (RTEMS_SELF); } for (i = 0 ; ; i++) { - taskvar = localvar = 100 * arg; + taskvar = (void *)(localvar = 100 * arg); rtems_task_wake_after (0); - if (taskvar == localvar) { - printf ("Task:%d taskvar:%d localvar:%d\n", arg, taskvar, localvar); + if ((int)taskvar == localvar) { + printf ("Task:%d taskvar:%d localvar:%d\n", arg, (int)taskvar, localvar); rtems_task_suspend (RTEMS_SELF); } if ((arg == 3) && (i == 100)) { - puts ("Task variables test succeeded."); - puts ("*** END OF TEST SP28 ***"); + printf ("Task variables test succeeded.\n"); exit (0); } } @@ -75,7 +74,7 @@ starttask (int arg) sc = rtems_task_create (rtems_build_name ('S', 'R', 'V', arg + 'A'), 100, - RTEMS_MINIMUM_STACK_SIZE * 3, + 10000, RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0), RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL, &tid); @@ -93,7 +92,6 @@ starttask (int arg) rtems_task Init (rtems_task_argument ignored) { - puts ("*** START OF TEST SP28 ***"); starttask (1); starttask (2); starttask (3); diff --git a/cpukit/rtems/include/rtems/rtems/tasks.h b/cpukit/rtems/include/rtems/rtems/tasks.h index fa574bba8a..f9234e6e89 100644 --- a/cpukit/rtems/include/rtems/rtems/tasks.h +++ b/cpukit/rtems/include/rtems/rtems/tasks.h @@ -412,7 +412,8 @@ rtems_status_code rtems_task_is_suspended( rtems_status_code rtems_task_variable_add( rtems_id tid, - int *ptr + void **ptr, + void (*dtor)(void *) ); /* @@ -423,7 +424,7 @@ rtems_status_code rtems_task_variable_add( rtems_status_code rtems_task_variable_delete( rtems_id tid, - int *ptr + void **ptr ); /* diff --git a/cpukit/rtems/src/tasks.c b/cpukit/rtems/src/tasks.c index bbd9ff0dd8..5fdff2db18 100644 --- a/cpukit/rtems/src/tasks.c +++ b/cpukit/rtems/src/tasks.c @@ -103,6 +103,8 @@ User_extensions_routine _RTEMS_tasks_Delete_extension( deleted->task_variables = NULL; while (tvp) { next = tvp->next; + if (tvp->dtor) + (*tvp->dtor)( tvp->ptr ); _Workspace_Free( tvp ); tvp = next; } diff --git a/cpukit/rtems/src/taskvariableadd.c b/cpukit/rtems/src/taskvariableadd.c index 4ba8b7b21b..0f1ae0895e 100644 --- a/cpukit/rtems/src/taskvariableadd.c +++ b/cpukit/rtems/src/taskvariableadd.c @@ -24,7 +24,8 @@ rtems_status_code rtems_task_variable_add( rtems_id tid, - int *ptr + void **ptr, + void (*dtor)(void *) ) { Thread_Control *the_thread; @@ -54,6 +55,7 @@ rtems_status_code rtems_task_variable_add( tvp = the_thread->task_variables; while (tvp) { if (tvp->ptr == ptr) { + tvp->dtor = dtor; _Thread_Enable_dispatch(); return RTEMS_SUCCESSFUL; } @@ -72,6 +74,7 @@ rtems_status_code rtems_task_variable_add( } new->var = 0; new->ptr = ptr; + new->dtor = dtor; new->next = the_thread->task_variables; the_thread->task_variables = new; @@ -80,4 +83,3 @@ rtems_status_code rtems_task_variable_add( } return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ } - diff --git a/cpukit/rtems/src/taskvariabledelete.c b/cpukit/rtems/src/taskvariabledelete.c index eddaf1903d..c760f9ba39 100644 --- a/cpukit/rtems/src/taskvariabledelete.c +++ b/cpukit/rtems/src/taskvariabledelete.c @@ -24,7 +24,7 @@ rtems_status_code rtems_task_variable_delete( rtems_id tid, - int *ptr + void **ptr ) { Thread_Control *the_thread; diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h index 0e2802bbac..ec48864a9f 100644 --- a/cpukit/score/include/rtems/score/thread.h +++ b/cpukit/score/include/rtems/score/thread.h @@ -93,8 +93,9 @@ struct rtems_task_variable_tt; struct rtems_task_variable_tt { struct rtems_task_variable_tt *next; - int *ptr; - int var; + void **ptr; + void *var; + void (*dtor)(void *); }; typedef struct rtems_task_variable_tt rtems_task_variable_t; diff --git a/testsuites/sptests/sp28/init.c b/testsuites/sptests/sp28/init.c index d058f79ef6..f6f7d70218 100644 --- a/testsuites/sptests/sp28/init.c +++ b/testsuites/sptests/sp28/init.c @@ -22,7 +22,7 @@ rtems_task Init(rtems_task_argument argument); #include #include -volatile int taskvar; +volatile void *taskvar; rtems_task subtask (rtems_task_argument arg) @@ -31,37 +31,36 @@ subtask (rtems_task_argument arg) int i; rtems_status_code sc; - sc = rtems_task_variable_add (RTEMS_SELF, (void *) &taskvar); + sc = rtems_task_variable_add (RTEMS_SELF, &taskvar, NULL); if (sc != RTEMS_SUCCESSFUL) { printf ("Can't add task variable: %s\n", rtems_status_text (sc)); rtems_task_suspend (RTEMS_SELF); } - taskvar = localvar; + taskvar = (void *)localvar; while (localvar < 1000) { localvar++; rtems_task_wake_after (0); - taskvar++; + taskvar = (void *)((int)taskvar + 1); rtems_task_wake_after (0); - if (taskvar != localvar) { - printf ("Task:%d taskvar:%d localvar:%d\n", arg, taskvar, localvar); + if ((int)taskvar != localvar) { + printf ("Task:%d taskvar:%d localvar:%d\n", arg, (int)taskvar, localvar); rtems_task_suspend (RTEMS_SELF); } } - sc = rtems_task_variable_delete (RTEMS_SELF, (void *) &taskvar); + sc = rtems_task_variable_delete (RTEMS_SELF, &taskvar); if (sc != RTEMS_SUCCESSFUL) { printf ("Can't delete task variable: %s\n", rtems_status_text (sc)); rtems_task_suspend (RTEMS_SELF); } for (i = 0 ; ; i++) { - taskvar = localvar = 100 * arg; + taskvar = (void *)(localvar = 100 * arg); rtems_task_wake_after (0); - if (taskvar == localvar) { - printf ("Task:%d taskvar:%d localvar:%d\n", arg, taskvar, localvar); + if ((int)taskvar == localvar) { + printf ("Task:%d taskvar:%d localvar:%d\n", arg, (int)taskvar, localvar); rtems_task_suspend (RTEMS_SELF); } if ((arg == 3) && (i == 100)) { - puts ("Task variables test succeeded."); - puts ("*** END OF TEST SP28 ***"); + printf ("Task variables test succeeded.\n"); exit (0); } } @@ -75,7 +74,7 @@ starttask (int arg) sc = rtems_task_create (rtems_build_name ('S', 'R', 'V', arg + 'A'), 100, - RTEMS_MINIMUM_STACK_SIZE * 3, + 10000, RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0), RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL, &tid); @@ -93,7 +92,6 @@ starttask (int arg) rtems_task Init (rtems_task_argument ignored) { - puts ("*** START OF TEST SP28 ***"); starttask (1); starttask (2); starttask (3); -- cgit v1.2.3