[Ruby-oci8-devel] alloc_sz

KUBO Takehiro kubo at jiubao.org
Fri Dec 7 11:42:19 EST 2007


Hi Liming,

>     sz += sizeof(sb4);
>     obind->value_sz = sz;
>     obind->alloc_sz = (sz + (sizeof(sb4) - 1)) & ~(sizeof(sb4) - 1);

This round up to sz to 4-byte boundary.
  If sz is 5~8, alloz_sz is 8. If 9~12, 12.

(sz + (sizeof(sb4) - 1)) & ~(sizeof(sb4) - 1)
  => (sz + (4 - 1) & ~(4 - 1)
  => (sz + 3) & ~3
  => (sz + 3) & 0xFFFFFFFC

round-up is done by one addition and one bit-mask. This is most
efficient way.

sizeof(sb4) is 4 in any OS and CPU. We can write more simply as
"(sz + 3) & 0xFFFFFFFC". But if sizeof(x)'s value depends on OS or
CPU, "(sz + (sizeof(x) - 1)) & ~(sizeof(x) - 1)" is most portable.
This is an idiom in C.

> I am wondering why the alloc_sz is calculated from the above expression,
> any hints? I want to make this clear because this attribute will be used
> for allocating memory for binding value and passed to
> OCIBindArrayOfStruct as skip parameter later.

The first member of oci8_vstr_t is sb4. It should be aligned to 4-byte
boundary in memory on x86 CPU. If it is not aligned, it causes memory
access penalty. As for SPARC CPU, it must be aligned, otherwise it
causes BUS error. If alloc_sz is not a multiple of 4, the second
element is not on 4-byte boundary.

-- 
KUBO Takehiro


More information about the ruby-oci8-devel mailing list