NOTE: Not yet implemented.
\subsubsection{Freezing processors}
To freeze a processor we freeze the run queue slots and the trap and interrupt tables. Unlike other containers, processors freeze their resource unit eagerly, not lazily. The reason is that we expect few resource units and doing a lazy freeze/melt would degrade performance.
We need these methods to support freeze,
<Other protected methods of off_Processor. >+= (<-U) [<-D->]
// These are for freeze:
// Freeze dynamic resource state at curbuf in buf with avail bytes.
virtual err_t freeze_state(char *buf, char *&curbuf, size_t &avail,
char *&curto, size_t &toavail,
const off_prtl_id_t &frozen_domain);
// Copy static resource state in curbuf with toavail bytes.
virtual err_t copy_state(char *&curto, size_t &toavail) const;
as well as these others to support melt:
<Other protected methods of off_Processor. >+= (<-U) [<-D->]
// These are for melt:
// Does resource cleanup. No external resource should be used after
// return.
virtual err_t cleanup(void);
// Restores the static state from a user supplied buffer.
virtual err_t restore_state(char *&buf, size_t &bsize);
// Restores dynamic resource state.
virtual err_t melt_state(char *&buf, size_t &bsize, char *&from, size_t &size,
const off_prtl_id_t &melted_domain);
The most simple are cleanup and copy_state.
<off_Processor::cleanup implementation. >= (U->)
// Does resource cleanup. No external resource should be used after
// return.
err_t off_Processor::cleanup(void)
{
assert(valid() && p_name && p_url);
delete[] p_name;
delete[] p_url;
return EOK;
}
To copy the processor static state we copy the processor itself. We
forget about run queues, trap and interrupt tables because
freeze_state already freezes every processor component.
<off_Processor::copy_state implementation. >= (U->)
// Copy static resource state in curbuf with toavail bytes.
err_t off_Processor::copy_state(char *&curto, size_t &toavail) const
{
assert(valid());
if (curto){
if (toavail<sizeof(*this))
return ENOSPC;
*(off_Processor*)curto = *this;
assert(((off_Processor*)curto)->valid());
curto += sizeof(*this);
toavail-=sizeof(*this);
}
return EOK;
}
The counterpart, restore_state, uses a copy operator tailored not to
copy those members which must remain unaltered (p_traps etc.).
<Other public methods of off_Processor. >+= (<-U) [<-D]
// Copy Processor contents.
const off_Processor &operator=(const off_Processor &other);
It also uses can_melt to know if the frozen processor
can be melted on this one.
<Other protected methods of off_Processor. >+= (<-U) [<-D]
// Is the other bank meltable at this one?
boolean_t can_melt(const off_Processor *other) const;
<off_Processor::restore_state implementation. >= (U->)
// Restores the static state from a user supplied buffer.
err_t off_Processor::restore_state(char *&buf, size_t &bsize)
{
off_Processor *other=(off_Processor*)buf;
assert(valid());
if (buf){
if (bsize < sizeof(*this) || !can_melt(other)){
return EINVAL;
}
assert(other->valid());
*this=*other;
buf+=sizeof(*this);
bsize-=sizeof(*this);
}
return EOK;
}
<off_Processor::operator= implementation. >= (U->)
// Copy Processor contents.
const off_Processor &off_Processor::operator=(const off_Processor &other)
{
*(off_HWCompResource*)this = *(off_HWCompResource*)&other;
assert(valid() && other.valid());
p_alloc = other.p_alloc;
p_traps = other.p_traps;
p_irqs = other.p_irqs;
p_url=other.p_url;
p_name=other.p_name;
p_mdep=other.p_mdep;
return *this;
}
\Note{XXX freeze traps, irqs and alloc.}
<off_Processor::can_melt implementation. >= (U->)
// Is the other IO meltable at this one?
boolean_t off_Processor::can_melt(const off_Processor *other) const
{
// XXX do check it!
assert(valid() && other && other->valid());
return TRUE;
}
<off_Processor::freeze_state implementation. >= (U->)
// Freeze dynamic resource state at curbuf in buf with avail bytes.
err_t off_Processor::freeze_state(char *buf, char *&curbuf, size_t &avail,
char *&curto, size_t &toavail,
const off_prtl_id_t &frozen_domain)
{
(void)curto; (void)toavail;
assert(valid() && buf && curbuf);
set_domain(frozen_domain);
if (!::freeze(p_name,buf,curbuf,avail) ||
!::freeze(p_url,buf,curbuf,avail))
return ENOSPC;
// XXX freeze traps, irqs and run queue.
return ENOSYS;
}
<Off processor implementation dependencies. >+= (U->) [<-D] #include <klib/freeze.h> // for ::freeze, ::melt et al.
<off_Processor::melt_state implementation. >= (U->)
// Restores dynamic resource state.
err_t off_Processor::melt_state(char *&buf, size_t &bsize,
char *&from, size_t &size,
const off_prtl_id_t &melted_domain)
{
assert(valid() && buf);
(void)from; (void)size;
p_name=::melt(p_name,buf,bsize);
p_url=::melt(p_url,buf,bsize);
set_domain(melted_domain);
// melt traps, irqs and run queue.
return EOK;
}
\subsubsection{Freezing run queue slots}
We need to implement only these methods:
<Other protected methods of off_RunqSlot. >+= (<-U) [<-D]
// Copy static resource state in curbuf with toavail bytes.
virtual err_t copy_state(char *&curto, size_t &toavail) const;
// Restores the static state from a user supplied buffer.
virtual err_t restore_state(char *&buf, size_t &bsize);
// Restores dynamic resource state.
<off_RunqSlot::copy_state implementation. >= (U->)
// Copy static resource state in curbuf with toavail bytes.
err_t off_RunqSlot::copy_state(char *&curto, size_t &toavail) const
{
assert(valid());
if (curto){
if (toavail<sizeof(*this))
return ENOSPC;
*(off_RunqSlot*)curto = *this;
assert(((off_RunqSlot*)curto)->valid());
curto += sizeof(*this);
toavail-=sizeof(*this);
}
return EOK;
}
Note how in this one we take care that the reference to the container is not affected by the state restore.
<off_RunqSlot::restore_state implementation. >= (U->)
// Restores the static state from a user supplied buffer.
err_t off_RunqSlot::restore_state(char *&buf, size_t &bsize)
{
off_RunqSlot *other=(off_RunqSlot*)buf;
assert(valid());
if (buf){
off_Processor *bank=(off_Processor*)get_container();
if (bsize < sizeof(*this)){
return EINVAL;
}
assert(other->valid());
*this=*other;
set_container((off_CompResource*)bank);
buf+=sizeof(*this);
bsize-=sizeof(*this);
}
return EOK;
}
\subsection{Dumping processors}