473,785 Members | 2,282 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Is this standard c++...

I am thinking about using this technique for all the "local" memory pools in
a paticular multi-threaded allocator algorithm I invented. Some more info on
that can be found here:

http://groups.google.com/group/comp....c40d42a04ee855

Anyway, here is the code snippet:

#include <cstdio>
#include <cstddef>
#include <new>
template<size_t T_sz>
class lmem {
unsigned char m_buf[T_sz];
public:
void* loadptr() {
return m_buf;
}
};
class foo {
public:
foo() { printf("(%p)foo ::~foo()", (void*)this); }
~foo() { printf("(%p)foo ::~foo()", (void*)this); }
};
int main(void) {
foo *f;
lmem<sizeof(*f) foomem;
f = new (foomem.loadptr ()) foo;
f->~foo();
return 0;
}

Feb 27 '07
22 2301
On 28 Feb, 03:28, Ian Collins <ian-n...@hotmail.co mwrote:
kwikius wrote:
On 28 Feb, 02:47, Ian Collins <ian-n...@hotmail.co mwrote:
>kwikius wrote:
>>IMO, because the array is wrapped in a class there shouldnt be a
problem. IOW thc class alignment will take care of the issue. However
It should be possible to check . (Not absolutely sure if this is the
correct solution but whatever ...
>No, the class may be aligned according to the alignment requirements of
its members, in this case unsigned char.
Yep. I figured it out eventaully I think.
It seems to be possible but at the expense of always allocating your
char array oversize by alignment_of<T-1. Its not possible to know
where on the stack the lmem object will go.
Anyway the following seems to work :
template<typena me T, size_t T_sz>
class lmem {
// Don't think there is a way to avoid
// allocating extra stack space ...
unsigned char m_buf[T_sz + alignment_of<T> ::value -1];
public:
void* loadptr() {
// align memory to T
ptrdiff_t dummy = m_buf - static_cast<uns igned char*>(0);
ptrdiff_t offset = dummy % alignment_of<T> ::value;
ptrdiff_t result = offset == 0
? dummy
: dummy + alignment_of<T> ::value - offset;
// check this works
assert( result % alignment_of<T> ::value == 0);
return static_cast<uns igned char*>(0) + result;
}
};

Or even:

template <typename T>
class lmem {
T t;
public:
void* loadptr() {
return &t;
}

};
But consider a variant, and you are smokin', treating stack like heap
with no alloc overhead...

This may be the purpose behind the device ...

template< size_t T_sz>
class lmem {

unsigned char m_buf[T_sz];
public:
template <typename T>
void* loadptr() {
assert( T_sz >= sizeof(T) + alignment_of<T> ::value -1);
// align memory to T
ptrdiff_t dummy = m_buf - static_cast<uns igned char*>(0);
ptrdiff_t offset = dummy % alignment_of<T> ::value;
ptrdiff_t result = offset == 0
? dummy
: dummy + alignment_of<T> ::value - offset;
// check this works
assert( result % alignment_of<T> ::value == 0);
return static_cast<uns igned char*>(0) + result;
}
};

struct my{
int x, y;
double z;
my(int xx, int yy, double zz): x(xx),y(yy),z(z z){}
};

#include <iostream>
int main()
{

// muck about with stack offsets
char c = '\n';
short n = 1;
lmem<1000x;
double * pd = new (x.loadptr<doub le>()) double(1234.567 89);
std::cout << *pd <<'\n';
// add some detroy function which discrimainates pods etc
my * pc = new (x.loadptr<my>( )) my(1,2,3);
std::cout << pc->x << ' ' << pc->y << ' ' << pc->z <<'\n';
// use some destroy() for my dtor
}

regards
Andy Little
Feb 28 '07 #11
Ian Collins wrote:
Default User wrote:
Ian Collins wrote:
C++ purists avoid printf. Never mix it with iostreams.
Bah. Pointlessly dogmatic. Sometimes it's the right thing.
Care to cite an example?
Any time you need a compact statement for formatting output from
multiple variables. All that screwing around with setw and setprecision
and whatnot is ridiculous.

Just because dumbasses sometimes fail to use printf() in a correct
manner doesn't mean that those of us who aren't dumbasses should not
use it.

Yeah, yeah, I know Boost has some sort of formatted output thing, but
some of us can't use it. I have no idea what its status is vis-a-vis
the standard.

Brian
Feb 28 '07 #12
Default User wrote:
Ian Collins wrote:

>>Default User wrote:
>>>Ian Collins wrote:
C++ purists avoid printf. Never mix it with iostreams.

Bah. Pointlessly dogmatic. Sometimes it's the right thing.

Care to cite an example?


Any time you need a compact statement for formatting output from
multiple variables. All that screwing around with setw and setprecision
and whatnot is ridiculous.
Then use sprintf.

I've seen real problems where printf and iostreams were used on the same
stream (stdout).
Just because dumbasses sometimes fail to use printf() in a correct
manner doesn't mean that those of us who aren't dumbasses should not
use it.
I wasn't saying don't use it, I was saying don't mix.

--
Ian Collins.
Feb 28 '07 #13
Ian Collins wrote:
>
I've seen real problems where printf and iostreams were used on the same
stream (stdout).
There shouldn't be any problems with a standard-conforming library,
unless the program does something stupid. cout and stdout are
synchronized, so output comes out just the way you'd expect.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Feb 28 '07 #14
Pete Becker wrote:
Ian Collins wrote:
>>
I've seen real problems where printf and iostreams were used on the same
stream (stdout).

There shouldn't be any problems with a standard-conforming library,
unless the program does something stupid. cout and stdout are
synchronized, so output comes out just the way you'd expect.
The problems I had were with threaded code where the access guards for
the streams got in a mess (IIRC there were different guards for
iostreams and stdio streams). Anyway, this was in pre-standard days.

--
Ian Collins.
Feb 28 '07 #15
"kwikius" <an**@servocomm .freeserve.co.u kwrote in message
news:11******** **************@ m58g2000cwm.goo glegroups.com.. .
[...]
Yep. I figured it out eventaully I think.
It seems to be possible but at the expense of always allocating your
char array oversize by alignment_of<T-1. Its not possible to know
where on the stack the lmem object will go.
[...]
But consider a variant, and you are smokin', treating stack like heap
with no alloc overhead...

This may be the purpose behind the device ...
[...]

Indeed it its. I believe that I could make use of the following function
'ac_malloc_alig ned' :

http://appcore.home.comcast.net/appc...appcore_c.html
(2nd to last function in the file...)

to get the alignment correct. Your correct in that I have to endure a
penalty of an "over allocation" in order to get the alignment correct. I was
hoping to align the "main buffer" to a multiple of the size of a
architecture specific L2 cache-line then align is on L2 cacheline boundary.
I could then start to allocate the individual buffered chunks from there...
Well, I will post some more source code in a day or two... So far, it should
still be in the realm of standard c++... However, once I get this first
phase out of the way... well, the code is going to get HIGHLY architecture
specific as the so-called "critical" parts of my memory allocator algorithm
wart the interlocked RMW instructions and memory barriers are packed away
into ia32 and SPARC assembly language.
Mar 1 '07 #16
[...]Indeed it its. I believe that I could make use of the following
function
'ac_malloc_alig ned' :
Minus the explicit heap allocation of course!

;^)
Mar 1 '07 #17
On 28 Feb, 23:59, "Chris Thomasson" <cris...@comcas t.netwrote:

I have been lazily following your thread related stuff. One day I may
be able to make use of it, though currently it all looks pretty opaque
I'm afraid.

On this subject I had hoped that I could use boost::shared_p tr for a
GUI smart_ptr class but unfortunately it doesnt work in that
situation, so I have been forced to roll my own.

Here is some (slightly confused discussion baout it):

http://tinyurl.com/3debeh

I have been sticking to single threaded version and probably will for
the time being, but if I get onto anything more substatial it will
need to work with some form of concurrency, so at (if I get to) that
point I will certainly be interested...

regards
Andy Little
Mar 1 '07 #18
"Chris Thomasson" <cr*****@comcas t.netwrote in message
news:Xf******** *************** *******@comcast .com...
"kwikius" <an**@servocomm .freeserve.co.u kwrote in message
news:11******** **************@ m58g2000cwm.goo glegroups.com.. .
[...]
>Yep. I figured it out eventaully I think.
It seems to be possible but at the expense of always allocating your
char array oversize by alignment_of<T-1. Its not possible to know
where on the stack the lmem object will go.
[...]
>But consider a variant, and you are smokin', treating stack like heap
with no alloc overhead...

This may be the purpose behind the device ...
[...]

Indeed it its. I believe that I could make use of the following function
'ac_malloc_alig ned' :

http://appcore.home.comcast.net/appc...appcore_c.html
(2nd to last function in the file...)
Okay. I was thinking of something kind of like:
<pseudo-code/sketch>
---------

#include <cstdio>
#include <cstddef>
#include <cassert>
#include <new>
template<size_t T_basesz, size_t T_metasz, size_t T_basealign>
class lmem {
unsigned char m_basebuf[T_basesz + T_metasz + T_basealign - 1];
unsigned char *m_alignbuf;

private:
static unsigned char* alignptr(unsign ed char *buf, size_t alignsz) {
ptrdiff_t base = buf - static_cast<uns igned char*>(0);
ptrdiff_t offset = base % alignsz;
ptrdiff_t result = (! offset) ? base : base + alignsz - offset;
assert(! result % alignsz);
return static_cast<uns igned char*>(0) + result;
}

public:
lmem() : m_alignbuf(alig nptr(m_basebuf, T_basealign)) {}
template<typena me T>
void* loadptr() const {
assert(T_basesz >= (sizeof(T) * 2) - 1);
return alignptr(m_alig nbuf, sizeof(T));
}
void* loadmetaptr() const {
return m_alignbuf + T_basesz;
}
};
namespace detail {
namespace os {
namespace cfg {
enum config_e {
PAGE_SZ = 8192
};
}}

namespace arch {
namespace cfg {
enum config_e {
L2_CACHELINE_SZ = 64
};
}}

namespace lheap {
namespace cfg {
enum config_e {
BUF_SZ = os::cfg::PAGE_S Z * 2,
BUF_ALIGN_SZ = arch::cfg::L2_C ACHELINE_SZ,
BUF_METADATA_SZ = sizeof(void*)
};
}}
}
template<typena me T>
class autoptr_calldto r {
T *m_ptr;
public:
autoptr_calldto r(T *ptr) : m_ptr(ptr) {}
~autoptr_calldt or() {
if (m_ptr) { m_ptr->~T(); }
}
T* loadptr() const {
return m_ptr;
}
};

namespace lheap {
using namespace detail::lheap;
}

class foo {
public:
foo() { printf("(%p)foo ::foo()", (void*)this); }
~foo() { printf("(%p)foo ::~foo()", (void*)this); }
};

int main() {
{
lmem<lheap::cfg ::BUF_SZ,
lheap::cfg::BUF _METADATA_SZ,
lheap::cfg::BUF _ALIGN_SZfoomem ;

autoptr_calldto r<foof(new (foomem.loadptr <foo>()) foo);
}

printf("\npress any key to exit...\n"); getchar();
return 0;
}

The lmem object is meant to be barebones low-level buffer object in the
"system-code" part of my c++ memory allocator library I am currently
developing. Basically, I am going for a fairly thin wrapper over the
allocator pseudo-code I posted; you can follow the link to the invention to
look at it. Humm... As you can probably clearly see by now, I am a hard core
C programmer and I must admit that my c++ could skills can be improved
upon... So, any ideas for interface designs, or even system level design,
are welcome...

I was thinking about using a single lmem object per-thread and then
subsequently using it to allocate all of the per-thread data-structures my
allocator algorithms relies upon. So, essentially, every single
data-structure that makes up my multi-threaded allocator design can be based
entirely in the stacks of a plurality of threads. Wow, this has the
potential to have simply excellent scalability and performance
characteristics ; anyway... ;^)

So, since lmem is all I "really" need and I don't want to post any of the
implementations details wrt lock-free algorithms, ect... what else can I
discuss here that's on topic... I am going to need to finally decide on
exactly how I will be laying out the per-thread structures in the buffer
managed by lmem...

Then I need to think about how I am going to ensure that the threads stacks
don't go away when any of its allocator structures are in use by any other
thread. The following technique currently works fine:

<pseudo-code>

template

class mylib_thread {
// ...
public:
~mylib_thread() {
/*
special atomic-decrement-and-wait function;
off-topic, not shown here...
we can discuss the lock-free aspects of my algorithm
over on comp.programmin g.threads...
*/
}
};

user_thread_ent ry(mylib_thread &_this) {
// user application code
}

libsys_thread_e ntry(...) {
// library system code

lmem<lheap::cfg ::BUF_SZ,
lheap::cfg::BUF _METADATA_SZ,
lheap::cfg::BUF _ALIGN_SZfoomem ;

autoptr_calldto r<foo_this(new (_thismem.loadp tr<mylib_thread >())
mylib_thread);

user_thread_ent ry(*_this.loadp tr());
}


Any thoughts?
Mar 2 '07 #19
On 2 Mar, 11:48, "Chris Thomasson" <cris...@comcas t.netwrote:

<...>
Any thoughts?
First I don't know enough about threads to make any constructive
commnts. OTOH give me access to the system timer and program counter
and ability to disable interrupts and allow me to write interrrupt
service routines, in fact control of the system event mechanisms and I
would be happy. OTOH I guess I should head over to the threads
newsgroup and try to understand them better. Anyway here are some
thoughts (in contradiction to the above) thouh I havent studied your
code in any depth:

Firstly I don't understand from that the way you want to use the
device, but I would guess it would be restricted to specialised use,
however a few (confused) thoughts spring to mind. The first is that in
my environment the stack is actually quite a scarce resource, default
around 1 Mb (In VC7.1), after which you get a (non C++) stack overflow
in VC7.1. I presume you can modify this though.

The heap on the other hand can be looked on as a(almost) infinite
resource, even if you run out of physical memory the system will start
swapping memory to from disk. Very system specific though I guess..

In that sense I would guess that use of the stack is by nature not as
scaleable as using the heap.

So from that point of view it is interesting to try to come up with
scenarios where you would use the device.
>From the viewpoint of allocationg on the stack, essentially you have
to know how much you are going to allocate beforehand, but if the
stack is a scarce resource,its not viable to treat it in the same
carefree way as the heap proper and just allocate huge. Of course it
may be possible to use some assembler to write your own functions
grabbing runtime amounts of stack, which would maybe make the device
more versatile.

For use as an allocator, the alternative is of course to use malloc
for your one time start up allocation for your own allocator, and then
after the start up cost whether you allocated on the heap or stack I
would guess the cost of getting memory from the allocator is going to
be the same regardless where it is.

Therefore the main potential use of such a device would be where you
know the size of fixed size allocation, but don't know what types you
want to put in it, and where you doing your start up allocation
frequently. This may be in some situation where you actually dont want
to use the function call mechanism for some reason, IOW using the
scheme as a sort of scratch space where you are modifying the types in
the scratch space dependent on what you are doing. This does somehow
bring to mind use in embedded systems where there is no heap as such
so the scheme could be used as a heap for systems without a heap as it
were. You would then presumably need to keep passing a reference to
the allocator in to child functions or put it in a global variable.

Overall then its difficult to know where the advantages outweigh the
difficulties.

regards
Andy Little





Mar 3 '07 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

25
3795
by: Magnus Lie Hetland | last post by:
Is there any interest in a (hypothetical) standard graph API (with 'graph' meaning a network, consisting of nodes and edges)? Yes, we have the standard ways of implementing graphs through (e.g.) dicts mapping nodes to neighbor-sets, but if one wants a graph that's implemented in some other way, this may not be the most convenient (or abstract) interface to emulate. It might be nice to have the kind of polymorphic freedom that one has with,...
6
8331
by: John Bentley | last post by:
John Bentley writes at this level: If we think about our savings accounts then division never comes in (as far as I can see). We deposit and withdraw exact amounts most of the time. Occasionaly we get an interest payment. Unless the bank is cruel to its developers the interest figure will be able to be exactly represented by a computer, something like 4.1% as opposed to 4 1/3 % 125.78 * ' Initial Balance 04.1% -------
29
2410
by: David Eng | last post by:
In replying to P.J. Plauger ( http://groups.google.com/groups?dq=&hl=en&lr=&ie=UTF-8&threadm=1089204435.746211%40master.nyc.kbcfp.com&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DUTF-8%26group%3Dcomp.lang.c%252B%252B.moderated ) who responded my post in comp.long.c++ moderated neww group regarding "C++ standard and C++/CLI" topic, I worte the following post which was sensor by comp.lang.c++.moderated: ...
43
5026
by: Steven T. Hatton | last post by:
Now that I have a better grasp of the scope and capabilities of the C++ Standard Library, I understand that products such as Qt actually provide much of the same functionality through their own libraries. I'm not sure if that's a good thing or not. AFAIK, most of Qt is compatable with the Standard Library. That is, QLT can interoperate with STL, and you can convert back and forth between std::string and Qt::QString, etc. Are there any...
52
3792
by: lovecreatesbeauty | last post by:
Why the C standard committee doesn't provide a standard implementation including the C compiler and library when the language standard document is published? C works on the abstract model of low level machine. C stands for portability and platform and machine independent. If the C compiler and C standard library are written in C itself, is it possible that one "standard" C compiler plus library is enough? The standard implementation is...
24
2456
by: noridotjabi | last post by:
Why isn't there a Graphical User Interface standard? Think about it for a second. You may say, well evey systems API for GUIs is differnt, but do take into acound: every operating system requires differnt compilations and often totally differnt compiler code. For instance gcc on windows in not the same code as gcc on linux/unix but it produces the same programs when you use it to compile. Yes you can take something like: #include...
132
4660
by: Frederick Gotham | last post by:
If we look at a programming language such as C++: When an updated Standard comes out, everyone adopts it and abandons the previous one. It seems though that things aren't so clear-cut in the C community. It would seem that C99 is the most up-to-date Standard, but far more people seem to be working off the C89 Standard. Could someone please explain to me why this is so? --
1
3227
by: manish deshpande | last post by:
Hi, When i'm installing MySQL-server-standard-5.0.24a-0.rhel3.i386.rpm by the following command: rpm -i MySQL-server-standard-5.0.24a-0.rhel3.i386.rpm the following error is being shown: warning: MySQL-server-standard-5.0.24a-0.rhel3.i386.rpm: V3 DSA signature: NOKEY, key ID 5072e1f5 file /etc/my.cnf from install of MySQL-server-standard-5.0.24a-0.rhel3 conflicts with file from package mysql-3.23.58-1 file...
26
3829
by: Rick | last post by:
I'm told that "#pragma once" has made it into the ISO standard for either C or C++. I can't find any reference to that anywhere. If it's true, do any of you have a reference I can use? Thanks...
270
9564
by: jacob navia | last post by:
In my "Happy Christmas" message, I proposed a function to read a file into a RAM buffer and return that buffer or NULL if the file doesn't exist or some other error is found. It is interesting to see that the answers to that message prove that programming exclusively in standard C is completely impossible even for a small and ridiculously simple program like the one I proposed. 1 I read the file contents in binary mode, what should...
0
10350
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10157
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10097
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8983
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7505
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5386
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5518
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4055
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3658
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.