The processor pool wrapper is defined as follows
<Off processor table for users. >=
class off_uProcTbl : public off_uHWCompResource {
public:
off_uProcessor *alloc(off_Protection *prot,
natural_t n=1, off_proc_id_t at=OFF_EU_ID_NULL);
void free(off_uProcessor *pf, const off_Rights &r, natural_t n=1 );
off_uProcessor *fetch(off_proc_id_t d,const off_Rights &r) const;
};
Definesoff_uProcTbl(links are to index).
Processors for users also include a few methods coming from trap and interrupt tables.
<Off processor for users. >=
ENTRY class off_uProcessor : public off_uHWResUnit {
// Installs a new shuttle
void switch_to(off_shtl_id_t &new,
const off_Rights &proc_r, const off_Rights &shtl_r);
// Executes a run queue
void run(off_shtl_id_t s[], natural_t n,
const off_Rights &proc_r, const off_Rights &shtl_r[]);
// Arranges for the processor to notify the owner on this events
void notify( off_sevent_t events, off_prtl_id_t sched,
const off_Rights &proc_t);
// Returns the current shuttle
off_shtl_id_t self(const off_Rights &proc_r);
off_uTrap *alloc_trap(off_Protection *prot,
natural_t n=1, off_ev_id_t at=OFF_EU_ID_NULL);
void free_trap(off_uTrap *t, const off_Rights &r, natural_t n=1 );
off_uTrap *fetch_trap(off_ev_id_t t,const off_Rights &r) const;
off_uIrq *alloc_irq(off_Protection *prot,
natural_t n=1, off_ev_id_t at=OFF_EU_ID_NULL);
void free_irq(off_uIrq *t, const off_Rights &r, natural_t n=1 );
off_uIrq *fetch_irq(off_ev_id_t t,const off_Rights &r) const;
};
Definesoff_uProcessor(links are to index).
\subsection{Processors \cpp{} source files}
Processor code is kept in hw/Processor.h and hw/Processor.C.
<Processor.h*>= <Read the literate code instead warning. > #ifndef __OFF_PROCESSOR_H #define __OFF_PROCESSOR_H 1 <Off processor dependencies. > #ifdef __KERNEL__ <Off processor registers. > <Off processor. > #endif // __KERNEL__ <Off processor late dependencies. > #ifdef __KERNEL__ <off_Processor::get_allocatorimplementation. > <off_Processor::get_trapsandget_irqsimplementation. > <off_Processor::get_trapandget_irqimplementation. > <off_Processor::clistiis_cliandhltimplementation. > <off_Processor::operator+implementation. > #endif // __KERNEL__ #endif // __OFF_PROCESSOR_H
<Processor.C*>= <Read the literate code instead warning. > #include <hw/Processor.h> // Exported interface. <Off processor implementation dependencies. > <Off processor static members. > <off_Processor::selfimplementation. > <off_Processor::startimplementation. > <off_Processor::allocandfreeimplementation. > <off_Processor::start_clkimplementation. > <off_Processor::new_quantumimplementation. > <off_Processor::operator=implementation. > <off_Processor::nameofimplementation. > <off_Processor::get_urlimplementation. > <off_Processor::restore_stateimplementation. > <off_Processor::cleanupimplementation. > <off_Processor::copy_stateimplementation. > <off_Processor::freeze_stateimplementation. > <off_Processor::melt_stateimplementation. > <off_Processor::can_meltimplementation. > <off_Processor::get_currentimplementation. >
Run queue slots are found in RunqSlot.h and RunqSlot.C.
<RunqSlot.h*>= <Read the literate code instead warning. > #ifndef __OFF_RUNQ_SLOT_H #define __OFF_RUNQ_SLOT_H 1 <Off run queue slot dependencies. > #ifdef __KERNEL__ <Off run queue slot. > #endif // __KERNEL__ #ifdef __KERNEL__ <off_RunqSlot::get_shtlandset_shtlimplementation. > #endif // __KERNEL__ #endif // __OFF_RUNQ_SLOT_H
<RunqSlot.C*>= <Read the literate code instead warning. > #include <hw/RunqSlot.h> // Exported interface. <Off run queue slot implementation dependencies. > <Off run queue slot static members. > <off_RunqSlot::get_url_holderimplementation. > <off_RunqSlot::get_rurlimplementation. > <off_RunqSlot::off_RunqSlotimplementation. > <off_RunqSlot::operator newimplementation. > <off_RunqSlot::operator deleteimplementation. > <off_RunqSlot::copy_stateimplementation. > <off_RunqSlot::restore_stateimplementation. >
Run queue slot allocation is kept in RqAllocator.h and
RqAllocator.C.
<RqAllocator.h*>=
<Read the literate code instead warning. >
#ifndef __OFF_RQ_ALLOCATOR_H
#define __OFF_RQ_ALLOCATOR_H 1
<Off time slice allocator dependencies. >
#ifdef __KERNEL__
<Off linkable run queue slot. >
<Off time slice allocator. >
#endif // __KERNEL__
#ifdef __KERNEL__
<off_RqAllocator::operator + implementation. >
#endif // __KERNEL__
#endif // __OFF_RQ_ALLOCATOR_H
<RqAllocator.C*>=
<Read the literate code instead warning. >
#include <hw/RqAllocator.h> // Exported interface.
<Off time slice allocator static members. >
<off_RqAllocator::off_RqAllocator implementation. >
\subsection{Processors for ix86 based architectures}
Machine dependent processors are structures used to perform machine
dependent tasks needed to implement the Processor abstraction
described before. Most of its methods are simple wrappers for OSKit
or native functions.
<Off machine dependent processor. >= (U->)
// A processor for ix86 machines.
//
class off_mdepProcessor {
public:
// Inhibits interrupts.
static void clri(void) { cli(); }
// Enables interrupts.
static void seti(void) { sti(); }
// Are interrupts enabled?
static boolean_t has_clri(void) {
return !(get_eflags() & EFL_IF);
}
// Halts the processor.
static void halt(void) { __asm__ __volatile__("hlt ; hlt ; hlt ; hlt"); }
<Other public methods of off_mdepProcessor. >
private:
<Other private members of off_mdepProcessor. >
};
Definesoff_mdepProcessor(links are to index).
<Off machine dependent processor dependencies. >= (U->) [D->] #include <flux/types.h> // for boolean_t natural_t et al. #include <flux/machine/proc_reg.h> // for cli, sti et al. #include <flux/machine/eflags.h> // for EFL_IF et al.
Machine dependent processors are created from the processor number, which is kept in a private member.
<Other public methods of off_mdepProcessor. >= (<-U) [D->]
// Creates a machine dependent processor.
off_mdepProcessor(natural_t nb=0);
<off_mdepProcessor::off_mdepProcessor implementation. >= (U->)
// Creates a machine dependent processor.
off_mdepProcessor::off_mdepProcessor(natural_t nb) : p_nb(nb) {;}
<Other private members of off_mdepProcessor. >= (<-U) [D->]
natural_t p_nb;
Non boot processors are really started only after start is called.
<Other public methods of off_mdepProcessor. >+= (<-U) [<-D->]
// Starts the processor.
void start( off_mdepShtl *s);
<Off machine dependent processor dependencies. >+= (U->) [<-D->] class off_mdepShtl;
<Off machine dependent processor implementation dependencies. >= (U->) #include <shtl/mdep/mShtl.h> // for off_mdepShtl
<off_mdepProcessor::start implementation. >= (U->)
// Starts the processor.
void off_mdepProcessor::start( off_mdepShtl *s)
{
if (s!=NULL) {
smp_start_cpu(p_nb,0,(void*)s,0); // XXX use run_idle and shuttle stack.
}
}
The number of installed processors can be obtained with
<Other public methods of off_mdepProcessor. >+= (<-U) [<-D->]
// # of processors on intels.
static natural_t how_many(void);
<off_mdepProcessor::how_many implementation. >= (U->)
// # of processors on intels.
natural_t off_mdepProcessor::how_many(void)
{
<Initialize global machine dependent processor state. >
return smp_get_num_cpus();
}
Before using smp_get_num_cpus we might want to initialize
low-level SMP support.
<Initialize global machine dependent processor state. >= (<-U)
static boolean_t initialized=FALSE;
if (!initialized){
p_hassmp=(smp_initialize()>0);
initialized=TRUE;
}
where we record in p_hassmp whether this system has SMP or not.
<Other private members of off_mdepProcessor. >+= (<-U) [<-D]
static boolean_t p_hassmp; // Do we have SMP?
<Off machine dependent processor static members. >= (U->) boolean_t off_mdepProcessor::p_hassmp=FALSE; // Do we have SMP?
The implementation of self differs for SMP and non SMP
kernels. On SMP kernels, self obtains the processor id from the APIC
and uses that is as an index into the node pool of processors. On non
SMP kernel the node contains a single Processor instance and
self returns a pointer to it.
We use get_proc_id to get either the processor id or zero
depending on existing SMP support.
<Other public methods of off_mdepProcessor. >+= (<-U) [<-D]
// Return the processor id as said by the APIC.
static inline natural_t get_proc_id(void);
<off_mdepProcessor::get_proc_id implementation. >= (U->)
// Return the processor id as said by the APIC.
extern inline natural_t off_mdepProcessor::get_proc_id(void)
{
return smp_find_cur_cpu();
}
<Off machine dependent processor dependencies. >+= (U->) [<-D->] #include <flux/smp/smp.h> // for smp_find_cur_cpu et al.
\subsubsection{Processor registers for ix86 based architectures}
On Intels, we define the processor register set so that it matches the stack frame saved on traps and interrupts. In that way we can create register sets from a saved trap frame.
<Off machine dependent processor registers. >= (U->)
// Processor registers for ix86s
//
struct off_mdepProcRegs {
struct trap_state p_ts; // ix86 registers matching a trap stack frame.
// Creates a set of processor registers.
off_mdepProcRegs(void){ assert(sizeof(p_ts)==sizeof(off_mdepProcRegs)); }
// Set or get the PC/SP/EFLAGS.
void set_pc(register_t pc) { p_ts.eip = pc; }
void set_sp(register_t sp) { p_ts.esp = sp; }
void set_flags(register_t f) { p_ts.eflags = f; }
register_t get_pc(void) const { return p_ts.eip; }
register_t get_sp(void) const { return p_ts.esp; }
register_t get_flags(void) const { return p_ts.eflags; }
};
Definesoff_mdepProcRegs(links are to index).
<Off machine dependent processor dependencies. >+= (U->) [<-D] #include <flux/machine/base_trap.h> // for struct trap_state et al.
\subsubsection{Processors for ix86 based architectures \cpp{} source files}
Machine dependent processor code is kept in mdep/mProcessor.h and
mdep/mProcessor.C.
<mdep mProcessor.h*>=
<Read the literate code instead warning. >
#ifndef __OFF_MDEP_PROCESSOR_H
#define __OFF_MDEP_PROCESSOR_H 1
<Off machine dependent processor dependencies. >
#ifdef __KERNEL__
<Off machine dependent processor registers. >
<Off machine dependent processor. >
#endif // __KERNEL__
#ifdef __KERNEL__
<off_mdepProcessor::get_proc_id implementation. >
#endif // __KERNEL__
#endif // __OFF_MDEP_PROCESSOR_H
<mdep mProcessor.C*>= <Read the literate code instead warning. > #include <hw/mdep/mProcessor.h> // Exported interface. <Off machine dependent processor implementation dependencies. > <Off machine dependent processor static members. > <off_mdepProcessor::how_manyimplementation. > <off_mdepProcessor::off_mdepProcessorimplementation. > <off_mdepProcessor::startimplementation. >
off_Processor. >: U1, D2, D3, D4
p_alloc. >: U1, D2
next shuttle. >: U1, D2
off_Magic::nameof case for m_numbers. >: D1, D2
off_mdepProcessor::get_proc_id implementation. >: D1, U2
off_mdepProcessor::how_many implementation. >: D1, U2
off_mdepProcessor::off_mdepProcessor implementation. >: D1, U2
off_mdepProcessor::start implementation. >: D1, U2
off_Processor::alloc and free implementation. >: D1, U2
off_Processor::can_melt implementation. >: D1, U2
off_Processor::cleanup implementation. >: D1, U2
off_Processor::cli sti is_cli and hlt implementation. >: D1, U2
off_Processor::copy_state implementation. >: D1, U2
off_Processor::freeze_state implementation. >: D1, U2
off_Processor::get_allocator implementation. >: D1, U2
off_Processor::get_current implementation. >: D1, U2
off_Processor::get_trap and get_irq implementation. >: D1, U2
off_Processor::get_traps and get_irqs implementation. >: D1, U2
off_Processor::get_url implementation. >: D1, U2
off_Processor::melt_state implementation. >: D1, U2
off_Processor::nameof implementation. >: D1, U2
off_Processor::new_quantum implementation. >: D1, U2
off_Processor::new_quantum local variables. >: U1, D2, D3
off_Processor::operator+ implementation. >: D1, U2
off_Processor::operator= implementation. >: D1, U2
off_Processor::restore_state implementation. >: D1, U2
off_Processor::self implementation. >: D1, U2
off_Processor::start implementation. >: D1, U2
off_Processor::start_clk implementation. >: D1, U2
off_RqAllocator::off_RqAllocator implementation. >: D1, U2
off_RqAllocator::operator + implementation. >: D1, U2
off_RunqSlot::copy_state implementation. >: D1, U2
off_RunqSlot::get_rurl implementation. >: D1, U2
off_RunqSlot::get_shtl and set_shtl implementation. >: D1, U2
off_RunqSlot::get_url_holder implementation. >: D1, U2
off_RunqSlot::off_RunqSlot implementation. >: D1, U2
off_RunqSlot::operator delete implementation. >: D1, U2
off_RunqSlot::operator new implementation. >: D1, U2
off_RunqSlot::restore_state implementation. >: D1, U2
off_mdepProcessor. >: U1, D2, D3
off_Processor. >: U1, D2, D3, D4, D5, D6, D7
off_RqAllocator. >: U1, D2, D3
off_RunqSlot. >: U1, D2
off_Processor. >: U1, D2
off_Processor. >: U1, D2, D3, D4, D5
off_RunqSlot. >: U1, D2, D3
off_LRunqSlot. >: U1, D2, D3
off_mdepProcessor. >: U1, D2, D3, D4, D5
off_Processor. >: U1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19
off_RqAllocator. >: U1, D2, D3
off_RunqSlot. >: U1, D2, D3, D4, D5, D6
off_Processor according to mdep. >: U1, D2, D3, D4, D5
next shuttle. >: U1, D2
%% --------------------------------------------------------------
</a>