The Unix Heritage Society mailing list
 help / color / mirror / Atom feed
From: Steffen Nurpmeso <steffen@sdaoden.eu>
To: Paul Winalski <paul.winalski@gmail.com>
Cc: TUHS <tuhs@minnie.tuhs.org>
Subject: Re: [TUHS] C++ / Kernel
Date: Mon, 27 Aug 2018 18:31:17 +0200	[thread overview]
Message-ID: <20180827163117.PTEBF%steffen@sdaoden.eu> (raw)
In-Reply-To: <CABH=_VT5Yi-6uRz_-045cmf-4kbgTSHZhsCLLracoFXNDwSAYQ@mail.gmail.com>

Paul Winalski wrote in <CABH=_VT5Yi-6uRz_-045cmf-4kbgTSHZhsCLLracoFXNDwS\
AYQ@mail.gmail.com>:
 |On 8/24/18, Steffen Nurpmeso <steffen@sdaoden.eu> wrote:
 |> Though even more unfortunate i am, since this union trick is often
 |> the only way to be able to do proper a.k.a. allowed type
 |> conversion, where the standard text forbids something quick and
 |> easy, casting of or to function pointers in C++ comes to mind
 |> spontaneously.  (The linked story also tries to go via (char*) to
 |> a desired type, but the compiler seems to be too neat.  And even
 |> if this is a bug, of course...)
 |
 |One of the complaints about DEC's C99 compiler for Ultrix was that it
 |was too didactic in its enforcement of the C99 standard.  One customer
 |called it the Rush Limbough of compilers, because it was extremely
 |conservative and you couldn't argue with it.
 |
 |Function pointers can be tricky, as they might not be simple pointers
 |to a sequence of instructions.  On Itanium, for example, a C
 |pointer-to-function points to a descriptor for the function, not the
 |function code itself.

They can be as tricky as they want as long as i can go and use
them, wouldn't you agree?  Not only for simple callbacks but for
"manual VTables" you simply need those dynamic callbacks.  Like
you have said, you need a way to change the instruction location.
As far as i know this is what actually happens, and i want to be
able to access this mechanism without being prevented from some
language rule which is backed by nothing.  That is all.  Whatever
high language construct there may be.  To me this was one of the
properties of the C language.

I can give you another example.  I have a C++ library which uses
an approach to events where you (can) define slots, as in

  pub Misc::Sender<IOEvent> onInput;

You then say XY.onInput.connect(MYHOOK), where MYHOOK can be one
of four different types, which return "event consumed:

  pub typedef boolean (   *Slot1)(Event *);
  pub typedef boolean (   *Slot2)(void *, Event *);
  pub typedef boolean (   EventListener::*Slot3)(Event *);

The first is a PTF callback without user provided data, the second
adds that; the third is a PointerToMember.  The third defines
a PTM to a subclass of EventListener, which is an empty class but
with VTable (protected destructor), provided for the sole purpose
of offering a cheap event slot without marshalling object, managed
by an equal number of connection types, superclass:

  // actual connection structures
  // note we use the lower three bits of Conn::flags for Flags (including
  // ConnType) as below.  this works because the memory cache has an
  // alignment of 8 (or 16, and only).
  pri struct Conn{
    union{
      uir flags;
      Conn *right;
    };
  } SF_CC_PACKED;

E.g., the third

  pri struct ConnML{ // EventListener PTM
    Conn base;
    EventListener *elobj;
    Slot3 slot;
  } SF_CC_PACKED;

So far so good.  But what to do with free-form PTM hooks?
You need templates for that:

  pub template<class OBJ>
  struct ConnMT{ // free-form PTM (template indirection)
    typedef boolean (OBJ::*Slot4)(Event *);
    ConnFO cfo;
    OBJ *tobj;
    Slot4 slot;
  } SF_CC_PACKED;

But that induces several problems, one of them is

    - 2.95.2 and 2.95.3 compile the library without errors.
      The problem with them is that they are not able to handle the
      free-from template pointer-to-member (PTM),
      as well as the EventListener PTM specialization of
      SF::Sys::Misc::Sender correctly.
      This is a no-go for other libraries, which use events as
      a key concept (and base upon EventListener to get rid of the
      purely template PTM based connection overhead), but is
      otherwise no problem.
      (Some of the tests in test/ will not compile, though.)
      (Note: 2.95.2 has not been tested for a long time.
      2.95.3 is part of the test-suite at the time of this writing
      aka TAG 0.6.0.)

The other is that you cannot store ConnMT in generic code -- the
C++ standard does not offer this possibility, even though Slot4 is
a PTM just the very same way that Slot3 is, right?  PTMs are
a wild mix of VTable and offset, right.  But luckily it can be
done, with a very wild hack, but which still works after almost
twenty years, whether gcc or clang is used, at least the tests
ran just fine last time i have tried:

  // disconnecting of those is hard; try it like that (doc/cppcreq.txt).
  pri struct ConnMX{
    ConnFO cfo;
    void *tobj;
    ui1 ptmbuf[szof(Slot3)];
  } SF_CC_PACKED;

Nonetheless you need marshalling objects to dispatch events
through such slots, which is very painful and expensive, as well
as completely unnecessary yet imposed solely by language speech,
but at least all the list handling and such works just fine
(though using memcmp on ptmbuf is really wild).

  _pro template<class OBJ>
  void _Sender::connect4(typename ConnMT<OBJ>::Slot4 _Slot,
      OBJ *_tobj) const{
    ConnMT<OBJ> *cmt;
    cmt = SF_talloc(ConnMT<OBJ>, 1);
    cmt->cfo.base.flags = ((R(uir,m_slots) & ~f_mask) | ct_ptm_t);
    m_slots = &cmt->cfo.base;
    cmt->cfo.slot = &_Sender::_Dispatch<OBJ>;
    cmt->cfo.obj = cmt;
    cmt->tobj = _tobj;
    cmt->slot = _Slot;
  }

  _pri template<class OBJ>
  _sta boolean _Sender::_Dispatch(void *_tobj, Event *_ev){
    ConnMT<OBJ> *cmt = S(ConnMT<OBJ>*,_tobj);
    return (cmt->tobj->*cmt->slot)(_ev);
  }

And of course this is a primitive event mechanism which requires
an Event class to be used.  

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)

  reply	other threads:[~2018-08-27 16:31 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-23 14:42 ron
2018-08-23 17:24 ` Clem Cole
2018-08-23 20:21 ` Bakul Shah
2018-08-23 22:17   ` ron
2018-08-23 22:28     ` Nevin Liber
2018-08-23 22:48       ` Clem Cole
2018-08-23 23:14     ` Steffen Nurpmeso
2018-08-24 14:13       ` Steffen Nurpmeso
2018-08-24 14:32         ` ron
2018-08-24 18:15           ` Steffen Nurpmeso
2018-08-26 16:34             ` Paul Winalski
2018-08-27 16:31               ` Steffen Nurpmeso [this message]
2018-08-24  1:41     ` Bakul Shah
2018-08-24 10:41       ` Pete Turnbull
2018-08-24 12:17       ` ron
2018-08-24 18:36         ` Bakul Shah
2018-08-24 18:38           ` ron
2018-08-24  1:58     ` Dan Cross
2018-08-24  3:04       ` Clem cole
2018-08-24 14:01         ` Dan Cross
2018-08-24 13:22 ` Derek Fawcus
2018-08-24 16:59   ` Steffen Nurpmeso
2018-08-23 23:29 Noel Chiappa
2018-08-23 23:42 ` ron
2018-08-24  0:30   ` Clem Cole
2018-08-24  2:05     ` Bakul Shah
2018-08-24 12:21     ` ron
2018-08-24  1:27 Noel Chiappa
2018-08-24  2:52 ` Clem cole
2018-08-24  7:30 Paul Ruizendaal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180827163117.PTEBF%steffen@sdaoden.eu \
    --to=steffen@sdaoden.eu \
    --cc=paul.winalski@gmail.com \
    --cc=tuhs@minnie.tuhs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).