🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

9 total messages Started by Paul Wilson Sat, 18 Nov 1995 22:24
STL allocator spec broken?
#2641
Author: Paul Wilson
Date: Sat, 18 Nov 1995 22:24
66 lines
3742 bytes
My current understanding of STL allocators suggests that the standard
is badly designed.  I'd be happy to be corrected if I'm wrong.

As I understand it, STL templates can take an allocator argument,
so that you can instantiate the templates to give different types
that use different allocators.

This seems to me the wrong way to go.  The allocator should be specified
for particular instances to make the system really useful.  That is,
you should be able to allocate instances of exactly the same class
in different ways.

For example, if one of your allocators manages shared memory and another
manages private memory, you'd like to have data structures that can cross
that boundary.   Suppose you want to create a private list that is
a prefix of a shared list, or some kind of private tree whose subtrees
are shared.  You'd like the instances to be of the same type, so that
you can have pointers from one to the other without krufty special-case
code.

An example that's closer to my heart is that I want to support STL
classes with orthogonal persistence.  I'd like it to be possible
for a piece of code to operate on instances of a class irrespective
of whether they're allocated in transient memory, or in a persistent
store.

(E.g., for a database transaction, I may have temporary relations
implemented as collections on the transient heap, but permanent relations
allocated on the persistent heap.  I'd like the same code to be able to
operate on either, because the query processing steps don't care about
whether they're operating on intermediate or permanent relations.  I'd
also like the transient relations to be able to hold pointers to objects
that may themselves be transient objects generated during query processing,
or persisent objects faulted into memory from the p-store by a search query.)

As I understand it, ObjectSpace STL does support per-instance specification
of allocators, although I'm unclear on the details and whether it actually
works the way I'd like.

Will the STL standard eventually support this?

Am I mistaken that the standard STL allocator model conflicts with what
I want to do?  Are instantiations of templates with different allocators
different types, requiring different code to operate on them?  I suppose
we could write all of our code as template functions and generate two
versions of everything, but that's ugly and not a complete solution.

(A little background here: by default, our persistent store does not
checkpoint pages of transient memory.  If a failure occurs during a
transaction, all transient objects simply disappear, and all changes
to persistent data are lost---i.e., not propagated to the persistent
store.  It is assumed that the transaction will be restarted and the
transient data will be regenerated.)

-- 
| Paul R. Wilson, Comp. Sci. Dept., U of Texas @ Austin (wilson@cs.utexas.edu)
| Papers on memory allocators, garbage collection, memory hierarchies,
| persistence and  Scheme interpreters and compilers available via ftp from 
| ftp.cs.utexas.edu, in pub/garbage (or http://www.cs.utexas.edu/users/wilson/)      


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: STL allocator spec broken?
#2681
Author: John Max Skaller
Date: Tue, 21 Nov 1995 03:04
40 lines
2136 bytes
wilson@cs.utexas.edu (Paul Wilson) wrote:
>
>My current understanding of STL allocators suggests that the standard
>is badly designed.  I'd be happy to be corrected if I'm wrong.

Are you talking about:

  1) the Working Paper specification, or,
  2) The Stepanov/Lee specification?

According to the September 1995 WP, you have to pass
an allocator type argument to "list", and you have
to pass an allocator OBJECT of that type to a list.

According to Stepanov/Lee, you have to pass an allocator
TEMPLATE. [Note: pass a _template_, not a type]

>Am I mistaken that the standard STL allocator model conflicts with what
>I want to do?  Are instantiations of templates with different allocators
>different types, requiring different code to operate on them?  

  WP: no, not always (but they can be)
  Stepanov/Lee: yes, always.

>I suppose
>we could write all of our code as template functions and generate two
>versions of everything, but that's ugly and not a complete solution.

I don't understand: generally you WILL be writing almost all
modern C++ code as templates.

--
John Max Skaller               voice: 61-2-566-2189
81 Glebe Point Rd              fax:   61-2-660-0850
GLEBE NSW 2037                 email: maxtal@suphys.physics.oz.au
AUSTRALIA                      email: skaller@maxtal.com.au
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: STL allocator spec broken?
#2670
Author: Jim Chapman
Date: Wed, 22 Nov 1995 02:43
23 lines
1603 bytes
In article pv2@boogie.cs.utexas.edu, wilson@cs.utexas.edu (Paul Wilson) writes:

> [...]
> As I understand it, ObjectSpace STL does support per-instance specification
> of allocators, although I'm unclear on the details and whether it actually
> works the way I'd like.
> [...]

I share your preference in this matter.  With the ObjectSpace STL, the
container class constructors take an optional allocator argument. I
find that this serves my purposes better than the allocator-as-template-
argument model.


---
 ====  AT&T        | Jim Chapman             |
=--=== Global      | Multimedia Projects     | jbc@ElSegundoCA.ATTGIS.COM
=--=== Information | 100 N. Sepulveda Blvd.  |   Voice: (310) 524-6747
 ====  Solutions   | El Segundo, CA 90245    |   FAX:   (310) 524-5515
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: STL allocator spec broken?
#2745
Author: Anil Vijendran
Date: Tue, 28 Nov 1995 22:28
39 lines
2099 bytes
>>>>> On 18 Nov 1995 22:24:33 GMT, wilson@cs.utexas.edu (Paul Wilson)
said:

    Paul> An example that's closer to my heart is that I want to support STL
    Paul> classes with orthogonal persistence.  I'd like it to be possible
    Paul> for a piece of code to operate on instances of a class irrespective
    Paul> of whether they're allocated in transient memory, or in a persistent
    Paul> store.

I have a question in relation to this... I've seen persistence
systems/libraries where the allocator or the heap itself is passed
using the placement syntax... for example,

	ptr = new (pstore) shape;

I have always been wondering how the constructor of the class could
allocate its data members on the same heap the top level object was
placed in.

I think the placement syntax when extended to persistent stores and
such, whatever goes as the placement-expression, should be passed to
the constructor too.. Or can this be done sans such an extension? 

Thanks in advance. 



	
-- 
Peace.... +<:-)

Anil

___________________________________________________________
Nothing is certain but death and taxes

[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: STL allocator spec broken?
#2764
Author: Paul Wilson
Date: Wed, 29 Nov 1995 00:51
65 lines
3410 bytes
In article <xg3ohtwl6t0.fsf@marsh.cacs.usl.edu>,
Anil Vijendran <akv@cacs.usl.edu> wrote:
>>>>>> On 18 Nov 1995 22:24:33 GMT, wilson@cs.utexas.edu (Paul Wilson)
>said:
>
>I have a question in relation to this... I've seen persistence
>systems/libraries where the allocator or the heap itself is passed
>using the placement syntax... for example,
>
>	ptr = new (pstore) shape;
>
>I have always been wondering how the constructor of the class could
>allocate its data members on the same heap the top level object was
>placed in.
>
>I think the placement syntax when extended to persistent stores and
>such, whatever goes as the placement-expression, should be passed to
>the constructor too.. Or can this be done sans such an extension? 

It can be done without an extension, if there's a routine that an
object can use to find out what heap it itself is allocated in.

The Texas persistent store provides such a routine.  Every in-use
page of memory is part of a persistent store or a transient
(conventional non-persistent) store, and this routine simply checks
to see what store the page belongs to.  So an object can effectively
ask "where am I?" and then "allocate this there too".

This is not necessarily the best way to do it, however, because checking
what store owns a page takes dozens of instructions.  Another way of
doing it is for the object to hold onto a pointer to its store, and
use that when allocating its sub-objects.  That way the lookup only
happens once.

Yet another way to do it is to capture the pointer to the store object
(essentially an allocator) from the constructor and hold onto it for
later use, so that the lookup doesn't have to be done at all.

We're trying to figure out the most graceful way of making this work
with STL.  We haven't yet grokked all of the standardsese in the new
working paper, but it doesn't seem hard.  (If it is hard, STL needs
to be fixed.  My earlier mail on this topic was based on ignorance
of the new working paper---I didn't realize that the allocator model
had changed from the Stepanov version.)

Does anybody know of a clear description of the current allocator model?
Do the new books on STL---e.g., Nelson's---explain this, or are they out
of date because things have changed very recently?

Is there a standard set of programming style recommendations for
using allocators?

  Paul

-- 
| Paul R. Wilson, Comp. Sci. Dept., U of Texas @ Austin (wilson@cs.utexas.edu)
| Papers on memory allocators, garbage collection, memory hierarchies,
| persistence and  Scheme interpreters and compilers available via ftp from 
| ftp.cs.utexas.edu, in pub/garbage (or http://www.cs.utexas.edu/users/wilson/)      

---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: STL allocator spec broken?
#2780
Author: Alex Martelli
Date: Thu, 30 Nov 1995 17:52
68 lines
2875 bytes
akv@cacs.usl.edu (Anil Vijendran) writes:
	...
>I have a question in relation to this... I've seen persistence
>systems/libraries where the allocator or the heap itself is passed
>using the placement syntax... for example,

>	ptr = new (pstore) shape;

>I have always been wondering how the constructor of the class could
>allocate its data members on the same heap the top level object was
>placed in.

>I think the placement syntax when extended to persistent stores and
>such, whatever goes as the placement-expression, should be passed to
>the constructor too.. Or can this be done sans such an extension? 

Of course it can!  Just declare your "class shape" constructor to
(perhaps optionally) take a reference-to-allocator, eg:

class allocator {
public: virtual void* givemem(size_t bytes) = 0;
	virtual void freemem(void* ptr) = 0;
// etc
};

class default_allocator: public allocator {
public: virtual void* givemem(size_t bytes) {return ::operator new(bytes); }
  virtual void freemem(void *ptr) {::operator delete(ptr); }
// etc
};

void* operator new(size_t bytes, allocator& al) {
    return al.givemem(bytes);
}

class shape {
    int *amember;
    allocator &_al;
public: shape(allocator &al=default_allocator): _al(al) {
	    amember = new(al) int;
	}
        ~shape() {
	    _al.freemem(amember); // I just can't remember the placement
	                          // delete syntax...:-)
	}
	// etc
};

class pstore: public allocator { // etc
};
// ...
	shape *s = new(pstore) shape(pstore);

Basically, while it _might_ perhaps be nice to have syntax sugar to
avoid having to write pstore twice in this way, I do not think there
is really any burning need for such sugar...


Alex
--
DISCLAIMER: these are TOTALLY personal opinions and viewpoints, NOT connected
in any way with my employer, nor any other organization or individual!
Email: martelli@cadlab.it                            Phone: +39 (51) 597313
CAD.LAB s.p.a., v. Ronzani 7/29, Casalecchio, Italia   Fax: +39 (51) 597120

[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: STL allocator spec broken?
#2820
Author: Anil Vijendran
Date: Fri, 01 Dec 1995 19:21
26 lines
1428 bytes
>>>>> On 30 Nov 1995 17:52:37 GMT, martelli@cadlab.it (Alex Martelli)
said:

    Alex> 	shape *s = new(pstore) shape(pstore);

    Alex> Basically, while it _might_ perhaps be nice to have syntax sugar to
    Alex> avoid having to write pstore twice in this way, I do not think there
    Alex> is really any burning need for such sugar...

I'm not that much of syntactic-sugar guy, but tell me how you would do
this if you needed to allocate an array of objects? 

Doesn't anyone else feel there needs to be a link between the
placement-expression and the constructor? I'm curious 'cos I get the
feeling I'm missing something... 
-- 
Peace.... +<:-)

Anil


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: STL allocator spec broken?
#2835
Author: Alex Martelli
Date: Mon, 04 Dec 1995 22:38
71 lines
3802 bytes
akv@cacs.usl.edu (Anil Vijendran) writes:
	...
>    Alex> 	shape *s = new(pstore) shape(pstore);

>    Alex> Basically, while it _might_ perhaps be nice to have syntax sugar to
>    Alex> avoid having to write pstore twice in this way, I do not think there
>    Alex> is really any burning need for such sugar...

>I'm not that much of syntactic-sugar guy, but tell me how you would do
>this if you needed to allocate an array of objects? 

In the same way as when needing to pass ANY argument whatsoever to
the constructors of objects allocated as part of a new[]'ed builtin
array -- i.e., do without.  The draft standard simply does not support
any non-default constructors for this case, and despite all the
arguments one could muster against this decision (and there are
surely more important and cogent cases than the specific example
of passing an allocator), there isn't a snowball's chance in Hell
that the committee will budge on this point, I believe.  Apparently,
builtin arrays are, reasonably, perceived as very low-level features,
whose use must NOT be encouraged by any enhancement or new support --
witness the recent discussion about the lack of an auto_ptr for
builtin arrays.

Everybody's supposed to be using nicely packaged templates for
arraylike stuff -- and sweat it out if they're *implementing*
the darned "nicely packaged templates".

So, what one does (perhaps inside the template's guts) everytime
one needs a non-default constructor for array elements, is
something like...:

-- use operator new[]() to allocate raw memory (perhaps in a
   suitably overloaded form through an allocator);
-- loop over the raw memory, calling placement new on each
   slice (with whatever nondefault args one needs) to turn
   the raw bits into a living object.

In particular, if need be, one can pass the reference to the
allocato to use in the placement new statement.

>Doesn't anyone else feel there needs to be a link between the
>placement-expression and the constructor? I'm curious 'cos I get the
>feeling I'm missing something... 

Well, there's an old Usenet saying, known as Ugol's Law, that
goes something like "If you ask if you're the only one -- you
aren't".  But the fact that others feel like you does not imply,
of necessity, that it makes sense:-).  Note, for example, how
horribly having a link between placement-expression and ctor
would work in the normal usage case that I outline above, where
I have to use placement new over already-allocated memory (the
normal kind, taking a void*) BUT I have to tell the object to
use another allocator (the one that was originally used to
get the raw-memory, in a *different* point from the placement
expression I'm now using) for its own allocation purposes...!


Alex
--
DISCLAIMER: these are MY personal opinions and viewpoints, NOT connected
in any way with my employer, nor any other organization or individual!
Email: martelli@cadlab.it -- Phone: +39 (51) 597 313  [Fax: 597 120]
Cad.Lab S.p.A., v. Ronzani 7/29, 40033 Casalecchio (BO), Italia


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: STL allocator spec broken?
#2899
Author: Anil Vijendran
Date: Fri, 08 Dec 1995 04:06
106 lines
4658 bytes

I'm in violent agreement when someone says arrays are lowlevel and
that their use should be discouraged. I'm certainly not talking about
making a change in the language just so that array objects could be
constructed differently. That wouldn't even be the last item in the
list of things I'd like to see in C++. 

>>>>> On 04 Dec 1995 22:38:45 GMT, martelli@cadlab.it (Alex Martelli)
said:

    Alex> Well, there's an old Usenet saying, known as Ugol's Law, that
    Alex> goes something like "If you ask if you're the only one -- you
    Alex> aren't".  But the fact that others feel like you does not imply,
    Alex> of necessity, that it makes sense:-).  Note, for example, how
    Alex> horribly having a link between placement-expression and ctor
    Alex> would work in the normal usage case that I outline above, where
    Alex> I have to use placement new over already-allocated memory (the
    Alex> normal kind, taking a void*) BUT I have to tell the object to
    Alex> use another allocator (the one that was originally used to
    Alex> get the raw-memory, in a *different* point from the placement
    Alex> expression I'm now using) for its own allocation purposes...!

Well... Doing non-default construction on a per-object basis for
arrays is ugly by itself. So, to me, this doesn't seem like a good
argument against implicit arguments being passed to constructors.

Let me rewind a li'l bit. 

Why was this syntax invented?

	X* ptr = new (allocator) X;

Because

	void* raw = allocator.alloc(sizeof(X)); 
	X* ptr = new (raw) X;

is clumsy (error prone?). 

(I find the former easier to read/write. But I'm not very sure if it
is just a question of one line vs two lines. I'd like to know what
y'all think about the importance of support for the former.)

If `X' does allocation for its members then there is no language
supported way for `X' to get the allocator. IMHO, that doesn't sound
too good.

1. It is none of the users' business to even think about how the
   constructor allocates memory (or whatever) for its members. 
2. He has already said where the object has to be allocated. 

(Things like:

	data_member_ptr = allocator_map[this]->alloc(...);

are not portable and might (I'm not sure) not be thread safe, 'cos
least of all the allocator_map has to be a global variable. Mr Paul
Wilson was talking about this kinda stuff.)

There is atleast one important advantage that I can see to having
support for this:

	X::X(implicit Allocator& al = nullAllocator, int args)
              // `implicit' is a new keyword ;-)
              // could be replaced by `from_new' or some such. 
           {
           }              

	X* xptr = new (allocator) X(5); // `allocator' becomes implicit
                                        // argument to constructor

	X xobject(5); // `nullAllocator' becomes implicit argument to
                      // constructor, indicating to the constructor
                      // that the object is not allocated on the
                      // heap. 

	X* xptr = new X(5); // `defaultSystemAllocator' becomes implicit
                            // argument to the constructor. 

This way, an object gets to know more about how it was created--
dynamic or on stack. That could give the object a chance to do
somethings more efficiently.

Without support for such implicit arguments, any class that follows
this kind of an allocation paradigm ( new (allocator) X(allocator); )
automatically outlaws itself from array support. 

Wouldn't this be a useful thing? Wouldn't this be a decent scheme--
simple to implement, orthogonal etc? I'm sure someone would've thought
about it and discarded it. I want to know WHY! 

TIA for digging into this with me. 



-- 
Peace.... +<:-)

Anil


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads