2010年10月28日星期四

CAS/CAS2 for lock free queue on x86_64

Just ported lock-free queue to x86_64

here is CAS, CAS2 macros


#ifdef __x86_64__
#define __xg(x) ((volatile long *)(x)) // stole from linux kernel source

// CAS2(ret, &q->tail, head, tag2, next, tag2 + 1);

#define CAS2(ret, mem, old1, old2, new1, new2) \
do {\
asm volatile( \
".align 8 \n" \
"movq $0, %0 \n" \
"LOCK cmpxchg16b %1\n" \
"setz %0 \n" \
"1:\n" \
: "=m" (ret) \
: "m" (*__xg(mem)), "a" (old1), "d" (old2), "b" (new1), "c" (new2) \
: "memory", "cc" \
); \
/* ret = ( (ret & (1 <<>
} while(0);

#else
#define CAS2(ret, mem, old1, old2, new1, new2) \
do {\
asm volatile( \
".align 4 \n" \
"movl $0, %0 \n" \
"LOCK cmpxchg8b (%%esi)\n" \
"setz %0 \n" \
"1:\n" \
: "=m" (ret) \
: "S" (mem), "a" (old1), "d" (old2), "b" (new1), "c" (new2) \
: "memory", "cc" \
); \
/* ret = ( (ret & (1 <<>
} while(0);
#endif

#define DEAD_NODE(q) \
&((q)->stone)


#ifdef __x86_64__

#define CAS(ret, mem, old, new) \
do {\
asm volatile( \
".align 8 \n" \
"movq $0, %0 \n" \
"LOCK cmpxchgq %1, %2 \n" \
"setz %0 \n" \
: "=m" (ret) \
: "d" (new), "m" (*__xg(mem)), "a" (old) \
: "memory", "cc" \
); \
} while(0);

#else
#define CAS(ret, mem, old, new) \
do {\
asm volatile( \
".align 4 \n" \
"movl $0, %0 \n" \
"LOCK cmpxchgl %%edx, (%%esi) \n" \
"setz %0 \n" \
: "=m" (ret) \
: "d" (new), "S" (mem), "a" (old) \
: "memory", "cc" \
); \
} while(0);
#endif

Note: you will have to use long/unsigned long type for each variables for CAS/CAS2, if use int type, gcc might use e*x registers as operand of q suffix instructions, it will make you very unhappy.

2010年3月25日星期四

patch for amfphp AMF3 ByteArray serialization bug

Base on amfphp 1.9, there are bugs of AMF3 ByteArray serialization, if you want to send a ByteArray from PHP to flash, you will have to modify core/amf/io/AMFSerializer.php:writeAmf3ByteArray function.

Line 991:
Original code:
function writeAmf3ByteArray($d)
{
$this->writeByte(0x0C);
$this->writeAmf3String($d, true);
$this->writeAmf3ByteArrayBody($d);
}
change to:
function writeAmf3ByteArray($d)
{
$this->writeByte(0x0C);
$this->writeAmf3ByteArrayBody($d);
}
It fixed two issues:
1. writeAmf3String and writeAmf3ByteArrayBody writes ByteArray body content twice
2. writeAmf3String uses U29S-ref, ByteArray should be U29O-ref ( ref AMF3-spec)

Hope helpful