genode/base-hw/src/core/kernel/processor_pool.h

132 lines
2.6 KiB
C++

/*
* \brief Provide a processor object for every available processor
* \author Martin Stein
* \author Stefan Kalkowski
* \date 2014-01-14
*/
/*
* Copyright (C) 2014 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.
*/
#ifndef _KERNEL__PROCESSOR_POOL_H_
#define _KERNEL__PROCESSOR_POOL_H_
/* base includes */
#include <unmanaged_singleton.h>
/* core includes */
#include <kernel/kernel.h>
#include <kernel/thread.h>
namespace Kernel
{
/**
* Thread that consumes processor time if no other thread is available
*/
class Idle_thread;
/**
* Provides a processor object for every available processor
*/
class Processor_pool;
/**
* Return Processor_pool singleton
*/
Processor_pool * processor_pool();
}
class Kernel::Idle_thread : public Thread
{
private:
enum {
STACK_SIZE = sizeof(addr_t) * 32,
STACK_ALIGNM = Processor_driver::DATA_ACCESS_ALIGNM,
};
char _stack[STACK_SIZE] __attribute__((aligned(STACK_ALIGNM)));
/**
* Main function of all idle threads
*/
static void _main()
{
while (1) { Processor_driver::wait_for_interrupt(); }
}
public:
/**
* Constructor
*
* \param processor kernel object of targeted processor
*/
Idle_thread(Processor * const processor)
:
Thread(Priority::MAX, "idle")
{
ip = (addr_t)&_main;
sp = (addr_t)&_stack[STACK_SIZE];
init(processor, core_pd(), 0, 0);
}
};
class Kernel::Processor_pool
{
private:
char _processors[PROCESSORS][sizeof(Processor)];
char _idle_threads[PROCESSORS][sizeof(Idle_thread)];
/**
* Return idle thread of a specific processor
*
* \param processor_id kernel name of the targeted processor
*/
Idle_thread * _idle_thread(unsigned const processor_id) const
{
char * const p = const_cast<char *>(_idle_threads[processor_id]);
return reinterpret_cast<Idle_thread *>(p);
}
public:
/**
* Constructor
*/
Processor_pool()
{
for (unsigned i = 0; i < PROCESSORS; i++) {
new (_idle_threads[i]) Idle_thread(processor(i));
new (_processors[i]) Processor(i, _idle_thread(i));
}
}
/**
* Return the object of a specific processor
*
* \param id kernel name of the targeted processor
*/
Processor * processor(unsigned const id) const
{
assert(id < PROCESSORS);
char * const p = const_cast<char *>(_processors[id]);
return reinterpret_cast<Processor *>(p);
}
/**
* Return the object of the primary processor
*/
Processor * primary_processor() const
{
return processor(Processor::primary_id());
}
};
#endif /* _KERNEL__PROCESSOR_POOL_H_ */