summaryrefslogtreecommitdiffstats
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
parentMake default test initialization task preemptive (diff)
downloadrtems-libbsd-ab415f95a9ee784f0aa2131d237455ed6aad2dde.tar.bz2
Use extension to attach a struct thread to threads
Add test thread01.
-rw-r--r--Makefile12
-rwxr-xr-xfreebsd-to-rtems.py1
-rw-r--r--freebsd/sys/dev/usb/usb_process.c8
-rw-r--r--freebsd/sys/dev/usb/usb_process.h4
-rw-r--r--freebsd/sys/kern/kern_intr.c3
-rw-r--r--freebsd/sys/sys/pcpu.h5
-rw-r--r--freebsd/sys/sys/proc.h9
-rw-r--r--rtemsbsd/include/machine/pcpu.h42
-rw-r--r--rtemsbsd/include/machine/rtems-bsd-config.h.in13
-rw-r--r--rtemsbsd/include/machine/rtems-bsd-thread.h73
-rw-r--r--rtemsbsd/rtems/rtems-bsd-init-with-irq.c5
-rw-r--r--rtemsbsd/rtems/rtems-bsd-init.c1
-rw-r--r--rtemsbsd/rtems/rtems-bsd-mutex.c1
-rw-r--r--rtemsbsd/rtems/rtems-bsd-panic.c18
-rw-r--r--rtemsbsd/rtems/rtems-bsd-shell.c15
-rw-r--r--rtemsbsd/rtems/rtems-bsd-thread.c319
-rw-r--r--testsuite/include/rtems/bsd/test/default-init.h3
-rw-r--r--testsuite/swi01/init.c2
-rw-r--r--testsuite/thread01/test_main.c304
-rw-r--r--testsuite/timeout01/init.c2
-rw-r--r--testsuite/usb01/init.c2
21 files changed, 625 insertions, 217 deletions
diff --git a/Makefile b/Makefile
index 10b335a0..f710203d 100644
--- a/Makefile
+++ b/Makefile
@@ -863,6 +863,18 @@ O_FILES += $(TEST_INIT01_O_FILES)
D_FILES += $(TEST_INIT01_D_FILES)
RUN_TESTS += $(TEST_INIT01)
+TEST_THREAD01 = testsuite/thread01/thread01.exe
+TEST_THREAD01_O_FILES =
+TEST_THREAD01_D_FILES =
+TEST_THREAD01_O_FILES += testsuite/thread01/test_main.o
+TEST_THREAD01_D_FILES += testsuite/thread01/test_main.d
+$(TEST_THREAD01): $(TEST_THREAD01_O_FILES) $(LIB)
+ $(LINK.c) $^ -lm -o $@
+TESTS += $(TEST_THREAD01)
+O_FILES += $(TEST_THREAD01_O_FILES)
+D_FILES += $(TEST_THREAD01_D_FILES)
+RUN_TESTS += $(TEST_THREAD01)
+
ifeq ($(NEED_DUMMY_PIC_IRQ),yes)
CFLAGS += -I rtems-dummy-pic-irq/include
endif
diff --git a/freebsd-to-rtems.py b/freebsd-to-rtems.py
index db43581a..bb7cd59c 100755
--- a/freebsd-to-rtems.py
+++ b/freebsd-to-rtems.py
@@ -2363,6 +2363,7 @@ tests.addTest('netshell01', ['test_main', 'shellconfig', 'ns_parser_vars'], Fals
tests.addTest('swi01', ['init', 'swi_test'])
tests.addTest('timeout01', ['init', 'timeout_test', 'timeout_helper'])
tests.addTest('init01', ['test_main'])
+tests.addTest('thread01', ['test_main'])
# Register all the Module instances with the Module Manager
mm.addModule(rtems)
diff --git a/freebsd/sys/dev/usb/usb_process.c b/freebsd/sys/dev/usb/usb_process.c
index 67ddf693..8cb00473 100644
--- a/freebsd/sys/dev/usb/usb_process.c
+++ b/freebsd/sys/dev/usb/usb_process.c
@@ -99,11 +99,11 @@ usb_process(void *arg)
{
struct usb_process *up = arg;
struct usb_proc_msg *pm;
-#ifndef __rtems__
struct thread *td;
/* adjust priority */
td = curthread;
+#ifndef __rtems__
thread_lock(td);
sched_prio(td, up->up_prio);
thread_unlock(td);
@@ -111,9 +111,7 @@ usb_process(void *arg)
mtx_lock(up->up_mtx);
-#ifndef __rtems__
up->up_curtd = td;
-#endif /* __rtems__ */
while (1) {
@@ -390,11 +388,7 @@ usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1)
mtx_assert(up->up_mtx, MA_OWNED);
-#ifndef __rtems__
if (up->up_curtd == curthread) {
-#else /* __rtems__ */
- if (up->up_ptr->td_id == rtems_task_self()) {
-#endif /* __rtems__ */
/* Just remove the messages from the queue. */
if (pm0->pm_qentry.tqe_prev) {
TAILQ_REMOVE(&up->up_qhead, pm0, pm_qentry);
diff --git a/freebsd/sys/dev/usb/usb_process.h b/freebsd/sys/dev/usb/usb_process.h
index f9a3c38d..b4159af1 100644
--- a/freebsd/sys/dev/usb/usb_process.h
+++ b/freebsd/sys/dev/usb/usb_process.h
@@ -49,16 +49,12 @@ struct usb_process {
struct cv up_cv;
struct cv up_drain;
-#ifndef __rtems__
#if (__FreeBSD_version >= 800000)
struct thread *up_ptr;
#else
struct proc *up_ptr;
#endif
struct thread *up_curtd;
-#else /* __rtems__ */
- struct thread *up_ptr;
-#endif /* __rtems__ */
struct mtx *up_mtx;
usb_size_t up_msg_num;
diff --git a/freebsd/sys/kern/kern_intr.c b/freebsd/sys/kern/kern_intr.c
index bc252c13..f86fa675 100644
--- a/freebsd/sys/kern/kern_intr.c
+++ b/freebsd/sys/kern/kern_intr.c
@@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$");
#ifdef INTR_FILTER
#error INTR_FILTER is currently not suppported with RTEMS
#endif
+ #include <machine/rtems-bsd-thread.h>
#define RTEMSBSD_SWI_WAKEUP_EVENT RTEMS_EVENT_31
#endif /* __rtems__ */
#ifdef DDB
@@ -924,7 +925,7 @@ intr_event_schedule_thread(struct intr_event *ie)
/* Send event to wake the thread up.
* TODO: eventually replace event by a better mechanism
*/
- rtems_status_code sc = rtems_event_send(td->td_id, RTEMSBSD_SWI_WAKEUP_EVENT);
+ rtems_status_code sc = rtems_event_send(rtems_bsd_get_task_id(td), RTEMSBSD_SWI_WAKEUP_EVENT);
BSD_ASSERT(sc == RTEMS_SUCCESSFUL);
#endif /* __rtems__ */
thread_unlock(td);
diff --git a/freebsd/sys/sys/pcpu.h b/freebsd/sys/sys/pcpu.h
index e0eb23f4..b3bbb16a 100644
--- a/freebsd/sys/sys/pcpu.h
+++ b/freebsd/sys/sys/pcpu.h
@@ -201,11 +201,6 @@ SLIST_HEAD(cpuhead, pcpu);
extern struct cpuhead cpuhead;
extern struct pcpu *cpuid_to_pcpu[MAXCPU];
-#ifdef __rtems__
-struct thread *rtems_get_curthread(void);
-#define curthread rtems_get_curthread()
-#endif
-
#define curcpu PCPU_GET(cpuid)
#define curproc (curthread->td_proc)
#ifndef curthread
diff --git a/freebsd/sys/sys/proc.h b/freebsd/sys/sys/proc.h
index cd10421e..7bf640c7 100644
--- a/freebsd/sys/sys/proc.h
+++ b/freebsd/sys/sys/proc.h
@@ -198,6 +198,11 @@ struct rusage_ext {
* Thread context. Processes may have multiple threads.
*/
struct thread {
+#ifdef __rtems__
+ rtems_chain_node td_node;
+ Thread_Control *td_thread;
+ char td_name [16];
+#endif /* __rtems__ */
#ifndef __rtems__
struct mtx *volatile td_lock; /* replaces sched lock */
#endif /* __rtems__ */
@@ -314,10 +319,6 @@ struct thread {
const char *td_vnet_lpush; /* (k) Debugging vnet push / pop. */
struct rusage_ext td_rux; /* (t) Internal rusage information. */
struct vm_map_entry *td_map_def_user; /* (k) Deferred entries. */
-#else /* __rtems__ */
- rtems_chain_node td_node;
- rtems_id td_id;
- char td_name [16];
#endif /* __rtems__ */
};
diff --git a/rtemsbsd/include/machine/pcpu.h b/rtemsbsd/include/machine/pcpu.h
index caf1385f..b09f0942 100644
--- a/rtemsbsd/include/machine/pcpu.h
+++ b/rtemsbsd/include/machine/pcpu.h
@@ -7,27 +7,48 @@
*/
/*
- * Copyright (c) 2009, 2010 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2009-2013 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
- * Obere Lagerstr. 30
+ * Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.com/license/LICENSE.
+ * 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.
*/
#ifndef _RTEMS_BSD_MACHINE_PCPU_H_
#define _RTEMS_BSD_MACHINE_PCPU_H_
-#ifndef _RTEMS_BSD_MACHINE_RTEMS_BSD_CONFIG_H_
-#error "the header file <freebsd/machine/rtems-bsd-config.h> must be included first"
-#endif
+struct thread;
+
+struct thread *
+rtems_bsd_get_curthread_or_wait_forever(void);
-#define curthread (( struct thread * )(( RTEMS_API_Control * )_Thread_Executing->API_Extensions[THREAD_API_RTEMS] )->Notepads[RTEMS_NOTEPAD_0] )
+struct thread *
+rtems_bsd_get_curthread_or_null(void);
+
+#define curthread rtems_bsd_get_curthread_or_wait_forever()
extern struct pcpu *pcpup;
@@ -35,7 +56,4 @@ extern struct pcpu *pcpup;
#define PCPU_GET(member) (0)
#define PCPU_SET(member, val)
-//#define PCPU_GET(member) (pcpup->pc_ ## member)
-//#define PCPU_SET(member, val) (pcpup->pc_ ## member = (val))
-
#endif /* _RTEMS_BSD_MACHINE_PCPU_H_ */
diff --git a/rtemsbsd/include/machine/rtems-bsd-config.h.in b/rtemsbsd/include/machine/rtems-bsd-config.h.in
index 3990710d..477a2cd1 100644
--- a/rtemsbsd/include/machine/rtems-bsd-config.h.in
+++ b/rtemsbsd/include/machine/rtems-bsd-config.h.in
@@ -132,17 +132,6 @@ void rtems_bsd_assert_func(const char *file, int line, const char *func, const c
/* General definitions */
-#define BSD_TASK_PRIORITY_NORMAL 120
-
-#define BSD_TASK_PRIORITY_TIMER 110
-
-#define BSD_TASK_PRIORITY_INTERRUPT 100
-
-#define BSD_TASK_PRIORITY_RESOURCE_OWNER 100
-
-/* FIXME */
-#define BSD_MINIMUM_TASK_STACK_SIZE ((size_t) 32 * 1024)
-
#define M_RTEMS_HEAP 0
#define BSD_MAXIMUM_SLEEP_QUEUES 32
@@ -157,8 +146,6 @@ extern rtems_chain_control rtems_bsd_condvar_chain;
extern rtems_chain_control rtems_bsd_callout_chain;
-extern rtems_chain_control rtems_bsd_thread_chain;
-
extern rtems_chain_control rtems_bsd_malloc_chain;
/* CPU definitions */
diff --git a/rtemsbsd/include/machine/rtems-bsd-thread.h b/rtemsbsd/include/machine/rtems-bsd-thread.h
new file mode 100644
index 00000000..b8088b50
--- /dev/null
+++ b/rtemsbsd/include/machine/rtems-bsd-thread.h
@@ -0,0 +1,73 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_bsd_machine
+ *
+ * @brief TODO.
+ */
+
+/*
+ * Copyright (c) 2009-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.
+ */
+
+#ifndef _RTEMS_BSD_MACHINE_RTEMS_BSD_THREAD_H_
+#define _RTEMS_BSD_MACHINE_RTEMS_BSD_THREAD_H_
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/types.h>
+#include <sys/proc.h>
+
+#include <rtems.h>
+
+#define BSD_TASK_NAME rtems_build_name('_', 'B', 'S', 'D')
+
+#define BSD_TASK_PRIORITY_NORMAL 120
+
+#define BSD_TASK_PRIORITY_TIMER 110
+
+#define BSD_TASK_PRIORITY_INTERRUPT 100
+
+#define BSD_TASK_PRIORITY_RESOURCE_OWNER 100
+
+/* FIXME */
+#define BSD_MINIMUM_TASK_STACK_SIZE ((size_t) 32 * 1024)
+
+extern rtems_chain_control rtems_bsd_thread_chain;
+
+struct thread *
+rtems_bsd_get_thread(const Thread_Control *thread);
+
+static inline rtems_id
+rtems_bsd_get_task_id(const struct thread *td)
+{
+ return td->td_thread->Object.id;
+}
+
+#endif /* _RTEMS_BSD_MACHINE_RTEMS_BSD_THREAD_H_ */
diff --git a/rtemsbsd/rtems/rtems-bsd-init-with-irq.c b/rtemsbsd/rtems/rtems-bsd-init-with-irq.c
index a663fe34..c2966d66 100644
--- a/rtemsbsd/rtems/rtems-bsd-init-with-irq.c
+++ b/rtemsbsd/rtems/rtems-bsd-init-with-irq.c
@@ -7,10 +7,10 @@
*/
/*
- * Copyright (c) 2009, 2010 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2009-2013 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
- * Obere Lagerstr. 30
+ * Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
@@ -38,6 +38,7 @@
*/
#include <machine/rtems-bsd-config.h>
+#include <machine/rtems-bsd-thread.h>
#include <rtems/irq-extension.h>
diff --git a/rtemsbsd/rtems/rtems-bsd-init.c b/rtemsbsd/rtems/rtems-bsd-init.c
index 9e9fb1ff..44262cb6 100644
--- a/rtemsbsd/rtems/rtems-bsd-init.c
+++ b/rtemsbsd/rtems/rtems-bsd-init.c
@@ -38,6 +38,7 @@
*/
#include <machine/rtems-bsd-config.h>
+#include <machine/rtems-bsd-thread.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/sys/types.h>
diff --git a/rtemsbsd/rtems/rtems-bsd-mutex.c b/rtemsbsd/rtems/rtems-bsd-mutex.c
index bc364191..fe01bc48 100644
--- a/rtemsbsd/rtems/rtems-bsd-mutex.c
+++ b/rtemsbsd/rtems/rtems-bsd-mutex.c
@@ -38,6 +38,7 @@
*/
#include <machine/rtems-bsd-config.h>
+#include <machine/rtems-bsd-thread.h>
#include <rtems/score/objectimpl.h>
#include <rtems/rtems/attrimpl.h>
diff --git a/rtemsbsd/rtems/rtems-bsd-panic.c b/rtemsbsd/rtems/rtems-bsd-panic.c
index 6b1d8507..859c34e0 100644
--- a/rtemsbsd/rtems/rtems-bsd-panic.c
+++ b/rtemsbsd/rtems/rtems-bsd-panic.c
@@ -7,10 +7,10 @@
*/
/*
- * Copyright (c) 2009, 2010 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2009-2013 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
- * Obere Lagerstr. 30
+ * Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
@@ -38,6 +38,7 @@
*/
#include <machine/rtems-bsd-config.h>
+#include <machine/rtems-bsd-thread.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/sys/types.h>
@@ -50,18 +51,19 @@
static void
suspend_all_threads(void)
{
- rtems_chain_control *chain = &rtems_bsd_thread_chain;
- rtems_chain_node *node = rtems_chain_first(chain);
+ const rtems_chain_control *chain = &rtems_bsd_thread_chain;
+ const rtems_chain_node *node = rtems_chain_immutable_first(chain);
rtems_id self = rtems_task_self();
while (!rtems_chain_is_tail(chain, node)) {
- struct thread *td = (struct thread *) node;
+ const struct thread *td = (const struct thread *) node;
+ rtems_id id = rtems_bsd_get_task_id(td);
- if (td->td_id != self && td->td_id != RTEMS_SELF) {
- rtems_task_suspend(td->td_id);
+ if (id != self) {
+ rtems_task_suspend(id);
}
- node = rtems_chain_next(node);
+ node = rtems_chain_immutable_next(node);
}
rtems_task_suspend(RTEMS_SELF);
diff --git a/rtemsbsd/rtems/rtems-bsd-shell.c b/rtemsbsd/rtems/rtems-bsd-shell.c
index fba191a0..9e110e28 100644
--- a/rtemsbsd/rtems/rtems-bsd-shell.c
+++ b/rtemsbsd/rtems/rtems-bsd-shell.c
@@ -7,10 +7,10 @@
*/
/*
- * Copyright (c) 2009, 2010 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2009-2013 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
- * Obere Lagerstr. 30
+ * Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
@@ -38,6 +38,7 @@
*/
#include <machine/rtems-bsd-config.h>
+#include <machine/rtems-bsd-thread.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/sys/types.h>
@@ -105,17 +106,17 @@ rtems_bsd_dump_condvar(void)
static void
rtems_bsd_dump_thread(void)
{
- rtems_chain_control *chain = &rtems_bsd_thread_chain;
- rtems_chain_node *node = rtems_chain_first(chain);
+ const rtems_chain_control *chain = &rtems_bsd_thread_chain;
+ const rtems_chain_node *node = rtems_chain_immutable_first(chain);
printf("thread dump:\n");
while (!rtems_chain_is_tail(chain, node)) {
- struct thread *td = (struct thread *) node;
+ const struct thread *td = (const struct thread *) node;
- printf("\t%s: 0x%08x\n", td->td_name, td->td_id);
+ printf("\t%s: 0x%08x\n", td->td_name, rtems_bsd_get_task_id(td));
- node = rtems_chain_next(node);
+ node = rtems_chain_immutable_next(node);
}
}
diff --git a/rtemsbsd/rtems/rtems-bsd-thread.c b/rtemsbsd/rtems/rtems-bsd-thread.c
index 357fb45c..a0a78a59 100644
--- a/rtemsbsd/rtems/rtems-bsd-thread.c
+++ b/rtemsbsd/rtems/rtems-bsd-thread.c
@@ -7,10 +7,10 @@
*/
/*
- * Copyright (c) 2009, 2010 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2009-2013 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
- * Obere Lagerstr. 30
+ * Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
@@ -38,225 +38,238 @@
*/
#include <machine/rtems-bsd-config.h>
+#include <machine/rtems-bsd-thread.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/sys/types.h>
#include <sys/systm.h>
+#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/kthread.h>
#include <sys/malloc.h>
-#include <rtems/bsd/sys/lock.h>
-#include <sys/mutex.h>
+#include <sys/selinfo.h>
+#include <sys/filedesc.h>
#include <sys/jail.h>
#include <sys/resourcevar.h>
-#include <sys/filedesc.h>
+
+#include <rtems/score/threadimpl.h>
+#include <rtems/score/objectimpl.h>
RTEMS_CHAIN_DEFINE_EMPTY(rtems_bsd_thread_chain);
/* FIXME: What to do with the credentials? */
static struct ucred FIXME_ucred = {
- .cr_ref = 1 /* reference count */
+ .cr_ref = 1 /* reference count */
};
static struct filedesc FIXME_fd = {
- .fd_ofiles = NULL /* file structures for open files */
+ .fd_ofiles = NULL /* file structures for open files */
};
static struct proc FIXME_proc = {
.p_ucred = NULL /* (c) Process owner's identity. */
};
-static int prison_init = 1;
static struct prison FIXME_prison = {
.pr_parent = NULL
};
-static struct uidinfo FIXME_uidinfo; /* per euid resource consumption */
-static struct uidinfo FIXME_ruidinfo; /* per ruid resource consumption */
+static size_t rtems_bsd_extension_index;
-static struct thread *rtems_bsd_current_td = NULL;
-
-static void rtems_bsd_thread_descriptor_dtor(void *td)
+struct thread *
+rtems_bsd_get_thread(const Thread_Control *thread)
{
- // XXX are there other pieces to clean up?
- free(td, M_TEMP);
+ return thread->extensions[rtems_bsd_extension_index];
}
static struct thread *
-rtems_bsd_thread_init( rtems_id id )
+rtems_bsd_get_thread_by_id(rtems_id task_id)
{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- unsigned index = 0;
- char name [5] = "_???";
- struct thread *td;
- struct proc *proc;
-
- td = malloc(sizeof(struct thread), M_TEMP, M_WAITOK | M_ZERO);
- if (td == NULL)
- return NULL;
-
- // Initialize the thread descriptor
- index = rtems_object_id_get_index(id);
- snprintf(name + 1, sizeof(name) - 1, "%03u", index);
- sc = rtems_object_set_name(id, name);
- if (sc != RTEMS_SUCCESSFUL) {
- // XXX does the thread get deleted? Seems wrong
- // rtems_task_delete(id);
- free(td, M_TEMP);
- return NULL;
+ struct thread *td = NULL;
+ Thread_Control *thread;
+ Objects_Locations location;
+
+ thread = _Thread_Get(task_id, &location);
+ switch (location) {
+ case OBJECTS_LOCAL:
+ td = rtems_bsd_get_thread(thread);
+ _Objects_Put(&thread->Object);
+ break;
+#if defined(RTEMS_MULTIPROCESSING)
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ break;
+#endif
+ default:
+ break;
}
- td->td_id = id;
- td->td_ucred = crhold(&FIXME_ucred);
-
- td->td_proc = &FIXME_proc;
- if (td->td_proc->p_ucred == NULL) {
- if ( prison_init ) {
- mtx_init(&FIXME_prison.pr_mtx, "prison lock", NULL, MTX_DEF | MTX_DUPOK);
- prison_init = 0;
- }
- FIXME_ucred.cr_prison = &FIXME_prison; /* jail(2) */
- FIXME_ucred.cr_uidinfo = uifind(0);
- FIXME_ucred.cr_ruidinfo = uifind(0);
- FIXME_ucred.cr_ngroups = 1; /* group 0 */
-
- td->td_proc->p_ucred = crhold(&FIXME_ucred);
- mtx_init(&td->td_proc->p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK);
- td->td_proc->p_pid = getpid();
- td->td_proc->p_fibnum = 0;
- td->td_proc->p_fd = &FIXME_fd;
- sx_init_flags(&FIXME_fd.fd_sx, "config SX thread lock", SX_DUPOK);
- }
+ return td;
+}
- // Actually set the global pointer
- rtems_bsd_current_td = td;
+struct thread *
+rtems_bsd_thread_create(Thread_Control *thread, int wait)
+{
+ struct thread *td = malloc(sizeof(*td), M_TEMP, M_ZERO | wait);
- // Now add the task descriptor as a per-task variable
- sc = rtems_task_variable_add(
- id,
- &rtems_bsd_current_td,
- rtems_bsd_thread_descriptor_dtor
- );
- if (sc != RTEMS_SUCCESSFUL) {
- free(td, M_TEMP);
- return NULL;
+ if (td != NULL) {
+ td->td_thread = thread;
+ td->td_proc = &FIXME_proc;
}
- return td;
+ thread->extensions[rtems_bsd_extension_index] = td;
+
+ return td;
}
-/*
- * Threads which delete themselves would leak the task
- * descriptor so we are using the per-task variable so
- * it can be cleaned up.
- */
-struct thread *rtems_get_curthread(void)
+static struct thread *
+rtems_bsd_get_curthread(int wait)
{
- struct thread *td;
-
- /*
- * If we already have a struct thread associated with this thread,
- * obtain it. Otherwise, allocate and initialize one.
- */
- td = rtems_bsd_current_td;
- if ( td == NULL ) {
- td = rtems_bsd_thread_init( rtems_task_self() );
- if ( td == NULL ){
- panic("rtems_get_curthread: Unable to thread descriptor\n");
- }
+ Thread_Control *executing = _Thread_Get_executing();
+ struct thread *td = rtems_bsd_get_thread(executing);
+
+ if (td == NULL) {
+ td = rtems_bsd_thread_create(executing, wait);
}
- return td;
+ return td;
}
-static int
-rtems_bsd_thread_start(struct thread **td_ptr, void (*func)(void *), void *arg, int flags, int pages, const char *fmt, va_list ap)
+struct thread *
+rtems_bsd_get_curthread_or_wait_forever(void)
{
- struct thread *td = malloc(sizeof(struct thread), M_TEMP, M_WAITOK | M_ZERO);
+ return rtems_bsd_get_curthread(M_WAITOK);
+}
- if (td != NULL) {
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- rtems_id id = RTEMS_ID_NONE;
- unsigned index = 0;
- char name [5] = "_???";
-
- BSD_ASSERT(pages >= 0);
-
- memset( td, 0, sizeof(struct thread) );
-
- sc = rtems_task_create(
- rtems_build_name('_', 'T', 'S', 'K'),
- BSD_TASK_PRIORITY_NORMAL,
- BSD_MINIMUM_TASK_STACK_SIZE + (size_t) pages * PAGE_SIZE,
- RTEMS_DEFAULT_ATTRIBUTES,
- RTEMS_DEFAULT_ATTRIBUTES,
- &id
- );
- if (sc != RTEMS_SUCCESSFUL) {
- free(td, M_TEMP);
-
- return ENOMEM;
- }
+struct thread *
+rtems_bsd_get_curthread_or_null(void)
+{
+ return rtems_bsd_get_curthread(0);
+}
- td = rtems_bsd_thread_init( id );
- if (!td)
- return ENOMEM;
-
- sc = rtems_task_start(id, (rtems_task_entry) func, (rtems_task_argument) arg);
- if (sc != RTEMS_SUCCESSFUL) {
- rtems_task_delete(id);
- free(td, M_TEMP);
+static bool
+rtems_bsd_is_bsd_thread(Thread_Control *thread)
+{
+ return thread->Object.name.name_u32 == BSD_TASK_NAME;
+}
+
+static bool
+rtems_bsd_extension_thread_create(
+ Thread_Control *executing,
+ Thread_Control *created
+)
+{
+ bool ok = true;
+
+ if (rtems_bsd_is_bsd_thread(created)) {
+ struct thread *td = rtems_bsd_thread_create(created, 0);
- return ENOMEM;
+ ok = td != NULL;
+ if (ok) {
+ rtems_chain_append(&rtems_bsd_thread_chain, &td->td_node);
}
+ }
- td->td_id = id;
- vsnprintf(td->td_name, sizeof(td->td_name), fmt, ap);
- td->td_ucred = crhold(&FIXME_ucred);
+ return ok;
+}
+
+static void
+rtems_bsd_extension_thread_delete(
+ Thread_Control *executing,
+ Thread_Control *deleted
+)
+{
+ struct thread *td = rtems_bsd_get_thread(deleted);
- rtems_chain_append(&rtems_bsd_thread_chain, &td->td_node);
+ if (td != NULL) {
+ seltdfini(td);
- if (td_ptr != NULL) {
- *td_ptr = td;
+ if (rtems_bsd_is_bsd_thread(deleted)) {
+ rtems_chain_explicit_extract(&rtems_bsd_thread_chain, &td->td_node);
}
- return 0;
+ free(td, M_TEMP);
}
-
- return ENOMEM;
}
-static void rtems_bsd_thread_delete(void) __dead2;
+static const rtems_extensions_table rtems_bsd_extensions = {
+ .thread_create = rtems_bsd_extension_thread_create,
+ .thread_delete = rtems_bsd_extension_thread_delete
+};
static void
-rtems_bsd_thread_delete(void)
+rtems_bsd_threads_init(void *arg __unused)
{
- rtems_chain_control *chain = &rtems_bsd_thread_chain;
- rtems_chain_node *node = rtems_chain_first(chain);
- rtems_id id = rtems_task_self();
- struct thread *td = NULL;
+ rtems_id ext_id;
+ rtems_status_code sc;
+
+ sc = rtems_extension_create(
+ BSD_TASK_NAME,
+ &rtems_bsd_extensions,
+ &ext_id
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ BSD_PANIC("cannot create extension");
+ }
- while (!rtems_chain_is_tail(chain, node)) {
- struct thread *cur = (struct thread *) node;
+ rtems_bsd_extension_index = rtems_object_id_get_index(ext_id);
- if (cur->td_id == id) {
- td = cur;
- break;
- }
+ mtx_init(&FIXME_prison.pr_mtx, "prison lock", NULL, MTX_DEF | MTX_DUPOK);
- node = rtems_chain_next(node);
- }
+ FIXME_ucred.cr_prison = &FIXME_prison; /* jail(2) */
+ FIXME_ucred.cr_uidinfo = uifind(0);
+ FIXME_ucred.cr_ruidinfo = uifind(0);
+ FIXME_ucred.cr_ngroups = 1; /* group 0 */
- if (td != NULL) {
- rtems_chain_extract(&td->td_node);
+ FIXME_proc.p_ucred = crhold(&FIXME_ucred);
+ mtx_init(&FIXME_proc.p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK);
+ FIXME_proc.p_pid = getpid();
+ FIXME_proc.p_fibnum = 0;
+ FIXME_proc.p_fd = &FIXME_fd;
+ sx_init_flags(&FIXME_fd.fd_sx, "config SX thread lock", SX_DUPOK);
+}
- free(td, M_TEMP);
+SYSINIT(rtems_bsd_threads, SI_SUB_INTRINSIC, SI_ORDER_ANY, rtems_bsd_threads_init, NULL);
+
+static int
+rtems_bsd_thread_start(struct thread **td_ptr, void (*func)(void *), void *arg, int flags, int pages, const char *fmt, va_list ap)
+{
+ int eno = 0;
+ rtems_status_code sc;
+ rtems_id task_id;
+
+ BSD_ASSERT(pages >= 0);
+
+ sc = rtems_task_create(
+ BSD_TASK_NAME,
+ BSD_TASK_PRIORITY_NORMAL,
+ BSD_MINIMUM_TASK_STACK_SIZE + (size_t) pages * PAGE_SIZE,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &task_id
+ );
+ if (sc == RTEMS_SUCCESSFUL) {
+ struct thread *td = rtems_bsd_get_thread_by_id(task_id);
+
+ BSD_ASSERT(td != NULL);
+
+ vsnprintf(td->td_name, sizeof(td->td_name), fmt, ap);
+
+ sc = rtems_task_start(task_id, (rtems_task_entry) func, (rtems_task_argument) arg);
+ BSD_ASSERT(sc == RTEMS_SUCCESSFUL);
+
+ if (td_ptr != NULL) {
+ *td_ptr = td;
+ }
} else {
- BSD_PANIC("cannot find task entry");
+ eno = ENOMEM;
}
- rtems_task_delete(RTEMS_SELF);
+ return eno;
+}
- while (true) {
- /* Do nothing */
- }
+static __dead2 void
+rtems_bsd_thread_delete(void)
+{
+ rtems_task_delete(RTEMS_SELF);
+ BSD_PANIC("delete self failed");
}
void
diff --git a/testsuite/include/rtems/bsd/test/default-init.h b/testsuite/include/rtems/bsd/test/default-init.h
index 8e0dfc44..09f1f09c 100644
--- a/testsuite/include/rtems/bsd/test/default-init.h
+++ b/testsuite/include/rtems/bsd/test/default-init.h
@@ -41,6 +41,8 @@ rtems_task Init(
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
+
#define CONFIGURE_UNLIMITED_OBJECTS
#define CONFIGURE_UNIFIED_WORK_AREAS
@@ -57,7 +59,6 @@ rtems_task Init(
#include <machine/rtems-bsd-sysinit.h>
-#define CONFIGURE_NEED_NET
/* only include FXP and PCI for i386/pc386 for debug on qemu (for now) */
#if defined(i386)
#define CONFIGURE_NEED_PCIB
diff --git a/testsuite/swi01/init.c b/testsuite/swi01/init.c
index 57d77f80..ee206659 100644
--- a/testsuite/swi01/init.c
+++ b/testsuite/swi01/init.c
@@ -63,6 +63,8 @@ static void Init(rtems_task_argument arg)
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
+
#define CONFIGURE_UNLIMITED_OBJECTS
#define CONFIGURE_UNIFIED_WORK_AREAS
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>
diff --git a/testsuite/timeout01/init.c b/testsuite/timeout01/init.c
index e632bb0a..4afddc70 100644
--- a/testsuite/timeout01/init.c
+++ b/testsuite/timeout01/init.c
@@ -68,6 +68,8 @@ static void Init(rtems_task_argument arg)
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
+
#define CONFIGURE_UNLIMITED_OBJECTS
#define CONFIGURE_UNIFIED_WORK_AREAS
diff --git a/testsuite/usb01/init.c b/testsuite/usb01/init.c
index 517d1544..ed579a14 100644
--- a/testsuite/usb01/init.c
+++ b/testsuite/usb01/init.c
@@ -295,6 +295,8 @@ static void Init(rtems_task_argument arg)
#define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE (WORKER_COUNT * 512)
#define CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS 0
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
+
#define CONFIGURE_UNLIMITED_OBJECTS
#define CONFIGURE_UNIFIED_WORK_AREAS