OSSP CVS Repository

ossp - ossp-pkg/sio/al_todo.txt
Not logged in
[Honeypot]  [Browse]  [Directory]  [Home]  [Login
[Reports]  [Search]  [Ticket]  [Timeline
  [Raw

ossp-pkg/sio/al_todo.txt

o rse: memory chunk maintainance
  A piece of memory usually has the following 4 attributes which fully
  describe it:

  memory location: <pointer,length,size,refcount>
  memory type:     STACK|HEAP|SHMEM|CUSTOM
  memory scope:    LOAN|GIFT|[COPY]
  memory access:   READ_ONLY|READ_WRITE

  With the current al_chunk_t/al_buffer_t such a description is only
  partly possible, although IMHO (after efficiency) this flexibility in
  describing arbitrary memory chunks has to be #1 priority.

  Currently only al_attach_buffer() allows insertion of externally
  provided memory chunks. But these then have to be malloc(3)'ed and
  are not allowed to be allocated differently. For this the CUSTOM type
  would allow arbitrary memory chunks to be specified for an application
  provided destruction callback exists.

x mlelstv:
  insertion of externally provided memory chunks is the
  exception, not the rule. Previously it couldn't be malloc'ed
  because it was almost impossible to free it later. The latest
  change to the API provides the necessary destruction callback.

  I don't see specific "memory types" yet. Currently memory can be
  allocated and freed. If we support "memory types" we need
  a specific "memory" library that abstracts from these types
  beyond malloc() and free(). Things like cache-coherency or
  atomic access come to my mind.

  Memory scopes are implied by the specific operations:
  user API:   LOAN == al_attach_buffer (and COPY with al_*_bytes)
  internally: GIFT == al_splice (and COPY)
  Providing public GIFT semantic requires to expose the internal
  memory allocator. That's why I use LOAN.
  
  No ideas about "memory access" types yet. What is the use for
  a "read-only" assembly line ?

o rse: al.pod, DESCRIPTION:
  perhaps add the buzzwords "zero-copy" and "efficient" somewhere just
  to make sure people recognize that OSSP al is not "just another
  trivial buffer library" ;)

x mlelstv:
  it is "copy avoidance" but not "zero-copy".
  
o rse: al.pod, al_attach_buffer:
  scope still does not say anything about the content, i.e., is it
  allowed that the application still changes the content (as long as the
  size does not change)?

x mlelstv:
  the buffer is loaned to the library. Previously you wouldn't know
  when it is returnd (and thus available). Now a callback function
  is used to hand the buffer back.
  The same mechanism is used internally for buffers allocated by
  the library.

o rse: recommended renamings: 
  public:
    al_txalloc     -> al_tx_create
    al_txfree      -> al_tx_destroy
    al_traverse    -> al_traverse_start
    al_traverse_cb -> al_apply
  private:
    new_buffer     -> buffer_new
    dispose_buffer -> buffer_dispose
    make_buffer    -> buffer_make
    new_chunk      -> chunk_new
    split_chunk    -> chunk_split
    dispose_chunk  -> chunk_dispose

x mlelstv:
  alloc/free vs create/destroy:   al_tx_t is no object, thus
  no constructor, just an allocator. And that's denoted in the
  function name.

  al_apply sounds neat, but then al_traverse* need some neat
  names too.

  private naming: I don't like the change. Current names
  are english phrases. "new" (== verb) "buffer" (== subject).

o thl: sanity checks and return of AL_ERR_ARG

x mlelstv:
  ACK

o thl: Es fehlt eine al_configure() call mit dem man die al_memops_t
  beeinflussen kann.

x mlelstv:
  memops sind bisher private, sind sie ausreichend fuer public API ?
  Ich glaube nicht. Und "erweiterbare" APIs wuerde ich gerne vermeiden.

o thl: Beim splicen entstehen shared buffers und deren bisherige Behandlung
  ist rudimentaer, sorgt aber bereits fuer merklich Overhead usecount
  in al_buffer_t). Das transferieren von Teilen solcher shared buffer
  von einer al in eine andere ist derzeit ein Limit der Library.
  Ein versehentliches anhaengen von Daten in anscheinend freie
  Bufferbereiche, die aber doch von anderen Chunks genutzt werden,
  wird derzeit schlicht durch Totalverweigerung der Nutzung von
  evtl. freien Bufferbereichen bei shared buffers verhindert, indem
  AL_CHUNK_RESERVE() einfach immer "null Platz" fuer shared buffer
  (usecount > 1) zurueckgibt. Aehnliches gilt fuer das gift/loan
  Verhalten, wegen al_attach_buffer() muss extra ein freemem flag
  mitgescheift werden. Aber es wird gemacht und
  funktioniert und ich wuesste auch keinen besseren Weg.

x mlelstv:
  usecount is notwendig, wenn man zukuenftig aliasing (== copy-on-write)
  unterstuetzen will.

  Eine feinere Behandlung von shared buffers wuerde ich, gerade wegen
  des Overheads, vermeiden wollen. Buffer-Sharing dient nicht dem
  Sparen von Speicher sondern dem Verhindern von Kopieroperationen.

  freemem ist nicht laenger ein Flag, sondern ein (optionaler) Callback.
  Flexibler.
 
o thl: Es ist weder in der Doku noch im Code beruecksichtigt, dass
  die Assembly List zwischen al_traverse() und al_txfree() nicht
  veraendert werden darf. Ist auch nicht ganz so einfach zu erklaeren,
  denn veraendern heisst z.B. splicen. Appenden und prependen stoert
  wohl nicht. Es gehen aber die waehrend des traversals dazugekommenen
  Daten dem al_traverse_next() durch die Lappen, da die Datenmenge beim
  al_traverse() berechnet wird.

x mlelstv:
  Korrekt. Erster Ansatz ist ein al_traverse_end() mit dem man ein
  Traversal abschliesst (oder temporaer abschliesst, damit die notwendige
  Re-Initialisierung automatisch wieder vorgenommen werden kann).

o rse: the library is not threadsafe nor even reentrant because there
  are two static variables: alc_freelist, alc_freecount.

x mlelstv:
  ACK

  solution 1: keep per al_t freelists, simple, but doesn't allow
              a shared freelist.
  solution 2: add global context that can be hooked into thread libraries.
  solution 3: defer problem to a grid allocator library

  I suggest solution 3 :)

o rse: the list.h macros lack a common prefix.

x mlelstv:
  wenn schon dann XML namespaces.... >-)

o rse:
   al_rc_t al_txalloc      (al_t *al, al_tx_t **tx);
   al_rc_t al_txfree       (al_t *al, al_tx_t  *tx);
  -al_rc_t al_traverse     (al_t *al, size_t off, size_t n, al_td_t dir, al_tx_t *tx);
  +al_rc_t al_traverse     (al_t *al, al_tx_t  *tx, size_t off, size_t n, al_td_t dir);
   al_rc_t al_traverse_next(al_t *al, al_tx_t  *tx, al_chunk_t **alcp);
   al_rc_t al_traverse_end (al_t *al, al_tx_t  *tx, int final);

  mlelstv:
  parameter order is: object ptr(if any), input parameters, output parameters

  rse:
  Nun, generell ist deine "obj-ptr, input[, ...], output[, ...]"
  Reihenfolge voellig ok. Der Punkt ist nur, dasz es eigentlich
  "obj-ptr[, ...], input, [,...], output, [,...]" ist, sprich es
  kann durchaus bei Sub-APIs mehrere Object Pointer geben. Und
  genau das ist bei dir ja der Fall IMHO. Denn das al_tx_t und die
  Functions al_txalloc, al_txfree, al_traverse, al_traverse_next und
  al_traverse_end bilden bei dir ja eine solche Sub-API. Und deswegen
  wuerde ich das al_tx_t auch als zweites Argument bei al_traverse
  sehen. Denn obendrein: wenn es man es genau nimmt, ist das al_tx_t
  ja nicht nur bei al_traverse ein Output Parameter, denn die anderen
  Funktionen aendern ihn ja auch ab. Wenn man also streng zwischen Input
  und Output-Parameters unterscheidet, dann duerften Input Parameter
  also nie veraendert werden (wenn sie nicht eh per Kopie reingehen).
  Die Input/Output-Regel ist also streng genommen bereits durch
  al_traverse_next gebrochen IMHO.


CVSTrac 2.0.1