From: D Yuniskis on
Hi,

What manifest constants do folks use to define the limits
on physical memory (of a particular flavor -- e.g., RAM)?
For example, I do:

do_something(void *location, size_t size) {
ASSERT( (location >= FIRST_RAM) && (location <= LAST_RAM) );
ASSERT( size <= ((LAST_RAM - FIRST_RAM) + 1) )
ASSERT( location <= ((LAST_RAM + 1) - size) );

....
}

This gets tedious with discontiguous memory but I don't see
any way around it.
From: Tim Wescott on
On 07/19/2010 10:58 AM, D Yuniskis wrote:
> Hi,
>
> What manifest constants do folks use to define the limits
> on physical memory (of a particular flavor -- e.g., RAM)?
> For example, I do:
>
> do_something(void *location, size_t size) {
> ASSERT( (location >= FIRST_RAM) && (location <= LAST_RAM) );
> ASSERT( size <= ((LAST_RAM - FIRST_RAM) + 1) )
> ASSERT( location <= ((LAST_RAM + 1) - size) );
>
> ...
> }
>
> This gets tedious with discontiguous memory but I don't see
> any way around it.

What errors are you trying to catch?

If you over-allocate any static memory the linker will catch the problem
(if it's a decent linker). Normally one puts heap and stack space into
known memory regions, so you're not looking for "is this outside of all
possible memory regions", rather you're looking for "is this outside of
it's assigned space".

So I don't see what you're trying to _do_.

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

Do you need to implement control loops in software?
"Applied Control Theory for Embedded Systems" was written for you.
See details at http://www.wescottdesign.com/actfes/actfes.html
From: robertwessel2 on
On Jul 19, 12:58 pm, D Yuniskis <not.going.to...(a)seen.com> wrote:
> Hi,
>
> What manifest constants do folks use to define the limits
> on physical memory (of a particular flavor -- e.g., RAM)?
> For example, I do:
>
> do_something(void *location, size_t size) {
>    ASSERT( (location >= FIRST_RAM) && (location <= LAST_RAM) );
>    ASSERT( size <= ((LAST_RAM - FIRST_RAM) + 1) )
>    ASSERT( location <= ((LAST_RAM + 1) - size) );
>
> ...
>
> }
>
> This gets tedious with discontiguous memory but I don't see
> any way around it.


Not exactly sure what the question is, but that's more complex than
necessary. Something like:

ASSERT( (location >= FIRST_RAM) && ((location+size-1-FIRST_RAM) <=
(LAST_RAM-FIRST_RAM)) );

does the whole job.

If you've got multiple regions, or checks in multiple places, a macro
or two may be in order.

And if you know the arithmetic will be performed without wrap, you can
simplify the second term (by removing both of the "FIRST_RAM" terms).

(And ignoring that you're doing arithmetic on void pointers, which, of
course, is not allowed).
From: D Yuniskis on
Hi Robert,

robertwessel2(a)yahoo.com wrote:
> On Jul 19, 12:58 pm, D Yuniskis <not.going.to...(a)seen.com> wrote:
>> What manifest constants do folks use to define the limits
>> on physical memory (of a particular flavor -- e.g., RAM)?
>> For example, I do:
>>
>> do_something(void *location, size_t size) {
>> ASSERT( (location >= FIRST_RAM) && (location <= LAST_RAM) );
>> ASSERT( size <= ((LAST_RAM - FIRST_RAM) + 1) )
>> ASSERT( location <= ((LAST_RAM + 1) - size) );
>>
>> ...
>>
>> }
>>
>> This gets tedious with discontiguous memory but I don't see
>> any way around it.
>
> Not exactly sure what the question is, but that's more complex than
> necessary. Something like:
>
> ASSERT( (location >= FIRST_RAM) && ((location+size-1-FIRST_RAM) <=
> (LAST_RAM-FIRST_RAM)) );
>
> does the whole job.

"ASSERT()" is free -- only present in DEBUG code ("assert()",
by contrast, is not free).

As a matter of style, I always enumerate all of the contractual
obligations on each parameter so they can be *clearly* seen when
the code is read. This makes the second argument to ASSSERT()
(not shown in the examples) much more informative as a debugging aid:

ASSERT( (location >= FIRST_RAM) && (location <= LAST_RAM),
"location not in RAM region");

ASSERT( size <= ((LAST_RAM - FIRST_RAM) + 1),
"size exceeds dimensions of RAM region");

ASSERT( location <= ((LAST_RAM + 1) - size),
"do_something extends beyond end of RAM region");

contrast that with the message that your ASSERT would emit:
"do_something -- bad parameter(s)"

> If you've got multiple regions, or checks in multiple places, a macro
> or two may be in order.

Yes, though the arithmetic varies depending on the function being
performed (do_something()). My query was regarding choices for
manifest constants (even though they might not be constants).

E.g., things like MAX_INT don't apply and are suggestive of
other types of limits than those that would pertain, here.

> And if you know the arithmetic will be performed without wrap, you can
> simplify the second term (by removing both of the "FIRST_RAM" terms).

But you don't know that the arithmetic won't wrap. Hence
the clumsier expressions.

> (And ignoring that you're doing arithmetic on void pointers, which, of
> course, is not allowed).
From: D Yuniskis on
Hi Tim,

Tim Wescott wrote:
> On 07/19/2010 10:58 AM, D Yuniskis wrote:
>
>> What manifest constants do folks use to define the limits
>> on physical memory (of a particular flavor -- e.g., RAM)?
>> For example, I do:
>>
>> do_something(void *location, size_t size) {
>> ASSERT( (location >= FIRST_RAM) && (location <= LAST_RAM) );
>> ASSERT( size <= ((LAST_RAM - FIRST_RAM) + 1) )
>> ASSERT( location <= ((LAST_RAM + 1) - size) );
>>
>> ...
>> }
>>
>> This gets tedious with discontiguous memory but I don't see
>> any way around it.
>
> What errors are you trying to catch?

Running off the end/start of a memory region. And consider that
region may be as big as the largest int supported by the compiler

> If you over-allocate any static memory the linker will catch the problem

Not worried about static allocations -- for the reasons
you outline. Nor static assignments (e.g., foo[x] = foo[y] where
x and y are both >= 0 and < sizeof(foo)).

Not all things fit nicely into static allocations (e.g., any
product that has a variable memory complement has "limits"
that the linkage editor is not aware of -- late binding).

Any product that does more than the resource complement
appears capable of supporting has to dynamically reallocate
resources.

And, even a statically allocated region/object needs limit
checking (e.g., imagine these were FIRST_HEAP and LAST_HEAP
and you're trying to allocate a stack *in* that heap for a
newly/dynamically created task).

> (if it's a decent linker). Normally one puts heap and stack space into
> known memory regions, so you're not looking for "is this outside of all
> possible memory regions", rather you're looking for "is this outside of
> it's assigned space".

The "assigned space" is defined by [FIRST_* .. LAST_*].

You can attempt, for example, to allocate an 8K stack at 0xFFFFFF00
(oops!).

Or, move a string "up" a number of "addresses" and push it out
of it's "assigned space" (e.g., [FIRST_HEAP..LAST_HEAP])

etc.

All of these are *bugs* so the trite reply is "well, you shouldn't
be *doing* that". :> But, writing code that checks to see when
it (at runtime) is trying to do one of these things is the issue.
(applications tend to be isolated from this sort of thing
but OS's aren't)

So, I'm asking for names appropriate for these "region limits"
that are intuitive yet not suggestive of other "data type"
limitations (like UINT8_MAX, etc.).

> So I don't see what you're trying to _do_.