PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.c > standard memory allocator alignment issue...
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
standard memory allocator alignment issue...

Réponse
 
LinkBack Outils de la discussion
Vieux 12/05/2008, 07h13   #1
Chris Thomasson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut standard memory allocator alignment issue...

How many C compilers provide extensions which allow for a standard
implementation of the following hack?
__________________________________________________ __________________
#include <stdio.h>


typedef union aligner_types_u aligner_types;
typedef struct aligner_offset_s aligner_offset;


union aligner_types_u {
char char_;
short s_l;
int i_;
long l_;
double d_;
long double ld_;
float f_;
void *p_;
char (*fp0_) (char);
long double (*fp1_) (char, long double);
union aligner_types* uap_;
/* long long ll_; */
/* [...] */
};


struct aligner_offset_s {
char offset;
aligner_types types;
};


#define ALIGN_MAX ( \
sizeof(aligner_offset) > sizeof(aligner_types) \
? sizeof(aligner_offset) - sizeof(aligner_types) \
: sizeof(aligner_types) \
)


int main() {
printf("ALIGN_MAX == %d\n\nhit enter to exit...\n", ALIGN_MAX);
getchar();
return 0;
}

__________________________________________________ __________________



Thanks...



BTW, the ALIGN_MAX macro is needed because using a sizeof(aligner_types)
alone is not sufficient... How many people are running platforms where
(ALIGN_MAX == 8) is true?

  Réponse avec citation
Vieux 12/05/2008, 07h24   #2
Chris Thomasson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

"Chris Thomasson" <cristom@comcast.net> wrote in message
news:5umdnWjfo9PPQrrVnZ2dnUVZ_rLinZ2d@comcast.com. ..
> How many C compilers provide extensions which allow for a standard
> implementation of the following hack?

[...]

Standard in the sense of being portable within the various versions of a
given vendors C compiler...

:^o

  Réponse avec citation
Vieux 12/05/2008, 13h14   #3
Eric Sosman
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

Chris Thomasson wrote:
> How many C compilers provide extensions which allow for a standard
> implementation of the following hack?
> __________________________________________________ __________________
> #include <stdio.h>
>
>
> typedef union aligner_types_u aligner_types;
> typedef struct aligner_offset_s aligner_offset;
>
>
> union aligner_types_u {
> char char_;
> short s_l;
> int i_;
> long l_;
> double d_;
> long double ld_;
> float f_;
> void *p_;
> char (*fp0_) (char);
> long double (*fp1_) (char, long double);
> union aligner_types* uap_;
> /* long long ll_; */
> /* [...] */
> };
>
>
> struct aligner_offset_s {
> char offset;
> aligner_types types;
> };
>
>
> #define ALIGN_MAX ( \
> sizeof(aligner_offset) > sizeof(aligner_types) \
> ? sizeof(aligner_offset) - sizeof(aligner_types) \
> : sizeof(aligner_types) \
> )
>
>
> int main() {
> printf("ALIGN_MAX == %d\n\nhit enter to exit...\n", ALIGN_MAX);
> getchar();
> return 0;
> }
>
> __________________________________________________ __________________
>
>
>
> Thanks...
>
>
>
> BTW, the ALIGN_MAX macro is needed because using a sizeof(aligner_types)
> alone is not sufficient... How many people are running platforms where
> (ALIGN_MAX == 8) is true?


Observation #1: It is impossible that the "else" branch
of ALIGN_MAX' expansion will be evaluated, so you might as
well just put `42' there.

Observation #2: ALIGN_MAX computes the number of bytes
in the struct, minus one for the `char' element, minus the
number of padding bytes before the union, minus the number
of padding bytes *after* the union. I've never seen a
compiler where that final term would be non-zero, but ...

Observation #3: On some platforms the program will say
"ALIGN_MAX == 0", because that's one of the likely outcomes
of the undefined behavior in the printf() call.

Observation #4: I'm not entirely sure, but I think the
"extension" you seek is the offsetof macro in <stddef.h>.

--
Eric Sosman
esosman@ieee-dot-org.invalid
  Réponse avec citation
Vieux 12/05/2008, 22h41   #4
Chris Thomasson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

"Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message
news:0f-dnYX0zdkuqbXVnZ2dnUVZ_qTinZ2d@comcast.com...
> Chris Thomasson wrote:
>> How many C compilers provide extensions which allow for a standard
>> implementation of the following hack?
>> __________________________________________________ __________________

[...]
>> __________________________________________________ __________________

[...]
>> BTW, the ALIGN_MAX macro is needed because using a sizeof(aligner_types)
>> alone is not sufficient... How many people are running platforms where
>> (ALIGN_MAX == 8) is true?

>
> Observation #1: It is impossible that the "else" branch
> of ALIGN_MAX' expansion will be evaluated, so you might as
> well just put `42' there.


> Observation #2: ALIGN_MAX computes the number of bytes
> in the struct, minus one for the `char' element, minus the
> number of padding bytes before the union, minus the number
> of padding bytes *after* the union. I've never seen a
> compiler where that final term would be non-zero, but ...


> Observation #3: On some platforms the program will say
> "ALIGN_MAX == 0", because that's one of the likely outcomes
> of the undefined behavior in the printf() call.


Totally agree with everything you said. As for printf, at least I should
have it formatted for an unsigned integer: %u. ;^(



> Observation #4: I'm not entirely sure, but I think the
> "extension" you seek is the offsetof macro in <stddef.h>.


You got it:
__________________________________________________ _________________
#include <stdio.h>
#include <stddef.h>


typedef union aligner_types_u aligner_types;
typedef struct aligner_offset_s aligner_offset;


union aligner_types_u {
char char_; short s_l; int i_; long l_;
double d_; long double ld_; float f_;
union aligner_types* uap_;
void *p_; char (*fp0_) (char);
long double (*fp1_) (char, long double);
/* long long ll_; */
/* [...] */
};


struct aligner_offset_s {
char offset;
aligner_types types;
};


#define ALIGN_MAX offsetof(aligner_offset, types)


int main() {
printf("ALIGN_MAX == %u\n\nhit enter to exit...\n", ALIGN_MAX);
getchar();
return 0;
}
__________________________________________________ _________________



I am trying to come up with somewhat "portable" hack that can attempt to
determine maximum alignment for integral types across a number of different
compilers.

  Réponse avec citation
Vieux 12/05/2008, 22h51   #5
Chris Thomasson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

"Chris Thomasson" <cristom@comcast.net> wrote in message
news:tf-dndgJDOpIJbXVnZ2dnUVZ_hOdnZ2d@comcast.com...
> "Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message
> news:0f-dnYX0zdkuqbXVnZ2dnUVZ_qTinZ2d@comcast.com...
>> Chris Thomasson wrote:
>>> How many C compilers provide extensions which allow for a standard
>>> implementation of the following hack?
>>> __________________________________________________ __________________

> [...]
>>> __________________________________________________ __________________

[...]
>> Observation #4: I'm not entirely sure, but I think the
>> "extension" you seek is the offsetof macro in <stddef.h>.

>
> You got it:
> __________________________________________________ _________________

[...]
> __________________________________________________ _________________


> I am trying to come up with somewhat "portable" hack that can attempt to
> determine maximum alignment for integral types across a number of
> different compilers.


I have been successfully using the previous method in several
general-purpose memory allocators. However, I wanted to see if there is a
better way; offsetof works fine. BTW, does anybody know why there is not
something like ALIGN_MAX in <limits.h> already?

  Réponse avec citation
Vieux 12/05/2008, 23h08   #6
Eric Sosman
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

Chris Thomasson wrote:
> "Eric Sosman" <esosman@ieee-dot-org.invalid> wrote...
>> Chris Thomasson wrote:
>> [... printf with "%d" for a size_t ...]
>> Observation #3: On some platforms the program will say
>> "ALIGN_MAX == 0", because that's one of the likely outcomes
>> of the undefined behavior in the printf() call.

>
> Totally agree with everything you said. As for printf, at least I should
> have it formatted for an unsigned integer: %u. ;^(


Use "%u" *and* convert the size_t value to `unsigned int'.
(Or you can use "%zu" with a C99 library.) The particular
misbehavior I mentioned could occur on a BigEndian system
with a 64-bit size_t and a 32-bit int, where a plain "%d" or
"%u" would pick up the high-order (all-zero) half of the
double-wide size_t number ...

>> Observation #4: I'm not entirely sure, but I think the
>> "extension" you seek is the offsetof macro in <stddef.h>.

>
> You got it:
> [...]
> I am trying to come up with somewhat "portable" hack that can attempt to
> determine maximum alignment for integral types across a number of
> different compilers.


The difficulties are in enumerating all the integer types
(easy in C90, hard in C99) and in making useful manipulations
of pointers-as-integers (hard in C90, easier in C99 but still
not a walk in the park). For simple "flat" memory models the
kind of thing you're doing is straightforward, but there's the
nagging possibility that the code may find its way to a more
baroque environment ...

--
Eric.Sosman@sun.com

  Réponse avec citation
Vieux 12/05/2008, 23h22   #7
Eric Sosman
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

Chris Thomasson wrote:
> [... determining alignment with a struct and offsetof ...]
>
> I have been successfully using the previous method in several
> general-purpose memory allocators. However, I wanted to see if there is
> a better way; offsetof works fine. BTW, does anybody know why there is
> not something like ALIGN_MAX in <limits.h> already?


The Rationale doesn't say why not. My guess (and it's only
a guess) is that the Committee didn't want to get too involved
in specifying exactly how pointers convert to and from integers.
Without knowledge of which integer bits have what significance,
you can't make effective use of things like ALIGN_MAX.

--
Eric.Sosman@sun.com
  Réponse avec citation
Vieux 12/05/2008, 23h41   #8
Chris Thomasson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

"Eric Sosman" <Eric.Sosman@sun.com> wrote in message
news:1210630927.374478@news1nwk...
> Chris Thomasson wrote:
>> [... determining alignment with a struct and offsetof ...]
>>
>> I have been successfully using the previous method in several
>> general-purpose memory allocators. However, I wanted to see if there is a
>> better way; offsetof works fine. BTW, does anybody know why there is not
>> something like ALIGN_MAX in <limits.h> already?

>
> The Rationale doesn't say why not. My guess (and it's only
> a guess) is that the Committee didn't want to get too involved
> in specifying exactly how pointers convert to and from integers.
> Without knowledge of which integer bits have what significance,
> you can't make effective use of things like ALIGN_MAX.


Humm, a compiler vendor already has to supply a malloc implementation which
returns an address that is aligned on a sufficient boundary for all integral
types; right? Well, IMVHO, the standard could mention that a vendor shall
set the value of ALIGN_MAX to a sufficient boundary analogous to the
non-NULL return value of malloc which can accompany the alignment of any
integral type. The rational is that a vendor can likely extract ALIGN_MAX
from their existing malloc implementation...

Is that total crap?

;^)

  Réponse avec citation
Vieux 13/05/2008, 00h02   #9
Spiros Bousbouras
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

On 12 May, 23:41, "Chris Thomasson" <cris...@comcast.net> wrote:
> "Eric Sosman" <Eric.Sos...@sun.com> wrote in message
>
> news:1210630927.374478@news1nwk...
>
> > Chris Thomasson wrote:
> >> [... determining alignment with a struct and offsetof ...]

>
> >> I have been successfully using the previous method in several
> >> general-purpose memory allocators. However, I wanted to see if there is a
> >> better way; offsetof works fine. BTW, does anybody know why there is not
> >> something like ALIGN_MAX in <limits.h> already?

>
> > The Rationale doesn't say why not. My guess (and it's only
> > a guess) is that the Committee didn't want to get too involved
> > in specifying exactly how pointers convert to and from integers.
> > Without knowledge of which integer bits have what significance,
> > you can't make effective use of things like ALIGN_MAX.

>
> Humm, a compiler vendor already has to supply a malloc implementation which
> returns an address that is aligned on a sufficient boundary for all integral
> types; right? Well, IMVHO, the standard could mention that a vendor shall
> set the value of ALIGN_MAX to a sufficient boundary analogous to the
> non-NULL return value of malloc which can accompany the alignment of any
> integral type. The rational is that a vendor can likely extract ALIGN_MAX
> from their existing malloc implementation...


If you had ALIGN_MAX what would you do with it ?

  Réponse avec citation
Vieux 13/05/2008, 00h13   #10
Richard Tobin
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

In article <c2857956-f78b-47c9-97a9-a262af5535f6@r66g2000hsg.googlegroups.com>,
Spiros Bousbouras <spibou@gmail.com> wrote:

>If you had ALIGN_MAX what would you do with it ?


Write an allocator that returns memory adequately aligned for any
object, perhaps.

-- Richard
--
:wq
  Réponse avec citation
Vieux 13/05/2008, 00h20   #11
Keith Thompson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

Spiros Bousbouras <spibou@gmail.com> writes:
> On 12 May, 23:41, "Chris Thomasson" <cris...@comcast.net> wrote:
>> "Eric Sosman" <Eric.Sos...@sun.com> wrote in message
>>
>> news:1210630927.374478@news1nwk...
>>
>> > Chris Thomasson wrote:
>> >> [... determining alignment with a struct and offsetof ...]

>>
>> >> I have been successfully using the previous method in several
>> >> general-purpose memory allocators. However, I wanted to see if there is a
>> >> better way; offsetof works fine. BTW, does anybody know why there is not
>> >> something like ALIGN_MAX in <limits.h> already?

>>
>> > The Rationale doesn't say why not. My guess (and it's only
>> > a guess) is that the Committee didn't want to get too involved
>> > in specifying exactly how pointers convert to and from integers.
>> > Without knowledge of which integer bits have what significance,
>> > you can't make effective use of things like ALIGN_MAX.

>>
>> Humm, a compiler vendor already has to supply a malloc implementation which
>> returns an address that is aligned on a sufficient boundary for all integral
>> types; right? Well, IMVHO, the standard could mention that a vendor shall
>> set the value of ALIGN_MAX to a sufficient boundary analogous to the
>> non-NULL return value of malloc which can accompany the alignment of any
>> integral type. The rational is that a vendor can likely extract ALIGN_MAX
>> from their existing malloc implementation...

>
> If you had ALIGN_MAX what would you do with it ?


One thing I might do is write my own memory allocator. Call malloc()
once to get a big chunk of memory (guaranteed to be aligned properly),
then dole out properly-aligned subchunks of it in response to
my_malloc() calls. Free everything at once by free()ing the big
chunk. Without ALIGN_MAX, I can't think of a portable way to
guarantee that the pointers returned by my_malloc are properly
aligned.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
  Réponse avec citation
Vieux 13/05/2008, 00h22   #12
Ian Collins
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

Chris Thomasson wrote:
> "Eric Sosman" <Eric.Sosman@sun.com> wrote in message
> news:1210630927.374478@news1nwk...
>> Chris Thomasson wrote:
>>> [... determining alignment with a struct and offsetof ...]
>>>
>>> I have been successfully using the previous method in several
>>> general-purpose memory allocators. However, I wanted to see if there
>>> is a better way; offsetof works fine. BTW, does anybody know why
>>> there is not something like ALIGN_MAX in <limits.h> already?

>>
>> The Rationale doesn't say why not. My guess (and it's only
>> a guess) is that the Committee didn't want to get too involved
>> in specifying exactly how pointers convert to and from integers.
>> Without knowledge of which integer bits have what significance,
>> you can't make effective use of things like ALIGN_MAX.

>
> Humm, a compiler vendor already has to supply a malloc implementation
> which returns an address that is aligned on a sufficient boundary for
> all integral types; right? Well, IMVHO, the standard could mention that
> a vendor shall set the value of ALIGN_MAX to a sufficient boundary
> analogous to the non-NULL return value of malloc which can accompany the
> alignment of any integral type. The rational is that a vendor can likely
> extract ALIGN_MAX from their existing malloc implementation...
>
> Is that total crap?
>

That depends on whether the compiler supplies its own runtime, or uses
one supplied by the host environment.

--
Ian Collins.
  Réponse avec citation
Vieux 13/05/2008, 00h32   #13
Ian Collins
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

Chris Thomasson wrote:
> "Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message
> news:0f-dnYX0zdkuqbXVnZ2dnUVZ_qTinZ2d@comcast.com...
>> Chris Thomasson wrote:
>>> How many C compilers provide extensions which allow for a standard
>>> implementation of the following hack?
>>> __________________________________________________ __________________

> [...]
>>> __________________________________________________ __________________

> [...]
>>> BTW, the ALIGN_MAX macro is needed because using a
>>> sizeof(aligner_types) alone is not sufficient... How many people are
>>> running platforms where (ALIGN_MAX == 8) is true?

>>
>> Observation #1: It is impossible that the "else" branch
>> of ALIGN_MAX' expansion will be evaluated, so you might as
>> well just put `42' there.

>
>> Observation #2: ALIGN_MAX computes the number of bytes
>> in the struct, minus one for the `char' element, minus the
>> number of padding bytes before the union, minus the number
>> of padding bytes *after* the union. I've never seen a
>> compiler where that final term would be non-zero, but ...

>
>> Observation #3: On some platforms the program will say
>> "ALIGN_MAX == 0", because that's one of the likely outcomes
>> of the undefined behavior in the printf() call.

>
> Totally agree with everything you said. As for printf, at least I should
> have it formatted for an unsigned integer: %u. ;^(
>
>
>
>> Observation #4: I'm not entirely sure, but I think the
>> "extension" you seek is the offsetof macro in <stddef.h>.

>
> You got it:
> __________________________________________________ _________________
> #include <stdio.h>
> #include <stddef.h>
>
>
> typedef union aligner_types_u aligner_types;
> typedef struct aligner_offset_s aligner_offset;
>
>
> union aligner_types_u {
> char char_; short s_l; int i_; long l_;
> double d_; long double ld_; float f_;
> union aligner_types* uap_;
> void *p_; char (*fp0_) (char);
> long double (*fp1_) (char, long double);
> /* long long ll_; */
> /* [...] */
> };
>
>
> struct aligner_offset_s {
> char offset;
> aligner_types types;
> };
>
>
> #define ALIGN_MAX offsetof(aligner_offset, types)
>
>
> int main() {
> printf("ALIGN_MAX == %u\n\nhit enter to exit...\n", ALIGN_MAX);
> getchar();
> return 0;
> }
> __________________________________________________ _________________
>
>
>
> I am trying to come up with somewhat "portable" hack that can attempt to
> determine maximum alignment for integral types across a number of
> different compilers.
>

How would this code with the situation where sizeof(long long) == 8 and
sizeof(long double) = 12? In that case, 16 would probably be a sensible
value for ALIGN_MAX. Not easy to calculate as a compile time constant.

--
Ian Collins.
  Réponse avec citation
Vieux 13/05/2008, 00h36   #14
Chris Thomasson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

"Ian Collins" <ian-news@hotmail.com> wrote in message
news:68s1qcF2umj15U2@mid.individual.net...
> Chris Thomasson wrote:
>> "Eric Sosman" <Eric.Sosman@sun.com> wrote in message
>> news:1210630927.374478@news1nwk...
>>> Chris Thomasson wrote:
>>>> [... determining alignment with a struct and offsetof ...]
>>>>
>>>> I have been successfully using the previous method in several
>>>> general-purpose memory allocators. However, I wanted to see if there
>>>> is a better way; offsetof works fine. BTW, does anybody know why
>>>> there is not something like ALIGN_MAX in <limits.h> already?
>>>
>>> The Rationale doesn't say why not. My guess (and it's only
>>> a guess) is that the Committee didn't want to get too involved
>>> in specifying exactly how pointers convert to and from integers.
>>> Without knowledge of which integer bits have what significance,
>>> you can't make effective use of things like ALIGN_MAX.

>>
>> Humm, a compiler vendor already has to supply a malloc implementation
>> which returns an address that is aligned on a sufficient boundary for
>> all integral types; right? Well, IMVHO, the standard could mention that
>> a vendor shall set the value of ALIGN_MAX to a sufficient boundary
>> analogous to the non-NULL return value of malloc which can accompany the
>> alignment of any integral type. The rational is that a vendor can likely
>> extract ALIGN_MAX from their existing malloc implementation...
>>
>> Is that total crap?
>>

> That depends on whether the compiler supplies its own runtime, or uses
> one supplied by the host environment.


Humm, good point indeed. Well, in that case, I guess the compiler can
probably make use of the ALIGN_MAX definition already residing in the
<limits.h> file provided by a "conforming" host environment, where
conforming means provides a version of the next standard which would include
ALIGN_MAX in <limits.h>)...

  Réponse avec citation
Vieux 13/05/2008, 00h41   #15
Chris Thomasson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

"Ian Collins" <ian-news@hotmail.com> wrote in message
news:68s2caF2umj15U3@mid.individual.net...
> Chris Thomasson wrote:
>> "Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message
>> news:0f-dnYX0zdkuqbXVnZ2dnUVZ_qTinZ2d@comcast.com...
>>> Chris Thomasson wrote:

[...]
>> __________________________________________________ _________________


>>
>> I am trying to come up with somewhat "portable" hack that can attempt to
>> determine maximum alignment for integral types across a number of
>> different compilers.
>>

> How would this code with the situation where sizeof(long long) == 8 and
> sizeof(long double) = 12? In that case, 16 would probably be a sensible
> value for ALIGN_MAX. Not easy to calculate as a compile time constant.


On GCC for 32-bit x86 windows, sizeof(double) == 8, sizeof(long double) ==
12 and the offsetof version of ALIGN_MAX is 8. I think reasoning for result
is that 4 is suitable alignment for long double and 8 is already compatible
with boundary of 4.

  Réponse avec citation
Vieux 13/05/2008, 00h56   #16
Ian Collins
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

Chris Thomasson wrote:
> "Ian Collins" <ian-news@hotmail.com> wrote in message
> news:68s2caF2umj15U3@mid.individual.net...
>> Chris Thomasson wrote:
>>> "Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message
>>> news:0f-dnYX0zdkuqbXVnZ2dnUVZ_qTinZ2d@comcast.com...
>>>> Chris Thomasson wrote:

> [...]
>>> __________________________________________________ _________________

>
>>>
>>> I am trying to come up with somewhat "portable" hack that can attempt to
>>> determine maximum alignment for integral types across a number of
>>> different compilers.
>>>

>> How would this code with the situation where sizeof(long long) == 8 and
>> sizeof(long double) = 12? In that case, 16 would probably be a sensible
>> value for ALIGN_MAX. Not easy to calculate as a compile time constant.

>
> On GCC for 32-bit x86 windows, sizeof(double) == 8, sizeof(long double)
> == 12 and the offsetof version of ALIGN_MAX is 8. I think reasoning for
> result is that 4 is suitable alignment for long double and 8 is already
> compatible with boundary of 4.


Fair enough. I have used 16 for several "semi-portable" allocators. On
each platform where these were used, the native malloc also used 16.

--
Ian Collins.
  Réponse avec citation
Vieux 13/05/2008, 01h46   #17
Chris Torek
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

>Spiros Bousbouras <spibou@gmail.com> writes:
>> If you had ALIGN_MAX what would you do with it ?


In article <lny76fkt2w.fsf@nuthaus.mib.org>
Keith Thompson <kst-u@mib.org> wrote:
>One thing I might do is write my own memory allocator. ...


As I have noted (several times, I think) in the past, ALIGN_MAX
(or ALIGNBYTES, as we spelled it in 4.4BSD) is necessary but not
sufficient. You also need something that takes an "unaligned"
pointer and produces the "aligned version" of that pointer, or the
offset that makes it aligned. (This need only work for byte
pointers, i.e., "unsigned char *", although it is probably more
convenient if it is somehow generic.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: gmail (figure it out) http://web.torek.net/torek/index.html
  Réponse avec citation
Vieux 13/05/2008, 01h53   #18
Ben Bacarisse
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

Keith Thompson <kst-u@mib.org> writes:

> Spiros Bousbouras <spibou@gmail.com> writes:
>> On 12 May, 23:41, "Chris Thomasson" <cris...@comcast.net> wrote:
>>> "Eric Sosman" <Eric.Sos...@sun.com> wrote in message
>>>
>>> news:1210630927.374478@news1nwk...
>>>
>>> > Chris Thomasson wrote:
>>> >> [... determining alignment with a struct and offsetof ...]
>>>
>>> >> I have been successfully using the previous method in several
>>> >> general-purpose memory allocators. However, I wanted to see if there is a
>>> >> better way; offsetof works fine. BTW, does anybody know why there is not
>>> >> something like ALIGN_MAX in <limits.h> already?
>>>
>>> > The Rationale doesn't say why not. My guess (and it's only
>>> > a guess) is that the Committee didn't want to get too involved
>>> > in specifying exactly how pointers convert to and from integers.
>>> > Without knowledge of which integer bits have what significance,
>>> > you can't make effective use of things like ALIGN_MAX.
>>>
>>> Humm, a compiler vendor already has to supply a malloc implementation which
>>> returns an address that is aligned on a sufficient boundary for all integral
>>> types; right? Well, IMVHO, the standard could mention that a vendor shall
>>> set the value of ALIGN_MAX to a sufficient boundary analogous to the
>>> non-NULL return value of malloc which can accompany the alignment of any
>>> integral type. The rational is that a vendor can likely extract ALIGN_MAX
>>> from their existing malloc implementation...

>>
>> If you had ALIGN_MAX what would you do with it ?

>
> One thing I might do is write my own memory allocator. Call malloc()
> once to get a big chunk of memory (guaranteed to be aligned properly),
> then dole out properly-aligned subchunks of it in response to
> my_malloc() calls. Free everything at once by free()ing the big
> chunk. Without ALIGN_MAX, I can't think of a portable way to
> guarantee that the pointers returned by my_malloc are properly
> aligned.


The suggestion seems to be that ALIGN_MAX is some arithmetic value. I
can't see a way to adjust a pointer using it in any potable way. I
think this is the point behind Eric's "Without knowledge of which
integer bits have what significance, you can't make effective use of
things like ALIGN_MAX". The standard declines to say anything about
what the arithmetic value of a well-aligned pointer is.

If you are assuming that the suggestion is for a function-line macro:

#define ALIGN_MAX(p)

that behaves like a function declared void *ALIGN_MAX(void *) which
adjusts the pointer it is given, then I agree it would be possible to
write an allocator. (But I would suggest the name be lower-cased to
match things like offsetof and changed to sound less like a constant
-- another parameter might also be required to indicate "direction").

--
Ben.
  Réponse avec citation
Vieux 13/05/2008, 02h26   #19
Eric Sosman
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

Ben Bacarisse wrote:
>
> The suggestion seems to be that ALIGN_MAX is some arithmetic value. I
> can't see a way to adjust a pointer using it in any potable way.


Ahh! That wets the whistle proper, that does! Barkeep,
another round of Jack Daniel's Old Number (1uL << ALIGN_BITS)-1
for these good people, if you please.

--
Eric Sosman
esosman@ieee-dot-org.invalid
  Réponse avec citation
Vieux 13/05/2008, 03h00   #20
Chris Thomasson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

"Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message
news:877idz81nm.fsf@bsb.me.uk...
> Keith Thompson <kst-u@mib.org> writes:
>
>> Spiros Bousbouras <spibou@gmail.com> writes:
>>> On 12 May, 23:41, "Chris Thomasson" <cris...@comcast.net> wrote:
>>>> "Eric Sosman" <Eric.Sos...@sun.com> wrote in message
>>>>
>>>> news:1210630927.374478@news1nwk...
>>>>
>>>> > Chris Thomasson wrote:
>>>> >> [... determining alignment with a struct and offsetof ...]
>>>>
>>>> >> I have been successfully using the previous method in several
>>>> >> general-purpose memory allocators.

[...]
>>>>
>>>> > The Rationale doesn't say why not. My guess (and it's only
>>>> > a guess) is that the Committee didn't want to get too involved
>>>> > in specifying exactly how pointers convert to and from integers.
>>>> > Without knowledge of which integer bits have what significance,
>>>> > you can't make effective use of things like ALIGN_MAX.
>>>>
>>>> Humm, a compiler vendor already has to supply a malloc implementation
>>>> which
>>>> returns an address that is aligned on a sufficient boundary for all
>>>> integral
>>>> types; right?

[...]
>>> If you had ALIGN_MAX what would you do with it ?

>>
>> One thing I might do is write my own memory allocator.


[...]
> The suggestion seems to be that ALIGN_MAX is some arithmetic value. I
> can't see a way to adjust a pointer using it in any potable way.

[...]


I am currently using something like the following hack to align pointers on
boundaries which are powers of 2:
__________________________________________________ ________________
#include <stdio.h>
#include <stddef.h>


typedef union align_detail_types_u align_detail_types;
typedef struct align_detail_offset_s align_detail_offset;


union align_detail_types_u {
char char_; short s_l; int i_; long l_;
double d_; long double ld_; float f_;
union align_types* uap_;
void *p_; char (*fp0_) (char);
long double (*fp1_) (char, long double);
/* long long ll_; */
/* [...] */
};


struct align_detail_offset_s {
char offset;
align_detail_types types;
};


typedef long int align_detail_intptr;


#define ALIGN_MAX offsetof(align_detail_offset, types)


#define ALIGN_POW2(mp_this, mp_type) ((mp_type)( \
(((align_detail_intptr const)(mp_this)) + 1) & (-2) \
))


#define ALIGN(mp_this, mp_type, mp_align) ((mp_type)( \
(((align_detail_intptr const)(mp_this)) + \
ALIGN_POW2(mp_align, align_detail_intptr const) - 1) \
& (-ALIGN_POW2(mp_align, align_detail_intptr const)) \
))


#define ALIGN_CHECK(mp_this, mp_type, mp_align) ( \
(mp_this) == ALIGN(mp_this, mp_type, mp_align) \
)


typedef char ALIGN_DETAIL_SASSERT[
(ALIGN_MAX)
&& (ALIGN_CHECK(ALIGN_MAX, size_t, 2))
&& (ALIGN_CHECK(ALIGN_MAX, size_t, sizeof(void*)))
&& (ALIGN_CHECK(ALIGN_MAX, size_t, sizeof(void* (*) (void*))))
&& (sizeof(align_detail_intptr) >= sizeof(void*))
&& (sizeof(align_detail_intptr) >= sizeof(void* (*) (void*)))
? 1 : -1
];





#define L2CACHE_SIZE 128
#define BLOCK_SIZE 4096
#define SUPERBLOCK_SIZE (BLOCK_SIZE * 8)


int main() {
unsigned char* rawbuf[(SUPERBLOCK_SIZE * 2) - 1];

unsigned char* l2cachebuf =
ALIGN(rawbuf, unsigned char*, L2CACHE_SIZE);

unsigned char* pagebuf =
ALIGN(rawbuf, unsigned char*, BLOCK_SIZE);

unsigned char* superbuf =
ALIGN(rawbuf, unsigned char*, SUPERBLOCK_SIZE);

printf("(%u) == ALIGN_MAX\n(%p) == rawbuf\n\
(%p) == l2cachebuf\n(%p) == pagebuf\n(%p) == superbuf\n",
(unsigned)ALIGN_MAX, (void*)rawbuf, (void*)l2cachebuf,
(void*)pagebuf, (void*)superbuf);

return 0;
}

__________________________________________________ ________________




Any suggestions on how to improve the abomination?

;^)




> If you are assuming that the suggestion is for a function-line macro:
>
> #define ALIGN_MAX(p)
>
> that behaves like a function declared void *ALIGN_MAX(void *) which
> adjusts the pointer it is given, then I agree it would be possible to
> write an allocator. (But I would suggest the name be lower-cased to
> match things like offsetof and changed to sound less like a constant
> -- another parameter might also be required to indicate "direction").


That should be workable; I like it.

  Réponse avec citation
Vieux 13/05/2008, 03h07   #21
Ben Bacarisse
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

Eric Sosman <esosman@ieee-dot-org.invalid> writes:

> Ben Bacarisse wrote:
>>
>> The suggestion seems to be that ALIGN_MAX is some arithmetic value. I
>> can't see a way to adjust a pointer using it in any potable way.

>
> Ahh! That wets the whistle proper, that does!


*sigh* At least this one was mildly amusing. Most of my typos invert
the meaning of the text.

--
Ben.
  Réponse avec citation
Vieux 13/05/2008, 03h36   #22
Ben Bacarisse
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

"Chris Thomasson" <cristom@comcast.net> writes:

> "Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message
> news:877idz81nm.fsf@bsb.me.uk...

<snip>
> [...]
>> The suggestion seems to be that ALIGN_MAX is some arithmetic value. I
>> can't see a way to adjust a pointer using it in any po[r]table way.

<snip, but permit me to correct my typo!>
>
> I am currently using something like the following hack to align
> pointers on boundaries which are powers of 2:

<snip>
> typedef long int align_detail_intptr;

<snip>
> #define ALIGN_POW2(mp_this, mp_type) ((mp_type)( \
> (((align_detail_intptr const)(mp_this)) + 1) & (-2) \
> ))
>
>
> #define ALIGN(mp_this, mp_type, mp_align) ((mp_type)( \
> (((align_detail_intptr const)(mp_this)) + \
> ALIGN_POW2(mp_align, align_detail_intptr const) - 1) \
> & (-ALIGN_POW2(mp_align, align_detail_intptr const)) \
> ))

<snip>
> Any suggestions on how to improve the abomination?
>
> ;^)


I would document (maybe another clause in your static assert?) that
long must be able to hold a pointer (I assume you can't use C99's
intptr_t?).

You rely on the representation of -2 and of -ALIGN_POW2(...). I'd use
all unsigned types to avoid both. Other than that, I think this is
the best you can do (but I am no expert on this so you may well get
better advice shortly...).

--
Ben.
  Réponse avec citation
Vieux 13/05/2008, 08h46   #23
Keith Thompson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: standard memory allocator alignment issue...

Chris Torek <nospam@torek.net> writes:
>>Spiros Bousbouras <spibou@gmail.com> writes:
>>> If you had ALIGN_MAX what would you do with it ?

>
> In article <lny76fkt2w.fsf@nuthaus.mib.org>
> Keith Thompson <kst-u@mib.org> wrote:
>>One thing I might do is write my own memory allocator. ...

>
> As I have noted (several times, I think) in the past, ALIGN_MAX
> (or ALIGNBYTES, as we spelled it in 4.4BSD) is necessary but not
> sufficient. You also need something that takes an "unaligned"
> pointer and produces the "aligned version" of that pointer, or the
> offset that makes it aligned. (This need only work for byte
> pointers, i.e., "unsigned char *", although it is probably more
> convenient if it is somehow generic.)


Unless, as I said, your memory allocator uses chunks allocated by
malloc().

But yes, if you want to get your memory from somewhere other than
malloc, you do need a way to generate an aligned pointer from an
unaligned one.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"