/** * @fn :tc_libc_spawn_task_spawnattr_SetGetstacksize * @brief :sets and gets the stack size attribute of the thread attributes object referred to by st_attr * @scenario :The stack size attribute determines the minimum size (in bytes) that will be allocated for * threads created using the thread attributes object st_attr. * @API's covered :posix_spawnattr_init, task_spawnattr_setstacksize,task_spawnattr_getstacksize * @Preconditions :posix_spawnattr_init * @Postconditions :none * @Return :void */ static void tc_libc_spawn_task_spawnattr_setgetstacksize(void) { int ret_chk = ERROR; pid_t pid; posix_spawnattr_t st_attr; size_t stacksize; ret_chk = posix_spawnattr_init(&st_attr); TC_ASSERT_EQ("posix_spawnattr_init", ret_chk, OK); ret_chk = task_spawnattr_setstacksize(&st_attr, SPAWN_STACKSIZE); TC_ASSERT_EQ("task_spawnattr_setstacksize", ret_chk, OK); ret_chk = task_spawn(&pid, "spawn_stacksize", function_name_spawn, NULL, &st_attr, (char *const *)NULL, (char *const *)NULL); sleep(SEC_4); TC_ASSERT_EQ("task_spawn", ret_chk, OK); ret_chk = task_spawnattr_getstacksize(&st_attr, &stacksize); TC_ASSERT_EQ("task_spawnattr_getstacksize", ret_chk, OK); TC_ASSERT_EQ("task_spawnattr_getstacksize", stacksize, SPAWN_STACKSIZE); TC_SUCCESS_RESULT(); }
int exec_builtin(FAR const char *appname, FAR char * const *argv, FAR const char *redirfile, int oflags) { FAR const struct builtin_s *builtin; posix_spawnattr_t attr; posix_spawn_file_actions_t file_actions; struct sched_param param; pid_t pid; int index; int ret; /* Verify that an application with this name exists */ index = builtin_isavail(appname); if (index < 0) { ret = ENOENT; goto errout_with_errno; } /* Get information about the builtin */ builtin = builtin_for_index(index); if (builtin == NULL) { ret = ENOENT; goto errout_with_errno; } /* Initialize attributes for task_spawn(). */ ret = posix_spawnattr_init(&attr); if (ret != 0) { goto errout_with_errno; } ret = posix_spawn_file_actions_init(&file_actions); if (ret != 0) { goto errout_with_attrs; } /* Set the correct task size and priority */ param.sched_priority = builtin->priority; ret = posix_spawnattr_setschedparam(&attr, ¶m); if (ret != 0) { goto errout_with_actions; } ret = task_spawnattr_setstacksize(&attr, builtin->stacksize); if (ret != 0) { goto errout_with_actions; } /* If robin robin scheduling is enabled, then set the scheduling policy * of the new task to SCHED_RR before it has a chance to run. */ #if CONFIG_RR_INTERVAL > 0 ret = posix_spawnattr_setschedpolicy(&attr, SCHED_RR); if (ret != 0) { goto errout_with_actions; } ret = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER); if (ret != 0) { goto errout_with_actions; } #else ret = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSCHEDPARAM); if (ret != 0) { goto errout_with_actions; } #endif /* Is output being redirected? */ if (redirfile) { /* Set up to close open redirfile and set to stdout (1) */ ret = posix_spawn_file_actions_addopen(&file_actions, 1, redirfile, O_WRONLY, 0644); if (ret != 0) { sdbg("ERROR: posix_spawn_file_actions_addopen failed: %d\n", ret); goto errout_with_actions; } } /* Start the built-in */ ret = task_spawn(&pid, builtin->name, builtin->main, &file_actions, &attr, (argv) ? &argv[1] : (FAR char * const *)NULL, (FAR char * const *)NULL); if (ret != 0) { sdbg("ERROR: task_spawn failed: %d\n", ret); goto errout_with_actions; } /* Free attibutes and file actions. Ignoring return values in the case * of an error. */ /* Return the task ID of the new task if the task was sucessfully * started. Otherwise, ret will be ERROR (and the errno value will * be set appropriately). */ (void)posix_spawn_file_actions_destroy(&file_actions); (void)posix_spawnattr_destroy(&attr); return pid; errout_with_actions: (void)posix_spawn_file_actions_destroy(&file_actions); errout_with_attrs: (void)posix_spawnattr_destroy(&attr); errout_with_errno: set_errno(ret); return ERROR; }