Exemple #1
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 );
}
Exemple #2
0
int rtems_gxx_key_create (__gthread_key_t *key, void (*dtor) (void *))
{
  rtems_status_code status;

  /* Ok, this can be a bit tricky. We are going to return a "key" as a
   * pointer to the buffer that will hold the value of the key itself.
   * We have to to this, because the others functions on this interface
   * deal with the value of the key, as used with the POSIX API.
   */
   /* Do not pull your hair, trust me this works. :-) */
  __gthread_key_t new_key = (__gthread_key_t) malloc( sizeof( *new_key ) );
  *key = new_key;
  new_key->val  = NULL;
  new_key->dtor = dtor;

  #ifdef DEBUG_GXX_WRAPPERS
    printk(
      "gxx_wrappers: create key=%x, dtor=%x, new_key=%x\n", key, dtor, new_key
    );
  #endif

  /* register with RTEMS the buffer that will hold the key values */
  status = rtems_task_variable_add( RTEMS_SELF, (void **)new_key, dtor );
  if ( status == RTEMS_SUCCESSFUL )
    return 0;

  free( new_key );
  return -1;
}
Exemple #3
0
void *rtems_gxx_getspecific(__gthread_key_t key)
{
  rtems_status_code  status;
  void              *p= 0;

  /* register with RTEMS the buffer that will hold the key values */
  status = rtems_task_variable_get( RTEMS_SELF, (void **)key, &p );
  if ( status == RTEMS_SUCCESSFUL ) {
    /* We do not have to do this, but what the heck ! */
     p= key->val;
  } else {
    /* fisrt time, always set to zero, it is unknown the value that the others
     * threads are using at the moment of this call
     */
    status = rtems_task_variable_add( RTEMS_SELF, (void **)key, key->dtor );
    if ( status != RTEMS_SUCCESSFUL ) {
      _Internal_error_Occurred(
        INTERNAL_ERROR_CORE,
        true,
        INTERNAL_ERROR_GXX_KEY_ADD_FAILED
      );
    }
    key->val = (void *)0;
  }

  #ifdef DEBUG_GXX_WRAPPERS
    printk(
      "gxx_wrappers: getspecific key=%x, ptr=%x, id=%x\n",
       key,
       p,
       rtems_task_self()
    );
  #endif
  return p;
}
Exemple #4
0
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" );
  }
}
Exemple #5
0
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);
  }
}
Exemple #6
0
/*
 * Set up per-task RPC variables
 */
int rtems_rpc_task_init (void)
{
	rtems_status_code sc;
	struct _rtems_rpc_task_variables *tvp;

	if (rtems_rpc_task_variables == &rpc_default) {
		tvp = malloc (sizeof *tvp);
		if (tvp == NULL)
			return RTEMS_NO_MEMORY;
		/*
		 * FIXME: Should have destructor which cleans up
		 * all RPC stuff:
		 *	- Close all files
		 *	- Go through and free linked list elements
		 *	- Free other allocated memory (e.g. clnt_perror_buf)
		 */
		sc = rtems_task_variable_add (
			RTEMS_SELF, (void *)&rtems_rpc_task_variables, NULL);
		if (sc != RTEMS_SUCCESSFUL) {
			free (tvp);
			return sc;
		}
		*tvp = rpc_init;
		rtems_rpc_task_variables = tvp;
	}
	return RTEMS_SUCCESSFUL;
}
Exemple #7
0
BSP_ExceptionExtension
BSP_exceptionHandlerInstall(BSP_ExceptionExtension e)
{
volatile BSP_ExceptionExtension	test;
	if ( RTEMS_SUCCESSFUL != rtems_task_variable_get(RTEMS_SELF, (void*)&BSP_exceptionExtension, (void**)&test) ) {
		/* not yet added */
		rtems_task_variable_add(RTEMS_SELF, (void*)&BSP_exceptionExtension, 0);
	}
	test = BSP_exceptionExtension;
	BSP_exceptionExtension = e;
	return test;
}
Exemple #8
0
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" );

}
rtems_status_code rtems_libio_set_private_env(void) {
  rtems_status_code 					sc;
  rtems_id          					task_id;
  rtems_filesystem_location_info_t		loc;

  sc=rtems_task_ident(RTEMS_SELF,0,&task_id);
  if (sc != RTEMS_SUCCESSFUL) return sc;

  /* Only for the first time a malloc is necesary */
  if (rtems_current_user_env==&rtems_global_user_env) {
   rtems_user_env_t	*tmp = malloc(sizeof(rtems_user_env_t));
   if (!tmp)
     return RTEMS_NO_MEMORY;

#ifdef HAVE_USERENV_REFCNT
   tmp->refcnt = 1;
#endif

   sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,(void(*)(void *))free_user_env);
   if (sc != RTEMS_SUCCESSFUL) {
	 /* don't use free_user_env because the pathlocs are
	  * not initialized yet
	  */
     free(tmp);
     return sc;
   }
   rtems_current_user_env = tmp;
  };

  *rtems_current_user_env = rtems_global_user_env; /* get the global values*/
  rtems_current_user_env->task_id=task_id;         /* mark the local values*/

  /* Clone the pathlocs. In contrast to most other
   * code we must _not_ free the original locs because
   * what we are trying to do here is forking off
   * clones. The reason is a pathloc can be allocated by the
   * file system and needs to be freed when deleting the environment.
   */

  rtems_filesystem_evaluate_path("/", 1, 0, &loc, 0);
  rtems_filesystem_root    = loc;
  rtems_filesystem_evaluate_path("/", 1, 0, &loc, 0);
  rtems_filesystem_current = loc;

  return RTEMS_SUCCESSFUL;
}
rtems_status_code rtems_libio_share_private_env(rtems_id task_id) {
  rtems_status_code  sc;
  rtems_user_env_t * shared_user_env;
  rtems_id           current_task_id;

  sc=rtems_task_ident(RTEMS_SELF,0,&current_task_id);
  if (sc != RTEMS_SUCCESSFUL) return sc;

  if (rtems_current_user_env->task_id==current_task_id) {
   /* kill the current user env & task_var*/
	rtems_user_env_t 	*tmp = rtems_current_user_env;
   sc = rtems_task_variable_delete(RTEMS_SELF,(void*)&rtems_current_user_env);
   if (sc != RTEMS_SUCCESSFUL) return sc;
   free_user_env(tmp);
  };

  /* AT THIS POINT, rtems_current_user_env is DANGLING */

  sc = rtems_task_variable_get(task_id,(void*)&rtems_current_user_env,
		                       (void*)&shared_user_env       );
  if (sc != RTEMS_SUCCESSFUL)
    goto bailout;

  sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,free_user_env);
  if (sc != RTEMS_SUCCESSFUL)
    goto bailout;

  /* the current_user_env is the same pointer that remote env */
  rtems_current_user_env = shared_user_env;

  /* increase the reference count */
#ifdef HAVE_USERENV_REFCNT
  rtems_current_user_env->refcnt++;
#endif

  return RTEMS_SUCCESSFUL;

bailout:
  /* fallback to the global env */
  rtems_current_user_env = &rtems_global_user_env;
  return sc;
}
Exemple #11
0
int rtems_gxx_setspecific(__gthread_key_t key, const void *ptr)
{
  rtems_status_code status;

  #ifdef DEBUG_GXX_WRAPPERS
    printk(
      "gxx_wrappers: setspecific key=%x, ptr=%x, id=%x\n",
      key,
      ptr,
      rtems_task_self()
      );
  #endif

  /* register with RTEMS the buffer that will hold the key values */
  status = rtems_task_variable_add( RTEMS_SELF, (void **)key, key->dtor );
  if ( status == RTEMS_SUCCESSFUL ) {
    /* now let's set the proper value */
    key->val =  (void *)ptr;
    return 0;
  }
  return -1;
}
Exemple #12
0
bool rtems_shell_main_loop(
  rtems_shell_env_t *shell_env_arg
)
{
  rtems_shell_env_t *shell_env;
  rtems_shell_cmd_t *shell_cmd;
  rtems_status_code  sc;
  struct termios     term;
  struct termios     previous_term;
  char              *prompt = NULL;
  int                cmd;
  int                cmd_count = 1; /* assume a script and so only 1 command line */
  char              *cmds[RTEMS_SHELL_CMD_COUNT];
  char              *cmd_argv;
  int                argc;
  char              *argv[RTEMS_SHELL_MAXIMUM_ARGUMENTS];
  bool               result = true;
  bool               input_file = false;
  int                line = 0;
  FILE              *stdinToClose = NULL;
  FILE              *stdoutToClose = NULL;

  rtems_shell_initialize_command_set();

  shell_env =
  rtems_current_shell_env = rtems_shell_init_env( shell_env_arg );

  /*
   * @todo chrisj
   * Remove the use of task variables. Change to have a single
   * allocation per shell and then set into a notepad register
   * in the TCB. Provide a function to return the pointer.
   * Task variables are a virus to embedded systems software.
   */
  sc = rtems_task_variable_add(
    RTEMS_SELF,
    (void*)&rtems_current_shell_env,
    rtems_shell_env_free
  );
  if (sc != RTEMS_SUCCESSFUL) {
    rtems_error(sc,"rtems_task_variable_add(current_shell_env):");
    return false;
  }

  setuid(0);
  setgid(0);

  rtems_current_user_env->euid = rtems_current_user_env->egid = 0;

  fileno(stdout);

  /* fprintf( stderr,
     "-%s-%s-\n", shell_env->input, shell_env->output );
  */

  if (shell_env->output && strcmp(shell_env->output, "stdout") != 0) {
    if (strcmp(shell_env->output, "stderr") == 0) {
      stdout = stderr;
    } else if (strcmp(shell_env->output, "/dev/null") == 0) {
      fclose (stdout);
    } else {
      FILE *output = fopen(shell_env_arg->output,
                           shell_env_arg->output_append ? "a" : "w");
      if (!output) {
        fprintf(stderr, "shell: open output %s failed: %s\n",
                shell_env_arg->output, strerror(errno));
        return false;
      }
      stdout = output;
      stdoutToClose = output;
    }
  }

  if (shell_env->input && strcmp(shell_env_arg->input, "stdin") != 0) {
    FILE *input = fopen(shell_env_arg->input, "r");
    if (!input) {
      fprintf(stderr, "shell: open input %s failed: %s\n",
              shell_env_arg->input, strerror(errno));
      return false;
    }
    stdin = input;
    stdinToClose = input;
    shell_env->forever = false;
    input_file =true;
  }
  else {
    /* make a raw terminal,Linux Manuals */
    if (tcgetattr(fileno(stdin), &previous_term) >= 0) {
      term = previous_term;
      term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
      term.c_oflag &= ~OPOST;
      term.c_oflag |= (OPOST|ONLCR); /* But with cr+nl on output */
      term.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
      term.c_cflag  |= CLOCAL | CREAD;
      term.c_cc[VMIN]  = 1;
      term.c_cc[VTIME] = 0;
      if (tcsetattr (fileno(stdin), TCSADRAIN, &term) < 0) {
        fprintf(stderr,
                "shell:cannot set terminal attributes(%s)\n",shell_env->devname);
      }
    }
    cmd_count = RTEMS_SHELL_CMD_COUNT;
    prompt = malloc(RTEMS_SHELL_PROMPT_SIZE);
    if (!prompt)
        fprintf(stderr,
                "shell:cannot allocate prompt memory\n");
  }

  setvbuf(stdin,NULL,_IONBF,0); /* Not buffered*/
  setvbuf(stdout,NULL,_IONBF,0); /* Not buffered*/

  rtems_shell_initialize_command_set();

  /*
   * Allocate the command line buffers.
   */
  cmd_argv = malloc (RTEMS_SHELL_CMD_SIZE);
  if (!cmd_argv) {
    fprintf(stderr, "no memory for command line buffers\n" );
  }

  cmds[0] = calloc (cmd_count, RTEMS_SHELL_CMD_SIZE);
  if (!cmds[0]) {
    fprintf(stderr, "no memory for command line buffers\n" );
  }

  if (cmd_argv && cmds[0]) {

    memset (cmds[0], 0, cmd_count * RTEMS_SHELL_CMD_SIZE);

    for (cmd = 1; cmd < cmd_count; cmd++) {
      cmds[cmd] = cmds[cmd - 1] + RTEMS_SHELL_CMD_SIZE;
    }

    do {
      /* Set again root user and root filesystem, side effect of set_priv..*/
      sc = rtems_libio_set_private_env();
      if (sc != RTEMS_SUCCESSFUL) {
        rtems_error(sc,"rtems_libio_set_private_env():");
        result = false;
        break;
      }

      /*
       *  By using result here, we can fall to the bottom of the
       *  loop when the connection is dropped during login and
       *  keep on trucking.
       */
      if (shell_env->login_check != NULL) {
        result = rtems_shell_login(stdin,stdout);
      } else {
        result = true;
      }

      if (result)  {
        const char *c;
        memset (cmds[0], 0, cmd_count * RTEMS_SHELL_CMD_SIZE);
        if (!input_file) {
          rtems_shell_cat_file(stdout,"/etc/motd");
          fprintf(stdout, "\n"
                  "RTEMS SHELL (Ver.1.0-FRC):%s. " \
                  __DATE__". 'help' to list commands.\n",
                  shell_env->devname);
        }

        if (input_file)
          chdir(shell_env->cwd);
        else
          chdir("/"); /* XXX: chdir to getpwent homedir */

        shell_env->exit_shell = false;

        for (;;) {
          int cmd;

          /* Prompt section */
          if (prompt) {
            rtems_shell_get_prompt(shell_env, prompt,
                                   RTEMS_SHELL_PROMPT_SIZE);
          }

          /* getcmd section */
          cmd = rtems_shell_line_editor(cmds, cmd_count,
                                        RTEMS_SHELL_CMD_SIZE, prompt,
                                        stdin, stdout);

          if (cmd == -1)
            continue; /* empty line */

          if (cmd == -2)
            break; /*EOF*/

          line++;

          if (shell_env->echo)
            fprintf(stdout, "%d: %s\n", line, cmds[cmd]);

          /* evaluate cmd section */
          c = cmds[cmd];
          while (*c) {
            if (!isblank((unsigned char)*c))
              break;
            c++;
          }

          if (*c == '\0')   /* empty line */
            continue;

          if (*c == '#') {  /* comment character */
            cmds[cmd][0] = 0;
            continue;
          }

          if (!strcmp(cmds[cmd],"bye") || !strcmp(cmds[cmd],"exit")) {
            fprintf(stdout, "Shell exiting\n" );
            break;
          } else if (!strcmp(cmds[cmd],"shutdown")) { /* exit application */
            fprintf(stdout, "System shutting down at user request\n" );
            exit(0);
          }

          /* exec cmd section */
          /* TODO:
           *  To avoid user crash catch the signals.
           *  Open a new stdio files with posibility of redirection *
           *  Run in a new shell task background. (unix &)
           *  Resuming. A little bash.
           */
          memcpy (cmd_argv, cmds[cmd], RTEMS_SHELL_CMD_SIZE);
          if (!rtems_shell_make_args(cmd_argv, &argc, argv,
                                     RTEMS_SHELL_MAXIMUM_ARGUMENTS)) {
            shell_cmd = rtems_shell_lookup_cmd(argv[0]);
            if ( argv[0] == NULL ) {
              shell_env->errorlevel = -1;
            } else if ( shell_cmd == NULL ) {
              shell_env->errorlevel = rtems_shell_script_file(argc, argv);
            } else {
              shell_env->errorlevel = shell_cmd->command(argc, argv);
            }
          }

          /* end exec cmd section */
          if (shell_env->exit_shell)
            break;
        }

        fflush( stdout );
        fflush( stderr );
      }
    } while (result && shell_env->forever);

  }

  if (cmds[0])
    free (cmds[0]);
  if (cmd_argv)
    free (cmd_argv);
  if (prompt)
    free (prompt);

  if (stdinToClose) {
    fclose( stdinToClose );
  } else {
    if (tcsetattr(fileno(stdin), TCSADRAIN, &previous_term) < 0) {
      fprintf(
        stderr,
        "shell: cannot reset terminal attributes (%s)\n",
        shell_env->devname
      );
    }
  }
  if ( stdoutToClose )
    fclose( stdoutToClose );
  return result;
}
Exemple #13
0
rtems_status_code rtems_libio_set_private_env(void)
{
  rtems_status_code sc = RTEMS_SUCCESSFUL;
  rtems_id task_id = rtems_task_self();
  rtems_filesystem_location_info_t root_loc;
  rtems_filesystem_location_info_t current_loc;
  rtems_user_env_t *new_env = NULL;
  int rv = 0;

  rv = rtems_filesystem_evaluate_path("/", 1, 0, &root_loc, 0);
  if (rv != 0)
    goto error_0;

  rv = rtems_filesystem_evaluate_path("/", 1, 0, &current_loc, 0);
  if (rv != 0)
    goto error_1;

  /* 
   * Malloc is necessary whenever the current task does not
   * have its own environment in place. This could be:
   * a) it never had one
   * OR
   * b) it shared another task's environment
   */

  /* 
   * Bharath: I'm not sure if the check can be reduced to
   * if( rtems_current_user_env->task_id != task_id ) {
   */

  if (
    rtems_current_user_env == &rtems_global_user_env
      || rtems_current_user_env->task_id != task_id
  ) {
    new_env = malloc(sizeof(rtems_user_env_t));
    if (new_env == NULL)
      goto error_2;

    #ifdef HAVE_USERENV_REFCNT
      new_env->refcnt = 1;
    #endif

    sc = rtems_task_variable_add(
      RTEMS_SELF,
      (void*)&rtems_current_user_env,
      (void(*)(void *))free_user_env
    );
    if (sc != RTEMS_SUCCESSFUL)
      goto error_3;

    rtems_current_user_env = new_env;
  }

  /* Inherit the global values */
  *rtems_current_user_env = rtems_global_user_env;

  rtems_current_user_env->task_id = task_id;

  /*
   * Clone the pathlocs. In contrast to most other code we must _not_ free the
   * original locs because what we are trying to do here is forking off clones.
   * The reason is a pathloc can be allocated by the file system and needs to
   * be freed when deleting the environment.
   */
  rtems_filesystem_root = root_loc;
  rtems_filesystem_current = current_loc;

  return RTEMS_SUCCESSFUL;

error_3:
  free(new_env);

error_2:
  rtems_filesystem_freenode(&current_loc);

error_1:
  rtems_filesystem_freenode(&root_loc);

error_0:
  return RTEMS_NO_MEMORY;
}
Exemple #14
0
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);

  puts("*** END OF TEST 28 ***" );
  rtems_test_exit(0);
}
Exemple #15
0
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);
  }
}