mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-22 13:02:56 +01:00
Imported Genode release 11.11
This commit is contained in:
committed by
Christian Helmuth
parent
6bcc9aef0e
commit
da4e1feaa5
121
base-codezero/src/core/thread_start.cc
Normal file
121
base-codezero/src/core/thread_start.cc
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* \brief Implementation of Thread API interface for core
|
||||
* \author Norman Feske
|
||||
* \date 2006-05-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2011 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform.h>
|
||||
#include <platform_thread.h>
|
||||
|
||||
enum { verbose_thread_start = true };
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread() { }
|
||||
|
||||
|
||||
void Thread_base::_deinit_platform_thread() { }
|
||||
|
||||
|
||||
/**
|
||||
* Create and start new thread
|
||||
*
|
||||
* \param space_no space ID in which the new thread will be executed
|
||||
* \param sp initial stack pointer
|
||||
* \param ip initial instruction pointer
|
||||
* \return new thread ID, or
|
||||
* negative error code
|
||||
*/
|
||||
inline int create_thread(int space_no,
|
||||
void *sp, void *ip,
|
||||
int pager_tid = 1)
|
||||
{
|
||||
using namespace Codezero;
|
||||
|
||||
struct task_ids ids = { 1, space_no, TASK_ID_INVALID };
|
||||
|
||||
/* allocate new thread at the kernel */
|
||||
unsigned long flags = THREAD_CREATE | TC_SHARE_SPACE | TC_SHARE_GROUP;
|
||||
int ret = l4_thread_control(flags, &ids);
|
||||
if (ret < 0) {
|
||||
PERR("l4_thread_control returned %d, spid=%d\n",
|
||||
ret, ids.spid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned long utcb_base_addr = (unsigned long)l4_get_utcb();
|
||||
|
||||
/* calculate utcb address of new thread */
|
||||
unsigned long new_utcb = utcb_base_addr + ids.tid*sizeof(struct utcb);
|
||||
|
||||
/* setup thread context */
|
||||
struct exregs_data exregs;
|
||||
exregs_set_stack(&exregs, (unsigned long)sp);
|
||||
exregs_set_pc (&exregs, (unsigned long)ip);
|
||||
exregs_set_pager(&exregs, pager_tid);
|
||||
exregs_set_utcb (&exregs, new_utcb);
|
||||
|
||||
ret = l4_exchange_registers(&exregs, ids.tid);
|
||||
if (ret < 0) {
|
||||
printf("l4_exchange_registers returned ret=%d\n", ret);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* start execution */
|
||||
ret = l4_thread_control(THREAD_RUN, &ids);
|
||||
if (ret < 0) {
|
||||
printf("Error: l4_thread_control(THREAD_RUN) returned %d\n", ret);
|
||||
return -3;
|
||||
}
|
||||
|
||||
/* return new thread ID allocated by the kernel */
|
||||
return ids.tid;
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_thread_start()
|
||||
{
|
||||
Thread_base::myself()->_thread_bootstrap();
|
||||
Thread_base::myself()->entry();
|
||||
sleep_forever();
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::start()
|
||||
{
|
||||
/* create and start platform thread */
|
||||
_tid.pt = new(platform()->core_mem_alloc()) Platform_thread(_context->name);
|
||||
|
||||
_tid.l4id = create_thread(1, &_context->stack[-4], (void *)&_thread_start);
|
||||
if (_tid.l4id.tid < 0)
|
||||
PERR("create_thread returned %d", _tid.l4id.tid);
|
||||
|
||||
if (verbose_thread_start)
|
||||
printf("core started local thread \"%s\" with ID %d\n",
|
||||
_context->name, _tid.l4id.tid);
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::cancel_blocking()
|
||||
{
|
||||
PWRN("not implemented");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user