Index: ossp-pkg/sio/al_todo.txt RCS File: /v/ossp/cvs/ossp-pkg/sio/Attic/al_todo.txt,v co -q -kk -p'1.3' '/v/ossp/cvs/ossp-pkg/sio/Attic/al_todo.txt,v' | diff -u - /dev/null -L'ossp-pkg/sio/al_todo.txt' 2>/dev/null --- ossp-pkg/sio/al_todo.txt +++ /dev/null 2024-05-17 07:45:24.000000000 +0200 @@ -1,182 +0,0 @@ - -o rse: memory chunk maintainance - A piece of memory usually has the following 4 attributes which fully - describe it: - - memory location: - 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. -