summaryrefslogtreecommitdiffstats
path: root/testsuite/thread01
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-10-09 08:56:49 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-10-10 09:09:19 +0200
commitab415f95a9ee784f0aa2131d237455ed6aad2dde (patch)
tree5dbc6edb5c1fe248dc5ca4204b271f5a19c1270d /testsuite/thread01
parentMake default test initialization task preemptive (diff)
downloadrtems-libbsd-ab415f95a9ee784f0aa2131d237455ed6aad2dde.tar.bz2
Use extension to attach a struct thread to threads
Add test thread01.
Diffstat (limited to 'testsuite/thread01')
-rw-r--r--testsuite/thread01/test_main.c304
1 files changed, 304 insertions, 0 deletions
diff --git a/testsuite/thread01/test_main.c b/testsuite/thread01/test_main.c
new file mode 100644
index 00000000..643a6ad9
--- /dev/null
+++ b/testsuite/thread01/test_main.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/rtems-bsd-config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <rtems/bsd/sys/types.h>
+#include <rtems/bsd/sys/param.h>
+#include <sys/proc.h>
+#include <sys/kthread.h>
+#include <sys/errno.h>
+
+#include <rtems.h>
+#include <rtems/libcsupport.h>
+#include <rtems/score/threaddispatch.h>
+#include <rtems/score/wkspace.h>
+
+#define TEST_NAME "LIBBSD THREAD 1"
+
+#define TEST_KTHREAD_ADD ((void *) 0xdeadbeef)
+
+static rtems_id main_task_id;
+
+static char test_kproc_name[] = "kproc";
+
+static struct kproc_desc test_kproc_start_desc;
+
+static char test_kthread_name[] = "kthread";
+
+static struct kthread_desc test_kthread_start_desc;
+
+static void
+test_curthread(const char *name)
+{
+ struct thread *td_0 = rtems_bsd_get_curthread_or_null();
+ struct thread *td_1 = rtems_bsd_get_curthread_or_wait_forever();
+ struct thread *td_2 = curthread;
+
+ assert(td_0 != NULL);
+ assert(td_0 == td_1);
+ assert(td_0 == td_2);
+ assert(strcmp(&td_0->td_name[0], name) == 0);
+}
+
+static void
+wake_up_main_thread(void)
+{
+ rtems_status_code sc;
+
+ sc = rtems_event_transient_send(main_task_id);
+ assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void
+wait_for_worker_thread(void)
+{
+ rtems_status_code sc;
+
+ sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void
+non_bsd_thread(rtems_task_argument arg)
+{
+ rtems_status_code sc;
+
+ test_curthread("");
+ wake_up_main_thread();
+
+ sc = rtems_task_delete(RTEMS_SELF);
+ assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void
+test_non_bsd_thread(void)
+{
+ rtems_status_code sc;
+ rtems_id task_id;
+ rtems_resource_snapshot snapshot;
+
+ rtems_resource_snapshot_take(&snapshot);
+
+ sc = rtems_task_create(
+ rtems_build_name('T', 'A', 'S', 'K'),
+ RTEMS_MINIMUM_PRIORITY,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &task_id
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_start(task_id, non_bsd_thread, 0);
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ wait_for_worker_thread();
+
+ assert(rtems_resource_snapshot_check(&snapshot));
+}
+
+static void
+test_kproc_start_proc(void)
+{
+ test_curthread(&test_kproc_name[0]);
+ wake_up_main_thread();
+ kproc_exit(0);
+}
+
+static void
+test_kproc_start(void)
+{
+ rtems_resource_snapshot snapshot;
+ struct proc *pr = NULL;
+ struct kproc_desc *kpd = &test_kproc_start_desc;
+
+ puts("test kproc_start()");
+
+ rtems_resource_snapshot_take(&snapshot);
+
+ kpd->arg0 = &test_kproc_name[0];
+ kpd->func = test_kproc_start_proc,
+ kpd->global_procpp = &pr;
+
+ kproc_start(kpd);
+ wait_for_worker_thread();
+
+ assert(pr != NULL);
+
+ assert(rtems_resource_snapshot_check(&snapshot));
+}
+
+static void
+test_kthread_start_thread(void)
+{
+ test_curthread(&test_kthread_name[0]);
+ wake_up_main_thread();
+ kthread_exit();
+}
+
+static void
+test_kthread_start(void)
+{
+ rtems_resource_snapshot snapshot;
+ struct thread *td = NULL;
+ struct kthread_desc *ktd = &test_kthread_start_desc;
+
+ puts("test kthread_start()");
+
+ rtems_resource_snapshot_take(&snapshot);
+
+ ktd->arg0 = &test_kthread_name[0];
+ ktd->func = test_kthread_start_thread,
+ ktd->global_threadpp = &td;
+
+ kthread_start(ktd);
+ wait_for_worker_thread();
+
+ assert(td != NULL);
+
+ assert(rtems_resource_snapshot_check(&snapshot));
+}
+
+static void
+test_kthread_add_thread(void *arg)
+{
+ test_curthread(&test_kthread_name[0]);
+
+ assert(arg == TEST_KTHREAD_ADD);
+
+ wake_up_main_thread();
+ kthread_exit();
+}
+
+static void
+test_kthread_add(void)
+{
+ rtems_resource_snapshot snapshot;
+ uintptr_t take_away;
+ void *greedy;
+
+ puts("test kthread_add()");
+
+ greedy = rtems_workspace_greedy_allocate_all_except_largest(&take_away);
+
+ rtems_resource_snapshot_take(&snapshot);
+
+ assert(rtems_configuration_get_unified_work_area());
+
+ while (take_away > 0) {
+ struct thread *td = NULL;
+ void *away;
+ int eno;
+
+ /*
+ * FIXME: This direct workspace access is a hack to get
+ * reasonable test run times with RTEMS_DEBUG enabled.
+ */
+ _Thread_Disable_dispatch();
+ away = _Workspace_Allocate(take_away);
+ _Thread_Enable_dispatch();
+
+ eno = kthread_add(
+ test_kthread_add_thread,
+ TEST_KTHREAD_ADD,
+ NULL,
+ &td,
+ 0,
+ 0,
+ "%s",
+ &test_kthread_name[0]
+ );
+
+ _Thread_Disable_dispatch();
+ _Workspace_Free(away);
+ _Thread_Enable_dispatch();
+
+ if (eno == 0) {
+ wait_for_worker_thread();
+ assert(td != NULL);
+
+ take_away = 0;
+ } else {
+ assert(eno == ENOMEM);
+ assert(rtems_resource_snapshot_check(&snapshot));
+
+ --take_away;
+ }
+ }
+
+ rtems_workspace_greedy_free(greedy);
+}
+
+static void
+test_rtems_bsd_get_curthread_or_null(void)
+{
+ rtems_resource_snapshot snapshot;
+ void *greedy;
+
+ puts("test rtems_bsd_get_curthread_or_null()");
+
+ rtems_resource_snapshot_take(&snapshot);
+
+ greedy = rtems_workspace_greedy_allocate(NULL, 0);
+ assert(rtems_bsd_get_curthread_or_null() == NULL);
+ rtems_workspace_greedy_free(greedy);
+
+ rtems_resource_snapshot_take(&snapshot);
+}
+
+static void
+test_main(void)
+{
+ rtems_status_code sc;
+ rtems_task_priority prio = RTEMS_MAXIMUM_PRIORITY - 1;
+
+ main_task_id = rtems_task_self();
+
+ sc = rtems_task_set_priority(RTEMS_SELF, prio, &prio);
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ test_non_bsd_thread();
+ test_kproc_start();
+ test_kthread_start();
+ test_kthread_add();
+ test_rtems_bsd_get_curthread_or_null();
+
+ puts("*** END OF " TEST_NAME " TEST ***");
+ exit(0);
+}
+
+#include <rtems/bsd/test/default-init.h>