    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Adding Polymorphic Classes to the Anthem 'threads'
Model</title>
        <link>https://members.accu.org/index.php/articles/977</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + CVu Journal Vol 12, #2 - Mar 2000</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c127/">122</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-127/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+127/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Adding Polymorphic Classes to the Anthem 'threads'
Model</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 March 2000 13:15:35 +00:00 or Fri, 03 March 2000 13:15:35 +00:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
</div>
<p>In my previous CAUGers article, &quot;Adding 'threads' to Anthem&quot;
[<a href="#Goodliffe">Goodliffe</a>] I presented a somewhat devious
method of adding a background processing thread to what was
previously a single threaded co-operatively multitasking RISC OS
application. This method is not a shining example of best-practice
program design. OK, it is a bit of a hack that allows you to do
something that you ordinarily cannot do in RISC OS. However, its
product is a stable and very effective method of scheduling a
background thread that can interact with the desktop application
thread.</p>
<p>A number of implementation issues were not addressed by that
article. I present here some further information to aid those
interested in attempting a similar modification to their
programs.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e29" id="d0e29"></a>Where we've
been</h2>
</div>
<p>Before I continue, a quick recap would be in order. As well as
refreshing the CAUGers readers' memories this will perhaps benefit
the general C Vu readership who were unable to read the previous
article.</p>
<p>Anthem is a MIDI sequencer application, which is somewhat akin
to a word processor for music. The application UI code is based in
part on the TSE sequencer engine library. This workhorse code
performs MIDI playback. Both are written in C++.</p>
<p>RISC OS currently does not have a built-in application-level
threading model. RISC OS desktop applications are co-operatively
multitasked: they must explicitly yield the right to execute, no
other application will be able to pre-empt them.</p>
<p>The Anthem application was originally designed around a simple
single-threaded architecture. This meant that if another
application hogged control of the co-operative multitasking, MIDI
playback could break up. Adding a second 'thread' to produce MIDI
output in the background was a later architectural decision to
rectify this problem.</p>
<p>Under RISC OS one can build relocatable modules - code blocks
that provide services to augment the basic operating system
facilities. These blocks of code are capable of being entered on
timer call-backs whereas normal application code is not. These
call-backs can pre-empt application execution.</p>
<p>The threading solution described in [<a href=
"#Goodliffe">Goodliffe</a>] involves building two versions of the
sequencer engine code (based on a single source tree). One code
build is targeted at the application level, one build at
relocatable module level. The two versions run at the same time,
tied up in such a way that they share data in a common memory pool
(a RISC OS dynamic area).</p>
<p>The module version performs MIDI output on periodic call-backs.
We provide a simple and sufficient locking mechanism to prevent one
'thread' from interfering with another. Using this mechanism it is
possible to provide background playback whilst the desktop
application is running and still be able to manipulate the song
data. The playback no longer breaks up when desktop response is
poor.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e49" id="d0e49"></a>Dual
hand-rolled vtables</h2>
</div>
<p>OK, so I made that term up myself. It sounds complicated and
disgusting. That is because the concept it describes is. I alluded
to these vtables at the end of the previous article and now we
shall discover what on earth they are and why we need them.</p>
<p>The problem revolves around the existence of polymorphic
classes, i.e. classes with virtual member functions. The vtable is
the most common compiler implementation of the virtual function
mechanism. It is essentially a jump table that is associated with
an object of a polymorphic class. It contains a list of pointers to
member functions, identifying each particular implementation of a
given virtual function. This is a somewhat terse description, for
more information you may wish to have a look at item 24 of More
Effective C++ [<a href="#Meyers">Meyers</a>].</p>
<p>The TSE sequencer engine library contains one polymorphic class
hierarchy. This presents a problem to our dual build
(application/module) approach. The vtable is effectively data
associated with an object. So this data is shared between the
application and module builds of the library. Here is our problem:
which set of function pointers should be placed in the table?</p>
<p>If the vtable contains pointers to the application-build code
then the program will crash and burn. When the module code is
executing, it will call one of the virtual functions, look up the
particular implementation in the shared vtable, and call into
application code. Now if the application is currently paged in then
all will go swimmingly. The problem is that the application will
quite likely be paged out since another application currently has
the (co-operatively managed) application execution privilege. The
module code will branch somewhere into that random application.
Bang. This is a pleasant way to bring our somewhat unprotected
operating system to a blazing halt. Literally.</p>
<p>On the other hand if the vtable contains pointers to the module
code then things will also not go according to plan. Although the
module code will never be paged out as in the previous case, a
module build and application build differ slightly - notably in
their stack handling semantics. Explosions can happen this way
too.</p>
<p>The solution? We hand-roll our own vtables. The faint of heart
give up here whilst the daring continue. As I stressed in the
previous article this is, in reality, a piece of blatant hackery
that has been used to good effect in this situation. However, I
would not recommend this technique as a starting point for the
design of a new software system. Now I have made my disclaimer, I
shall continue...</p>
<p>Let us say that my polymorphic base class originally looked like
this (it is a simplification since there is no private data, but it
shows the shape of what I am doing):</p>
<pre class="programlisting">
class Base {
  public:
    Base();
    virtual ~Base() = 0;
    virtual void a() = 0;
    virtual int  b(int param) = 0;
};
class Derived : public Base {
  public:
    Derived();
    virtual ~Derived();
    virtual void a();
    virtual int  b(int param);
};
</pre>
<p>Now under the new regime we will hand roll our own vtable and
use it manually, thus:</p>
<pre class="programlisting">
struct Base_vtbl_type {
  void (*constructor)();
  void (*destructor )();
  void (*a      )();
  int  (*b      )(int param);
};
class Base {
  public:
    Base();
    ~Base();
    void initialise(); 
// patch up vtables - more later
    void a()
    {
      (TSE_MODULEBUILD) ? vtbl_mod-&gt;a()
               : vtbl_app-&gt;a();
    }
    int b(int param)
    {
      return (TSE_MODULEBUILD) ?
          vtbl_mod-&gt;b(param)  
        : vtbl_app-&gt;b(param);
    }
  private:
    Base_vtbl_type *vtbl_mod; 
// vtable for module use
    Base_vtbl_type *vtbl_app; 
// vtable for app use
};
</pre>
<p>In the above code we have defined a compile time flag,
<tt class="literal">TSE_MODULEBUILD</tt>, that is set if we are
compiling the code for a module, and not set if this is an
application build. Here is the hint at how to use our hand-rolled
vtables - the <tt class="classname">Base</tt> class is now just
acting as the spring board into the appropriate piece of code
(which will be the version located in the appropriate address space
for the caller).</p>
<p>So how are we going to set up these two tables? First we need to
know how we would implement <tt class="classname">Derived</tt>
under the new regime. Rather than define <tt class=
"methodname">Derived::b(int param)</tt> and et al, we instead
define the following simple functions:</p>
<pre class="programlisting">
void Derived_constructor() { }
void Derived_destructor() { }
void Derived_a() { }
void Derived_b(int param){ }
</pre>
<p>But what about object member data that would be passed in via
the implicit this pointer? We will come to that later.</p>
<p>Next we define a pseudo-vtable for this pseudo class:</p>
<pre class="programlisting">
static Base_vtbl_type Derived_vtbl  {
  Derived_constructor,
  Derived_destructor,
  Derived_a,
  Derived_b
};
</pre>
<p>Based on some implementation-choosing magic, the <tt class=
"classname">Base</tt> class' constructor will patch up the function
pointers appropriately. This will first be done in the application
code, since that is where the <tt class="classname">Base</tt>
object is created.</p>
<pre class="programlisting">
Base::Base(){ initialise(); }
Base::~Base() {
// if this is entered in module code we are 
// in error
  vtbl_app-&gt;destructor();
}
void Base::initialise() {
  int impl = get_impl_type_from_ether();
  Base_vtbl_type *vtbl = 0;
  switch(impl)   {
    case Base_impl_Derived:
      vtbl = &amp;Derived_vtbl;
      break;
    // other impls here
  }
  if (!vtbl) ... // panic!
  vtbl-&gt;constructor();
  if (TSE_MODULEBUILD)
    vtbl_mod = vtbl;
  else
    vtbl_app = vtbl;
}
</pre>
<p>This <tt class="classname">Base</tt> constructor will patch up
the vtable appropriately for the application code by calling
<tt class="methodname">Base::initialise()</tt>. Once this is done
by the application it is important that the 'registration' call of
the module build of the code (this is the call that patches up the
appropriate data pointers between the two code versions) also calls
its version of <tt class="methodname">Base::initiliase()</tt>.
Following this we have two complimentary versions of our hand
rolled vtable set up and ready to be used.</p>
<p>I'll admit it's not pleasant, but it works.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e122" id="d0e122"></a>Object
data</h2>
</div>
<p>So what happens to the object's private data?</p>
<p>In my particular case, this was pretty easy to deal with.
Naturally, each 'pseudo-object' needed some local object storage.
However it is part of the TSE library design that the class is a
singleton, i.e. there will only ever be one object of a class
derived from <tt class="classname">Base</tt>. I can therefore use a
<tt class="literal">static</tt> data pointer in the implementation
file to suffice.</p>
<p>It is possible to make this more general, and I leave that as an
exercise for the reader.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e137" id=
"d0e137"></a>Conclusion</h2>
</div>
<p>We have seen how to implement virtual functions on top of the
trickery used to create a background thread.</p>
<p>Hopefully in implementing our own form of vtables we now also
have a clearer idea of what the compiler is doing underneath us
when we type make. This is a valuable lesson that we should
hopefully never have to use in the same way again.</p>
<p>Again, I must stress that I have presented this here for your
interest and not as a shining example of how to perform
pseudo-threading in RISC OS. This is part of a technique - not the
technique.</p>
<p>If any other readers have experiences of attempting a similar
feat then please share them with the CAUGers readership. Anthem is
available from R-Comp Interactive. See <a href=
"http://www.rcomp.co.uk" target="_top">www.rcomp.co.uk</a> for
details.</p>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e151" id="d0e151"></a>References</h2>
</div>
<div class="bibliomixed"><a name="Goodliffe" id="Goodliffe"></a>
<p class="bibliomixed">[Goodliffe] Pete Goodliffe. Adding 'threads'
to Anthem. In: CAUGERs 1999 6(6).</p>
</div>
<div class="bibliomixed"><a name="Meyers" id="Meyers"></a>
<p class="bibliomixed">[Meyers] Scott Meyers. <span class=
"citetitle"><i class="citetitle">More Effective C++</i></span>
(ISBN: 0-201-63371-X). Addison-Wesley. Item 24.</p>
</div>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
