Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion testing/ostest/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ if ARCH_FPU && SCHED_WAITPID

config TESTING_OSTEST_FPUTESTDISABLE
bool "Disable FPU test"
default n
default y if !BUILD_FLAT
default n if BUILD_FAT

if !TESTING_OSTEST_FPUTESTDISABLE

Expand Down
4 changes: 4 additions & 0 deletions testing/ostest/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,8 @@ ifeq ($(CONFIG_ARCH_SETJMP_H),y)
CSRCS += setjmp.c
endif

ifeq ($(CONFIG_BUILD_KERNEL),y)
CSRCS += task.c
endif

include $(APPDIR)/Application.mk
10 changes: 9 additions & 1 deletion testing/ostest/ostest.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,13 @@ void aio_test(void);

/* restart.c ****************************************************************/

#ifndef CONFIG_BUILD_KERNEL
void restart_test(void);
#endif

/* waitpid.c ****************************************************************/

#ifdef CONFIG_SCHED_WAITPID
#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_BUILD_KERNEL)
int waitpid_test(void);
#endif

Expand Down Expand Up @@ -259,4 +261,10 @@ int sem_nfreeholders(void);
# define sem_nfreeholders()
#endif

#ifdef CONFIG_BUILD_KERNEL
int task_create(FAR const char *name, int priority,
int stack_size, main_t entry, FAR char * const argv[]);
int task_delete(int pid);
#endif

#endif /* __APPS_TESTING_OSTEST_OSTEST_H */
20 changes: 19 additions & 1 deletion testing/ostest/ostest_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,13 +344,15 @@ static int user_main(int argc, char *argv[])
check_test_memory_usage();
#endif

#ifndef CONFIG_BUILD_KERNEL
/* Checkout task_restart() */

printf("\nuser_main: task_restart test\n");
restart_test();
check_test_memory_usage();
#endif

#ifdef CONFIG_SCHED_WAITPID
#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_BUILD_KERNEL)
/* Check waitpid() and friends */

printf("\nuser_main: waitpid test\n");
Expand Down Expand Up @@ -555,8 +557,16 @@ static int user_main(int argc, char *argv[])
#endif /* CONFIG_PRIORITY_INHERITANCE && !CONFIG_DISABLE_PTHREAD */

#if defined(CONFIG_ARCH_HAVE_VFORK) && defined(CONFIG_SCHED_WAITPID)
#ifndef CONFIG_BUILD_KERNEL
printf("\nuser_main: vfork() test\n");
vfork_test();
#else
/* REVISIT: The issue with vfork() is on the kernel side, fix the issue
* and re-enable this test with CONFIG_BUILD_KERNEL
*/

printf("\nuser_main: vfork() test DISABLED (CONFIG_BUILD_KERNEL)\n");
#endif
#endif

/* Compare memory usage at time ostest_main started until
Expand Down Expand Up @@ -664,7 +674,15 @@ int main(int argc, FAR char **argv)
#ifdef CONFIG_TESTING_OSTEST_WAITRESULT
/* Wait for the test to complete to get the test result */

#ifndef CONFIG_BUILD_KERNEL
if (waitpid(result, &ostest_result, 0) != result)
#else
if (pthread_join((pthread_t) result, NULL) == 0)
{
ostest_result = OK;
}
else
#endif
{
printf("ostest_main: ERROR Failed to wait for user_main to "
"terminate\n");
Expand Down
4 changes: 4 additions & 0 deletions testing/ostest/restart.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@

#include "ostest.h"

#ifndef CONFIG_BUILD_KERNEL

/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
Expand Down Expand Up @@ -224,3 +226,5 @@ void restart_test(void)

printf("restart_main: Exiting\n");
}

#endif /* !CONFIG_BUILD_KERNEL */
218 changes: 218 additions & 0 deletions testing/ostest/task.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
/****************************************************************************
* apps/testing/ostest/task.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/

/****************************************************************************
* Included Files
****************************************************************************/

#include <nuttx/config.h>

#include <errno.h>
#include <malloc.h>
#include <pthread.h>
#include <spawn.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>

#include <nuttx/compiler.h>

/****************************************************************************
* Pre-processor Definitions
****************************************************************************/

#define MAX_EXEC_ARGS 256

/****************************************************************************
* Private Types
****************************************************************************/

struct main_args_s
{
main_t entry;
int prio;
int argc;
FAR char *argv[];
};

/****************************************************************************
* Private Functions
****************************************************************************/

/****************************************************************************
* Name: main_trampoline
*
* Description:
* Trampoline function for pthread to pass argv among other things
*
****************************************************************************/

static void *main_trampoline(void *ptr)
{
struct main_args_s *args = (struct main_args_s *) ptr;
pthread_setschedprio(pthread_self(), args->prio);
pthread_setname_np(pthread_self(), args->argv[0]);
args->entry(args->argc, args->argv);
free(ptr);
return NULL;
}

/****************************************************************************
* Name: task_create
*
* Description:
* Adaptation for CONFIG_BUILD_KERNEL to compile ostest using pthreads
* instead of NuttX tasks.
*
****************************************************************************/

int task_create(FAR const char *name, int priority,
int stack_size, main_t entry, FAR char * const argv[])
{
FAR struct main_args_s *args;
FAR char *ptr;
pthread_t pid;
pthread_attr_t attr;
size_t argvsize = 0;
size_t argssize;
int argc = 0;
int ret;
int i;

/* Get the number of arguments and the size of the argument list */

if (argv)
{
while (argv[argc])
{
argvsize += strlen(argv[argc]) + 1;
if (argc >= MAX_EXEC_ARGS)
{
ret = E2BIG;
goto update_errno;
}

argc++;
}
}

/* Name is a part of argv */

argvsize += strlen(name) + 1;

/* Allocate the struct + memory for argv + name */

argssize = sizeof(struct main_args_s) + (argc + 2) * sizeof(FAR char *);

args = (struct main_args_s *)malloc(argssize + argvsize);
if (!args)
{
ret = ENOMEM;
goto update_errno;
}

/* Initialize the struct */

args->entry = entry;
args->prio = priority;
args->argc = argc + 1; /* +1 for name */

/* Copy the name */

ptr = (char *)args + argssize;
args->argv[0] = ptr;
strcpy(ptr, name);
ptr += strlen(name) + 1;

/* Copy the argv list */

for (i = 0; i < argc; i++)
{
args->argv[i + 1] = ptr;
strcpy(ptr, argv[i]);
ptr += strlen(argv[i]) + 1;
}

/* Terminate the argv[] list */

args->argv[args->argc] = NULL;

/* Set the worker parameters */

pthread_attr_init(&attr);
pthread_attr_setschedpolicy(&attr, SCHED_RR);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setstacksize(&attr, stack_size);

/* Start the worker */

ret = pthread_create(&pid, &attr, &main_trampoline, args);
if (ret != 0)
{
printf("ERROR: pthread_create:%d, errno:%s\n", ret, strerror(ret));
free(args);
pid = ERROR;
}

pthread_attr_destroy(&attr);

update_errno:
if (ret != 0)
{
set_errno(-ret);
pid = ERROR;
}

return (int)pid;
}

/****************************************************************************
* Name: task_delete
*
* Description:
* Adaptation for CONFIG_BUILD_KERNEL to compile ostest using pthreads
* instead of NuttX tasks.
*
****************************************************************************/

int task_delete(int pid)
{
int ret;

if (pid == pthread_self())
{
ret = pthread_join(pid, NULL);
pthread_exit(NULL);
}
else
{
ret = pthread_cancel(pid);
}

if (ret < 0)
{
set_errno(-ret);
ret = ERROR;
}

return ret;
}

8 changes: 6 additions & 2 deletions testing/ostest/waitpid.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@

#include "ostest.h"

#ifdef CONFIG_SCHED_WAITPID
/* REVISIT: This could be implemented for CONFIG_BUILD_KERNEL as well, by
* starting a new process instead of using task_create()
*/

#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_BUILD_KERNEL)

/****************************************************************************
* Pre-processor Definitions
Expand Down Expand Up @@ -389,4 +393,4 @@ int waitpid_test(void)
return 0;
}

#endif /* CONFIG_SCHED_WAITPID */
#endif /* CONFIG_SCHED_WAITPID && !CONFIG_BUILD_KERNEL */