From ab415f95a9ee784f0aa2131d237455ed6aad2dde Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 9 Oct 2013 08:56:49 +0200 Subject: Use extension to attach a struct thread to threads Add test thread01. --- Makefile | 12 + freebsd-to-rtems.py | 1 + freebsd/sys/dev/usb/usb_process.c | 8 +- freebsd/sys/dev/usb/usb_process.h | 4 - freebsd/sys/kern/kern_intr.c | 3 +- freebsd/sys/sys/pcpu.h | 5 - freebsd/sys/sys/proc.h | 9 +- rtemsbsd/include/machine/pcpu.h | 42 +++- rtemsbsd/include/machine/rtems-bsd-config.h.in | 13 - rtemsbsd/include/machine/rtems-bsd-thread.h | 73 ++++++ rtemsbsd/rtems/rtems-bsd-init-with-irq.c | 5 +- rtemsbsd/rtems/rtems-bsd-init.c | 1 + rtemsbsd/rtems/rtems-bsd-mutex.c | 1 + rtemsbsd/rtems/rtems-bsd-panic.c | 18 +- rtemsbsd/rtems/rtems-bsd-shell.c | 15 +- rtemsbsd/rtems/rtems-bsd-thread.c | 319 ++++++++++++------------ testsuite/include/rtems/bsd/test/default-init.h | 3 +- testsuite/swi01/init.c | 2 + testsuite/thread01/test_main.c | 304 ++++++++++++++++++++++ testsuite/timeout01/init.c | 2 + testsuite/usb01/init.c | 2 + 21 files changed, 625 insertions(+), 217 deletions(-) create mode 100644 rtemsbsd/include/machine/rtems-bsd-thread.h create mode 100644 testsuite/thread01/test_main.c 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 #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 * * - * 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 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 + * + * + * 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 +#include +#include + +#include + +#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 * @@ -38,6 +38,7 @@ */ #include +#include #include 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 +#include #include #include 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 +#include #include #include 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 * @@ -38,6 +38,7 @@ */ #include +#include #include #include @@ -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 * @@ -38,6 +38,7 @@ */ #include +#include #include #include @@ -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 * @@ -38,225 +38,238 @@ */ #include +#include #include #include #include +#include #include #include #include -#include -#include +#include +#include #include #include -#include + +#include +#include 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 -#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 + * + * + * 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 + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#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 = ≺ + + 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 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 -- cgit v1.2.3