On Sun, 2007-12-02 at 01:26 +0000, Krzysztof Foltman wrote:
Dave Robillard wrote:
I still don't see where you're getting
all this messy code stuff.
Adding 8 to a pointer isn't any more or less messy than adding 16 to a
pointer.
uint32_t *p = &some_int_array[0];
p += 7;
Q: Where does p point now?
A: 28 bytes ahead of its previous value.
Congratulations, you can add and multiply. ?
That's where the elegance-related problem lies
(IMO).
heh.
If the struct size is 16, and you want to increase the
pointer by 8
bytes, you need to cast to char*, increase by 8, and cast back to
LV2_EVENT_HEADER. That's what was (and is) bugging me.
i += (events[i].size+7) >> 3;
is a bit nicer than:
p = (LV2_EVENT_HDR *)((char *)p + ((p->size + 7) &~7));
Yeah, that or
p = (LV2_EVENT*)(&p.data + PAD(p.size))
you have an unhealthy bit manipulation fetish or something :P
Anyway, I agree the alignment sucks. Not for these... colourful
reasons, but because accessing things that aren't aligned is slow.
The real problem (relative to the old original events) is the type
field. It doesn't need to be very large, so it takes up a little bit of
space and throws everything out of alignment regardless of whether we
choose 32 or 64 bit stamps.
struct LV2EventA {
uintn_t frames; // good alignment
uintn_t subframes; // good alignment
uint32_t size; // good alignment
uint8_t type; // bad alignment
// data // bad alignment
} // 9 or 13 bytes (ick)
How do we fix that? The only solution is to cram type into the space
taken up by size or subframes. If I had to pick, I'd choose doing it to
size, but OSC blobs (among other things) have a 32 bit length so that
sucks a bit. The max length if we use uint16_t is not even a meg
Taking over subframes space means tempo time wouldn't be sample
accurate, which is a show-stopper. It's a big chunk for time, sure, but
time is the most important information, the rest is framework.
struct LV2EventB {
uintn_t frames;
uintn_t subframes;
uint16_t size;
uint16_t type;
// data (32-bit aligned)
} // 8 or 12 bytes
is the best so far IMO, but that's an awful lot of space wasted on type
which isn't even likely to be > 10.
Is doing something really weird like 24 bytes for size and 8 bytes for
type worth it for the much nicer payload size limit (16 megs)?
Then again, UDP packet size (which OSC typically travels in) is
typically well within uint16_t's range, and if messages are actually
getting that big, they should probably be pointing at some shared
resource to avoid the potential copying.
All things considered LV2EventB with n=32 seems best to me..
-DR-