2012-05-30 20:13:09 +02:00
|
|
|
/*
|
|
|
|
* \brief Userland interface for the management of kernel thread-objects
|
|
|
|
* \author Martin Stein
|
hw: restrict processor broadcast to TLB flushing
Removes the generic processor broadcast function call. By now, that call
was used for cross processor TLB maintance operations only. When core/kernel
gets its memory mapped on demand, and unmapped again, the previous cross
processor flush routine doesn't work anymore, because of a hen-egg problem.
The previous cross processor broadcast is realized using a thread constructed
by core running on top of each processor core. When constructing threads in
core, a dataspace for its thread context is constructed. Each constructed
RAM dataspace gets attached, zeroed out, and detached again. The detach
routine requires a TLB flush operation executed on each processor core.
Instead of executing a thread on each processor core, now a thread waiting
for a global TLB flush is removed from the scheduler queue, and gets attached
to a TLB flush queue of each processor. The processor local queue gets checked
whenever the kernel is entered. The last processor, which executed the TLB
flush, re-attaches the blocked thread to its scheduler queue again.
To ease uo the above described mechanism, a platform thread is now directly
associated with a platform pd object, instead of just associate it with the
kernel pd's id.
Ref #723
2014-04-28 20:36:00 +02:00
|
|
|
* \author Stefan Kalkowski
|
2012-05-30 20:13:09 +02:00
|
|
|
* \date 2012-02-02
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2013-01-10 21:44:47 +01:00
|
|
|
* Copyright (C) 2012-2013 Genode Labs GmbH
|
2012-05-30 20:13:09 +02:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
|
|
* under the terms of the GNU General Public License version 2.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _CORE__INCLUDE__PLATFORM_THREAD_H_
|
|
|
|
#define _CORE__INCLUDE__PLATFORM_THREAD_H_
|
|
|
|
|
|
|
|
/* Genode includes */
|
|
|
|
#include <ram_session/ram_session.h>
|
2012-11-12 17:48:18 +01:00
|
|
|
#include <base/thread.h>
|
2013-11-14 17:29:34 +01:00
|
|
|
|
2016-03-08 16:59:43 +01:00
|
|
|
/* base-internal includes */
|
|
|
|
#include <base/internal/native_utcb.h>
|
|
|
|
|
2012-05-30 20:13:09 +02:00
|
|
|
/* core includes */
|
2013-03-08 11:54:12 +01:00
|
|
|
#include <address_space.h>
|
2015-05-19 14:18:40 +02:00
|
|
|
#include <object.h>
|
|
|
|
|
2016-06-16 15:55:36 +02:00
|
|
|
/* kernel includes */
|
2015-05-19 14:18:40 +02:00
|
|
|
#include <kernel/core_interface.h>
|
2013-11-14 17:29:34 +01:00
|
|
|
#include <kernel/thread.h>
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
namespace Genode {
|
|
|
|
|
|
|
|
class Pager_object;
|
|
|
|
class Thread_state;
|
|
|
|
class Rm_client;
|
|
|
|
class Platform_thread;
|
2014-04-28 21:31:57 +02:00
|
|
|
class Platform_pd;
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Userland interface for the management of kernel thread-objects
|
|
|
|
*/
|
2015-05-19 14:18:40 +02:00
|
|
|
class Platform_thread : public Kernel_object<Kernel::Thread>
|
2012-05-30 20:13:09 +02:00
|
|
|
{
|
2013-11-18 15:31:54 +01:00
|
|
|
enum { LABEL_MAX_LEN = 32 };
|
2012-05-30 20:13:09 +02:00
|
|
|
|
2015-05-19 14:18:40 +02:00
|
|
|
Platform_pd * _pd;
|
|
|
|
Weak_ptr<Address_space> _address_space;
|
2015-06-26 15:05:28 +02:00
|
|
|
Pager_object * _pager;
|
2015-05-19 14:18:40 +02:00
|
|
|
Native_utcb * _utcb_core_addr; /* UTCB addr in core */
|
|
|
|
Native_utcb * _utcb_pd_addr; /* UTCB addr in pd */
|
|
|
|
Ram_dataspace_capability _utcb; /* UTCB dataspace */
|
|
|
|
char _label[LABEL_MAX_LEN];
|
2012-05-30 20:13:09 +02:00
|
|
|
|
2013-06-06 17:02:22 +02:00
|
|
|
/*
|
|
|
|
* Wether this thread is the main thread of a program.
|
|
|
|
* This should be used only after 'join_pd' was called
|
|
|
|
* or if this is a core thread. For core threads its save
|
|
|
|
* also without 'join_pd' because '_main_thread' is initialized
|
|
|
|
* with 0 wich is always true as cores main thread has no
|
|
|
|
* 'Platform_thread'.
|
|
|
|
*/
|
|
|
|
bool _main_thread;
|
|
|
|
|
2014-03-06 14:30:37 +01:00
|
|
|
Affinity::Location _location;
|
|
|
|
|
2012-05-30 20:13:09 +02:00
|
|
|
/**
|
|
|
|
* Common construction part
|
|
|
|
*/
|
|
|
|
void _init();
|
|
|
|
|
2012-10-09 15:41:40 +02:00
|
|
|
/*
|
|
|
|
* Check if this thread will attach its UTCB by itself
|
|
|
|
*/
|
|
|
|
bool _attaches_utcb_by_itself();
|
|
|
|
|
2015-05-19 14:18:40 +02:00
|
|
|
unsigned _priority(unsigned virt_prio)
|
|
|
|
{
|
2015-06-29 13:30:35 +02:00
|
|
|
return Cpu_session::scale_priority(Kernel::Cpu_priority::MAX,
|
2015-05-19 14:18:40 +02:00
|
|
|
virt_prio);
|
|
|
|
}
|
|
|
|
|
2012-05-30 20:13:09 +02:00
|
|
|
public:
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor for core threads
|
2013-11-18 15:31:54 +01:00
|
|
|
*
|
2013-11-20 23:35:02 +01:00
|
|
|
* \param label debugging label
|
2014-04-28 21:31:57 +02:00
|
|
|
* \param utcb virtual address of UTCB within core
|
2012-05-30 20:13:09 +02:00
|
|
|
*/
|
2014-04-28 21:31:57 +02:00
|
|
|
Platform_thread(const char * const label, Native_utcb * utcb);
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor for threads outside of core
|
2013-11-18 15:31:54 +01:00
|
|
|
*
|
2014-10-16 11:15:46 +02:00
|
|
|
* \param quota CPU quota that shall be granted to the thread
|
2013-11-20 23:35:02 +01:00
|
|
|
* \param label debugging label
|
|
|
|
* \param virt_prio unscaled processor-scheduling priority
|
2016-01-23 14:42:55 +01:00
|
|
|
* \param utcb core local pointer to userland stack
|
2012-05-30 20:13:09 +02:00
|
|
|
*/
|
2014-10-16 11:15:46 +02:00
|
|
|
Platform_thread(size_t const quota, const char * const label,
|
2016-04-20 21:12:57 +02:00
|
|
|
unsigned const virt_prio, Affinity::Location,
|
|
|
|
addr_t const utcb);
|
2012-05-30 20:13:09 +02:00
|
|
|
|
2012-10-09 15:41:40 +02:00
|
|
|
/**
|
|
|
|
* Destructor
|
|
|
|
*/
|
|
|
|
~Platform_thread();
|
|
|
|
|
2012-05-30 20:13:09 +02:00
|
|
|
/**
|
2013-11-18 15:31:54 +01:00
|
|
|
* Join a protection domain
|
2012-05-30 20:13:09 +02:00
|
|
|
*
|
hw: restrict processor broadcast to TLB flushing
Removes the generic processor broadcast function call. By now, that call
was used for cross processor TLB maintance operations only. When core/kernel
gets its memory mapped on demand, and unmapped again, the previous cross
processor flush routine doesn't work anymore, because of a hen-egg problem.
The previous cross processor broadcast is realized using a thread constructed
by core running on top of each processor core. When constructing threads in
core, a dataspace for its thread context is constructed. Each constructed
RAM dataspace gets attached, zeroed out, and detached again. The detach
routine requires a TLB flush operation executed on each processor core.
Instead of executing a thread on each processor core, now a thread waiting
for a global TLB flush is removed from the scheduler queue, and gets attached
to a TLB flush queue of each processor. The processor local queue gets checked
whenever the kernel is entered. The last processor, which executed the TLB
flush, re-attaches the blocked thread to its scheduler queue again.
To ease uo the above described mechanism, a platform thread is now directly
associated with a platform pd object, instead of just associate it with the
kernel pd's id.
Ref #723
2014-04-28 20:36:00 +02:00
|
|
|
* \param pd platform pd object pointer
|
2013-11-18 15:31:54 +01:00
|
|
|
* \param main_thread wether thread is the first in protection domain
|
|
|
|
* \param address_space corresponding Genode address space
|
2012-05-30 20:13:09 +02:00
|
|
|
*
|
2016-04-14 16:29:07 +02:00
|
|
|
* This function has no effect when called more twice for a
|
|
|
|
* given thread.
|
2012-05-30 20:13:09 +02:00
|
|
|
*/
|
2016-04-14 16:29:07 +02:00
|
|
|
void join_pd(Platform_pd * const pd, bool const main_thread,
|
|
|
|
Weak_ptr<Address_space> address_space);
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Run this thread
|
2013-11-18 12:47:14 +01:00
|
|
|
*
|
2014-03-06 14:30:37 +01:00
|
|
|
* \param ip initial instruction pointer
|
|
|
|
* \param sp initial stack pointer
|
2012-05-30 20:13:09 +02:00
|
|
|
*/
|
2014-03-06 14:30:37 +01:00
|
|
|
int start(void * const ip, void * const sp);
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Pause this thread
|
|
|
|
*/
|
2015-05-19 14:18:40 +02:00
|
|
|
void pause() { Kernel::pause_thread(kernel_object()); }
|
2012-05-30 20:13:09 +02:00
|
|
|
|
2016-03-30 15:34:37 +02:00
|
|
|
/**
|
|
|
|
* Enable/disable single stepping
|
|
|
|
*/
|
|
|
|
void single_step(bool) { }
|
|
|
|
|
2012-05-30 20:13:09 +02:00
|
|
|
/**
|
|
|
|
* Resume this thread
|
|
|
|
*/
|
2015-05-19 14:18:40 +02:00
|
|
|
void resume() { Kernel::resume_thread(kernel_object()); }
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Cancel currently blocking operation
|
|
|
|
*/
|
2012-12-19 16:22:43 +01:00
|
|
|
void cancel_blocking() { resume(); }
|
2012-05-30 20:13:09 +02:00
|
|
|
|
2015-03-27 14:05:55 +01:00
|
|
|
/**
|
|
|
|
* Set CPU quota of the thread to 'quota'
|
|
|
|
*/
|
|
|
|
void quota(size_t const quota);
|
|
|
|
|
2012-05-30 20:13:09 +02:00
|
|
|
/**
|
2012-11-12 17:48:18 +01:00
|
|
|
* Get raw thread state
|
2012-05-30 20:13:09 +02:00
|
|
|
*/
|
2013-11-11 13:03:07 +01:00
|
|
|
Thread_state state();
|
2012-11-12 17:48:18 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Override raw thread state
|
|
|
|
*/
|
2013-11-11 13:03:07 +01:00
|
|
|
void state(Thread_state s);
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return unique identification of this thread as faulter
|
|
|
|
*/
|
2015-02-06 17:23:41 +01:00
|
|
|
unsigned long pager_object_badge() { return (unsigned long)this; }
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
/**
|
2012-09-04 17:32:55 +02:00
|
|
|
* Set the executing CPU for this thread
|
2014-03-06 14:30:37 +01:00
|
|
|
*
|
|
|
|
* \param location targeted location in affinity space
|
2012-05-30 20:13:09 +02:00
|
|
|
*/
|
2014-03-06 14:30:37 +01:00
|
|
|
void affinity(Affinity::Location const & location);
|
2012-05-30 20:13:09 +02:00
|
|
|
|
2013-07-09 15:58:06 +02:00
|
|
|
/**
|
|
|
|
* Get the executing CPU for this thread
|
|
|
|
*/
|
2014-03-06 14:30:37 +01:00
|
|
|
Affinity::Location affinity() const;
|
2013-07-09 15:58:06 +02:00
|
|
|
|
2013-03-08 11:54:12 +01:00
|
|
|
/**
|
|
|
|
* Return the address space to which the thread is bound
|
|
|
|
*/
|
2015-09-02 10:05:35 +02:00
|
|
|
Weak_ptr<Address_space>& address_space();
|
2013-03-08 11:54:12 +01:00
|
|
|
|
2015-06-11 23:05:02 +02:00
|
|
|
/**
|
|
|
|
* Return execution time consumed by the thread
|
|
|
|
*/
|
|
|
|
unsigned long long execution_time() const { return 0; }
|
|
|
|
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
/***************
|
|
|
|
** Accessors **
|
|
|
|
***************/
|
|
|
|
|
2015-03-10 12:06:55 +01:00
|
|
|
char const * label() const { return _label; };
|
|
|
|
|
2012-05-30 20:13:09 +02:00
|
|
|
void pager(Pager_object * const pager);
|
|
|
|
|
2013-02-05 15:38:06 +01:00
|
|
|
Pager_object * pager();
|
2012-05-30 20:13:09 +02:00
|
|
|
|
hw: restrict processor broadcast to TLB flushing
Removes the generic processor broadcast function call. By now, that call
was used for cross processor TLB maintance operations only. When core/kernel
gets its memory mapped on demand, and unmapped again, the previous cross
processor flush routine doesn't work anymore, because of a hen-egg problem.
The previous cross processor broadcast is realized using a thread constructed
by core running on top of each processor core. When constructing threads in
core, a dataspace for its thread context is constructed. Each constructed
RAM dataspace gets attached, zeroed out, and detached again. The detach
routine requires a TLB flush operation executed on each processor core.
Instead of executing a thread on each processor core, now a thread waiting
for a global TLB flush is removed from the scheduler queue, and gets attached
to a TLB flush queue of each processor. The processor local queue gets checked
whenever the kernel is entered. The last processor, which executed the TLB
flush, re-attaches the blocked thread to its scheduler queue again.
To ease uo the above described mechanism, a platform thread is now directly
associated with a platform pd object, instead of just associate it with the
kernel pd's id.
Ref #723
2014-04-28 20:36:00 +02:00
|
|
|
Platform_pd * pd() const { return _pd; }
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
Ram_dataspace_capability utcb() const { return _utcb; }
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* _CORE__INCLUDE__PLATFORM_THREAD_H_ */
|