--- a/kernel/eka/klib/arm/cbma.cia Tue May 11 17:28:22 2010 +0300
+++ b/kernel/eka/klib/arm/cbma.cia Tue May 25 14:09:55 2010 +0300
@@ -336,6 +336,81 @@
}
+/** Allocates a specific range of bit positions.
+
+ The specified range must lie within the total range for this allocator but it is
+ not necessary that all the positions are currently free.
+
+ @param aStart First position to allocate.
+ @param aLength Number of consecutive positions to allocate, must be >0.
+ @return The number of previously free positions that were allocated.
+ */
+EXPORT_C __NAKED__ TUint TBitMapAllocator::SelectiveAlloc(TInt /*aStart*/, TInt /*aLength*/)
+ {
+ asm("ldr r3, [r0, #%a0] " : : "i" _FOFF(TBitMapAllocator, iSize)); // r3->iSize
+ asm("stmfd sp!, {r4-r8,lr} ");
+ asm("adds r4, r1, r2 "); // r4 = aStart + aLength
+ asm("bcs 0f "); // if (aStart + aLength < aStart)
+ asm("cmp r4, r3 "); // if (aStart + aLength > iSize)
+ asm("bhi 0f ");
+ asm("mov r7, r0 "); // r7 = this
+ asm("mov r4, r1, lsr #5 "); // r4 = wix = aStart >> 5
+ asm("and r1, r1, #0x1f "); // r1 = sbit = aStart & 31
+ asm("ldr r6, [r7, #%a0] " : : "i" _FOFF(TBitMapAllocator, iAvail)); // r6 = iAvail
+ asm("add r4, r7, r4, lsl #2 ");
+ asm("add r4, r4, #%a0 " : : "i" _FOFF(TBitMapAllocator, iMap)); // r4 = iMap + wix
+ asm("sub r6, r6, r2 "); // r6 = iAvail -= aLength
+ asm("add r5, r2, r1 "); // r5 = ebit = sbit + aLength
+ asm("mvn r0, #0 ");
+ asm("mvn r0, r0, lsr r1 "); // r0 = b = ~(0xffffffff >> sbit)
+ asm("cmp r5, #32 ");
+ asm("mov r8, r2"); // r8 = aLength
+ asm("bhi salloc_cross_bdry "); // branch if (ebit >=32)
+
+ asm("mvn r5, #0 "); // r5 = 0xffffffff
+ asm("mov r5, r5, lsr r8 "); // r5 >> aLength
+ asm("mov r5, r5, lsr r1 "); // r5 >> sbit
+ asm("orr r5, r5, r0 "); // r5 = b = r0 | r5
+ asm("ldr r0, [r4] "); // r0 = w = *pW
+ asm("and r1, r0, r5 "); // r1 = w & b, clear the positions to be allocated
+ asm("str r1, [r4] "); // *pW = r1, store new bit map word.
+ asm("mvn r0, r0"); // r0 = ~w
+ asm("mvn r5, r5"); // r5 = ~b
+ asm("and r0, r0, r5"); // r0 = ~w & ~b
+ asm("bl " CSM_CFUNC(__e32_bit_count_32));
+ asm("add r6, r6, r0 "); // r6 = iAvail + allocated
+ asm("sub r0, r8, r0 "); // return aLength - allocated
+ asm("str r6, [r7] "); // iAvail += allocated, store free count
+ asm("ldmfd sp!, {r4-r8,pc} "); // return
+
+ asm("salloc_cross_bdry: "); // r0 = b, r8 = aLength, r7 = this, r5 = ebit
+ asm("ldr r2, [r4] "); // r2 = w = *pW
+ asm("and r1, r2, r0 "); // r1 = w & b
+ asm("str r1, [r4], #4 "); // *pW++ = r1, store new bit mask
+ asm("mvn r2, r2"); // r2 = ~w
+ asm("mvn r0, r0"); // r0 = ~b
+ asm("and r0, r0, r2"); // r0 = ~w & ~b
+ asm("bl " CSM_CFUNC(__e32_bit_count_32));
+ asm("add r6, r6, r0 "); // r6 = iAvail += allocated
+ asm("sub r8, r8, r0 "); // r8 = aLength -= allocated
+ asm("subs r5, r5, #32 "); // r5 = ebit -= 32
+ asm("bls salloc_return "); // ebit < 0 so return.
+ asm("cmp r5, #32 "); // if (ebit < 32) {
+ asm("mvnlt r0, #0 ");
+ asm("movlt r0, r0, lsr r5 "); // r0 = 0xffffffff >> ebit }
+ asm("movge r0, #0 "); // if (ebit >= 32) r0 = b = 0
+ asm("b salloc_cross_bdry ");
+
+ asm("salloc_return: ");
+ asm("str r6, [r7] "); // iAvail += allocated, store free count
+ asm("mov r0, r8 "); // return aLength
+ asm("ldmfd sp!, {r4-r8,pc} "); // return
+
+ asm("0: ");
+ ASM_FAULT();
+ }
+
+
/** Tests if a specific range of bit positions are all free
Specified range must lie within the total range for this allocator.