Grid Beam is a building technique developed in the 70’s. It is a simple technique which uses perforated square beams, connected by normal furniture bolts. I first learned about the technique from the book How to build with Grid Beam by new society publishers:
While the book is more of an history of grid beam, it does have some techniques and discussion on design. I think the technique has huge potential as a reusable building method
In need of a Dirty workbench, I decided to build a ‘stick’ making jig and attempt to build a bench. I was surprised by a few things:
Beam stability is a function of the species, not the holes
Hole accuracy is important, but not a deal breaker – the bolts pull the beams together nicely
It takes about 20 minutes to drill a 6 foot beam – not including finishing touches like chamfer
Our home is expensive to heat. Not only is that, but it feels drafty. We were convinced that our main heating problems were the Windows in our family room (where the thermostat is) – all were replaced without any effect.
Annoyed, we needed to find a way to pinpoint our homes problems. We turned to Thermal Imaging by Northwest Infrared to help us understand the problems. I am very impressed and highly recommend their service. I believe this is the single best thing that can be done to your home. It is inexpensive and pinpoints phantom energy loss. Northwest Infrared only does energy evaluation – you’ll get brutally honest information without the sales pitch.
Thermal analysis is a two step process:
Depressurize the home taking accurate barometric measurements to determine how much leakage there is.
Use a thermal imager to see where cold air is leaking into the home.
Common Problems
Attic access not sealed well:
Pipe cutouts are huge openings to the crawl space:
Downdraft vent in the cooktop isn’t sealed or baffled:
Return air vent uses the floor joists instead of being ducted – drawing lots of air from the ‘area between floors’
– And in our case those floor joists are open to the outside!
Check out this ghostly image:
Our Unique Problems
Our new windows weren’t sealed correctly (you can bet we’ll be bringing that up with Anderson Renewable):
Our vents aren’t sealed correctly:
Our worst offender is our heating room which is open to the crawl space. This room is essentially outside, but not insulated like it is an inside closet:
February 11th, 2009 § Comments Off on avr-libc realloc ‘fix’ § permalink
I’ve been working on patterns for Arduino, which relies on a dynamic array for managing event loops, observables, and device abstraction. However, I was blocked by a critical failure in realloc. While I could have worked around it using malloc/free, but wanted to understand what was going on in libc.
One thing that struck me about realloc was the naming conventions; What was the difference between fp1, fp2, cp1, cp2? Some referred to a free block, some referred to a free pointer. I gave up and renamed the variables to something more readable.
The fatal flaw has to do with mixing sizeof(__freelist) and sizeof(size_t). In many cases, the difference results in indexing into the middle of a free list entry, thus corrupting memory.
void* realloc(void *ptr, size_t newLength)
{
struct __freelist *currentBlock, *nextBlock,
*currentFreeBlock, *previousFreeBlock;
char *currentPointer, *nextPointer;
void *memp;
size_t largestBlockSize, sizeIncrease;
/* Trivial case, required by C standard. */
if (ptr == 0)
return Malloc(newLength);
currentPointer = (char *)ptr;
currentBlock = (struct __freelist *)
(currentPointer - sizeof(size_t));
nextPointer = (char *)ptr + newLength; /* new next pointer */
if (nextPointer < currentPointer)
{
/* Pointer wrapped across top of RAM, fail. */
return 0;
}
nextBlock = (struct __freelist *)(nextPointer - sizeof(size_t));
/*
* See whether we are growing or shrinking. When shrinking,
* we split off a chunk for the released portion, and call
* free() on it. Therefore, we can only shrink if the new
* size is at least sizeof(struct __freelist) smaller than the
* previous size.
*/
if (newLength <= currentBlock->sz)
{
/* The first test catches a possible unsigned int
* rollover condition. */
if (currentBlock->sz <= sizeof(struct __freelist) ||
newLength > currentBlock->sz - sizeof(struct __freelist))
{
return ptr;
}
nextBlock->sz = currentBlock->sz - newLength - sizeof(size_t);
currentBlock->sz = newLength;
Free(&(nextBlock->nx));
return ptr;
}
/*
* If we get here, we are growing. First, see whether there
* is space in the free list on top of our current chunk.
*/
sizeIncrease = newLength - currentBlock->sz;
currentPointer = (char *)ptr + currentBlock->sz;
for (largestBlockSize = 0, previousFreeBlock = 0,
currentFreeBlock = __flp; currentFreeBlock;
previousFreeBlock = currentFreeBlock,
currentFreeBlock = currentFreeBlock->nx)
{
if (currentFreeBlock == nextBlock &&
currentFreeBlock->sz >= sizeIncrease)
{
/* found something that fits */
if (sizeIncrease <= currentFreeBlock->sz + sizeof(size_t))
{
/* it just fits, so use it entirely */
currentBlock->sz +=
currentFreeBlock->sz + sizeof(size_t);
if (previousFreeBlock)
previousFreeBlock->nx = currentFreeBlock->nx;
else
__flp = currentFreeBlock->nx;
return ptr;
}
/* split off a new freelist entry */
currentPointer = (char *)ptr + newLength;
nextBlock = (struct __freelist *)
(currentPointer - sizeof(size_t));
nextBlock->nx = currentFreeBlock->nx;
nextBlock->sz = currentFreeBlock->sz -
sizeIncrease - sizeof(size_t);
if (previousFreeBlock)
previousFreeBlock->nx = nextBlock;
else
__flp = nextBlock;
currentBlock->sz = newLength;
return ptr;
}
/*
* Find the largest chunk on the freelist while
* walking it.
*/
if (currentFreeBlock->sz > largestBlockSize)
{
largestBlockSize = currentFreeBlock->sz;
}
}
/*
* If we are the topmost chunk in memory, and there was no
* large enough chunk on the freelist that could be re-used
* (by a call to malloc() below), quickly extend the
* allocation area if possible, without need to copy the old
* data.
*/
if (__brkval == (char *)ptr + currentBlock->sz && newLength > largestBlockSize)
{
nextPointer = __malloc_heap_end;
currentPointer = (char *)ptr + newLength;
if (nextPointer == 0)
{
nextPointer = STACK_POINTER() - __malloc_margin;
}
if (currentPointer < nextPointer)
{
__brkval = currentPointer;
currentBlock->sz = newLength;
return ptr;
}
/* If that failed, we are out of luck. */
return 0;
}
/*
* Call malloc() for a new chunk, then copy over the data, and
* release the old region.
*/
if ((memp = Malloc(newLength)) == 0)
return 0;
memcpy(memp, ptr, currentBlock->sz);
Free(ptr);
return memp;
}
Where am I?
You are currently viewing the archives for February, 2009 at OoeyGUI.