summaryrefslogtreecommitdiffstats
path: root/rtems/freebsd/rtems/rtems-bsd-thread.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@oarcorp.com>2012-03-07 09:52:04 -0600
committerJoel Sherrill <joel.sherrill@oarcorp.com>2012-03-07 09:52:04 -0600
commita9153ec3040f54fa52b68e14dafed2aba7b780ae (patch)
treefda80e3380dfebf7d97868507aa185757852e882 /rtems/freebsd/rtems/rtems-bsd-thread.c
downloadrtems-libbsd-a9153ec3040f54fa52b68e14dafed2aba7b780ae.tar.bz2
Initial import
Code is based on FreeBSD 8.2 with USB support from Sebastian Huber and Thomas Doerfler. Initial TCP/IP stack work is from Kevel Kirspel.
Diffstat (limited to 'rtems/freebsd/rtems/rtems-bsd-thread.c')
-rw-r--r--rtems/freebsd/rtems/rtems-bsd-thread.c208
1 files changed, 208 insertions, 0 deletions
diff --git a/rtems/freebsd/rtems/rtems-bsd-thread.c b/rtems/freebsd/rtems/rtems-bsd-thread.c
new file mode 100644
index 00000000..92bf79c0
--- /dev/null
+++ b/rtems/freebsd/rtems/rtems-bsd-thread.c
@@ -0,0 +1,208 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_bsd_rtems
+ *
+ * @brief TODO.
+ */
+
+/*
+ * Copyright (c) 2009, 2010 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 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.
+ */
+
+#include <rtems/freebsd/machine/rtems-bsd-config.h>
+
+#include <rtems/freebsd/sys/param.h>
+#include <rtems/freebsd/sys/types.h>
+#include <rtems/freebsd/sys/systm.h>
+#include <rtems/freebsd/sys/proc.h>
+#include <rtems/freebsd/sys/kthread.h>
+#include <rtems/freebsd/sys/malloc.h>
+
+RTEMS_CHAIN_DEFINE_EMPTY(rtems_bsd_thread_chain);
+
+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 proc *p = &proc0;;
+ struct thread *td = malloc(sizeof(struct thread), M_TEMP, M_WAITOK | M_ZERO);
+
+ 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);
+
+ 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;
+ }
+
+ sc = rtems_task_set_note( id, RTEMS_NOTEPAD_0, ( uint32_t )td );
+ if (sc != RTEMS_SUCCESSFUL) {
+ free(td, M_TEMP);
+
+ return ENOMEM;
+ }
+
+ 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) {
+ rtems_task_delete(id);
+ free(td, M_TEMP);
+
+ 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);
+
+ return ENOMEM;
+ }
+
+ td->td_id = id;
+ vsnprintf(td->td_name, sizeof(td->td_name), fmt, ap);
+ bzero(&td->td_ru, sizeof(td->td_ru));
+ td->td_ucred = crhold(p->p_ucred);
+ td->td_proc = p;
+
+ rtems_chain_append(&rtems_bsd_thread_chain, &td->td_node);
+
+ if (td_ptr != NULL) {
+ *td_ptr = td;
+ }
+
+ return 0;
+ }
+
+ return ENOMEM;
+}
+
+static void rtems_bsd_thread_delete(void) __dead2;
+
+static void
+rtems_bsd_thread_delete(void)
+{
+ 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;
+
+ while (!rtems_chain_is_tail(chain, node)) {
+ struct thread *cur = (struct thread *) node;
+
+ if (cur->td_id == id) {
+ td = cur;
+ break;
+ }
+
+ node = rtems_chain_next(node);
+ }
+
+ if (td != NULL) {
+ rtems_chain_extract(&td->td_node);
+
+ free(td, M_TEMP);
+ } else {
+ BSD_PANIC("cannot find task entry");
+ }
+
+ rtems_task_delete(RTEMS_SELF);
+
+ while (true) {
+ /* Do nothing */
+ }
+}
+
+void
+kproc_start(const void *udata)
+{
+ const struct kproc_desc *pd = udata;
+ int eno = kproc_create((void (*)(void *))pd->func, NULL, pd->global_procpp, 0, 0, "%s", pd->arg0);
+
+ BSD_ASSERT(eno == 0);
+}
+
+int
+kproc_create(void (*func)(void *), void *arg, struct proc **newpp, int flags, int pages, const char *fmt, ...)
+{
+ int eno = 0;
+ va_list ap;
+
+ va_start(ap, fmt);
+ eno = rtems_bsd_thread_start(newpp, func, arg, flags, pages, fmt, ap);
+ va_end(ap);
+
+ return eno;
+}
+
+void
+kproc_exit(int ecode)
+{
+ rtems_bsd_thread_delete();
+}
+
+void
+kthread_start(const void *udata)
+{
+ const struct kthread_desc *td = udata;
+ int eno = kthread_add((void (*)(void *)) td->func, NULL, NULL, td->global_threadpp, 0, 0, "%s", td->arg0);
+
+ BSD_ASSERT(eno == 0);
+}
+
+int
+kthread_add(void (*func)(void *), void *arg, struct proc *p, struct thread **newtdp, int flags, int pages, const char *fmt, ...)
+{
+ int eno = 0;
+ va_list ap;
+
+ va_start(ap, fmt);
+ eno = rtems_bsd_thread_start(newtdp, func, arg, flags, pages, fmt, ap);
+ va_end(ap);
+
+ return eno;
+}
+
+void
+kthread_exit(void)
+{
+ rtems_bsd_thread_delete();
+}
+
+int
+kproc_kthread_add(void (*func)(void *), void *arg, struct proc **procptr, struct thread **tdptr, int flags, int pages, const char * procname, const char *fmt, ...)
+{
+ int eno = 0;
+ va_list ap;
+
+ va_start(ap, fmt);
+ eno = rtems_bsd_thread_start(tdptr, func, arg, flags, pages, fmt, ap);
+ va_end(ap);
+
+ return eno;
+}