Understand BINDER_VM_SIZE in Android source code - android

In file framework/native/libs/binder/ProcessState.cpp
Why is BINDER_VM_SIZE set to 1M-8k?
#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))

It's not this value initially, you can find that(from git commit log) it's first value is
#define BINDER_VM_SIZE (1*1024*1024)
Then someone change this value to
#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
with the following commit message:
Modify the binder to request 1M - 2 pages instead of 1M. The backing
store in the kernel requires a guard page, so 1M allocations fragment
memory very badly. Subtracting a couple of pages so that they fit in
a power of two allows the kernel to make more efficient use of its
virtual address space.
I myself don't fully understand this message,so I just paste it here hope it may help your understanding!

Related

What's the difference between the AUDIO_FORMAT_PCM_32_BIT and AUDIO_FORMAT_PCM_8_24_BIT in Android Lollipop?

The AUDIO_FORMAT_PCM_32_BIT and AUDIO_FORMAT_PCM_8_24_BIT are two high definition audio formats in Android Lollipop.
Seems they are all in 32 bit depth.
Who know the exactly difference between them?
You can find that information in audio.h:
/* Audio format consists of a main format field (upper 8 bits) and a sub
format field (lower 24 bits).
AUDIO_FORMAT_PCM_32_BIT and AUDIO_FORMAT_PCM_8_24_BIT are defined as:
AUDIO_FORMAT_PCM_32_BIT = (AUDIO_FORMAT_PCM |
AUDIO_FORMAT_PCM_SUB_32_BIT),
AUDIO_FORMAT_PCM_8_24_BIT = (AUDIO_FORMAT_PCM |
AUDIO_FORMAT_PCM_SUB_8_24_BIT),
And if we look at the definitions of AUDIO_FORMAT_PCM_SUB_32_BIT and AUDIO_FORMAT_PCM_8_24_BIT we find some helpful comments:
AUDIO_FORMAT_PCM_SUB_32_BIT = 0x3, /* PCM signed .31 fixed point */
AUDIO_FORMAT_PCM_SUB_8_24_BIT = 0x4, /* PCM signed 7.24 fixed point */
In response to Michael's comment:
signed .31 means 1 bit for sign, 0 bits for the whole part, and 31 bits for the fractional part. signed 7.24 means 1 bit for sign, 7 bits for the whole part, and 24 bits for the fractional part. Read up on fixed-point arithmetic if you want to know more about how it's used.
AUDIO_FORMAT_PCM_8_24_BIT most likely refers to a padded 8 bits of zeros as the 7.24 fixed point doesn't make sense for PCM data. This is because PCM data ranges from [1.0 .. -1.0]. (it technically should be 8.23, otherwise 7.24 == 25-bits!). So the use of a "whole" [number] part does not make sense.
A single sample of AUDIO_FORMAT_PCM_8_24_BIT will contain 4 bytes, where only 3 bytes will hold any meaningful data and the remaining single byte will be all zeros.
The alternative is AUDIO_FORMAT_PCM_24_BIT_PACKED that only contains 3 bytes per sample and no padding. 24-bit audio has a strange format, and it doesn't fit well in the powers of 2 of digital audio. It is typically easier to handle a 24-bit sample as if it was 32-bit.

android how to set bootanimation interval help me please

I am changing my boot animation images but problem is repeating same images again & again this is des0 file . This is my dess0 file. Please tell me the purpose of this file? How do I set my interval?? I containing my bootanimation.zip file have 2 things a folder which contain 40 pics and desc0.text file which contain this which is below. Please tell me how do I set my interval???
how do I set my boot animation interval
1024 600 10
p 0 0 part0
p 1 0 part1
There could be any number of problems, first: according to your desc there should be three things in your zip namely, desct.txt, part0 and part1 folders. The numeric sequencing of files are very important. Also, the first loop is infinite so you'll get problems reaching part1.
I suggest follow the tutorial as explained in this XDA thread.

ARM NEON Assembler - usage & understanding

I am new to assembler and NEON programming.
My task is to convert part of an algorithm from C to ARM Assembler using NEON instructions.
The algorithm takes an int32 array, loads different values from this array, does some bitshifting and Xor and writes the result in another array.
Later I will use an array with 64bit values, but for now i just try to rewrite the code.
C Pseudo code:
out_array[index] = shiftSome( in_array[index] ) ^ shiftSome( in_array[index] );
So here are my questions regarding NEON Instructions:
1.) If i load a register like this:
vld1.32 d0, [r1]
will it load only 32Bit from the memory or 2x32Bit to fill the 64Bit Neon D-Register?
2.) How can I access the 2/4/8 (i32, i16, i8) parts of the D-Register?
3.) I am trying to load different values from the array with an offset, but it doesn't
seem to work...what am I doing wrong... here is my code:
(it is an integer array so I´m trying to load for example the 3-element, which should have an offset of 64Bit = 8 Byte)
asm volatile(
"vld1.32 d0, [%0], #8 \n"
"vst1.32 d0, [%1]" : : "r" (a), "r" (out): "d0", "r5");
where "a" is the array and "out" is an pointer to an integer (for debugging).
4.) After I load a value from the array I need to shift it to the right but it doesn't seem to work:
vshr.u32 d0, d0, #24 // C code: x >> 24;
5.) Is it possible to only load 1 Byte in a Neon register so that I don't have to shift/mask something to get only the one Byte i need?
6.) I need to use Inline assembler, but I am not sure what the last line is for:
input list : output list : what is this for?
7.) Do you know any good NEON References with code examples?
The Program should run on an Samsung Galaxy S2, cortex-A9 Processor if that makes any difference. Thanks for the help.
----------------edit-------------------
That is what i found out:
It will always load the full Register (64Bit)
You can use the "vmov" instruction to transfer part of a neon register to an arm register.
The offset should be in an arm register and will be added to the
base address after the memory access.
It is the "clobbered reg list". Every Register that is used and
neither in the input or output list, should be written here.
I can answer most of your questions: (update: clarified "lane" issue)
1) NEON instructions can only load and store entire registers (64-bit, 128-bit) at a time to and from memory. There is a MOV instruction variant that allows single "lanes" to be moved to or from ARM registers.
2) You can use the NEON MOV instruction to affect single lanes. Performance will suffer when doing too many single element operations. NEON instructions benefit application performance by doing parallel operations on vectors (groups of floats/ints).
3) The immediate value offsets in ARM assembly language are bytes, not elements/registers. NEON instructions allow post increment with a register, not immediate value. For normal ARM instructions, your post-increment of 8 will add 8 (bytes) to the source pointer.
4) Shifts in NEON affect all elements of a vector. A shift right of 24 bits using vshr.u32 will shift both 32-bit unsigned longs by 24 bits and throw away the bits that get shifted out.
5) NEON instructions allow moving single elements in and out of normal ARM registers, but don't allow loads or stores from memory directly into "lanes".
6) ?
7) Start here: http://blogs.arm.com/software-enablement/161-coding-for-neon-part-1-load-and-stores/ The ARM site has a good tutorial on NEON.
6) Clobbered registers.
asm(code : output operand list : input operand list : clobber list);
If you are using registers, which had not been passed as operands, you need to inform
the compiler about this. The following code will adjust a value to a multiple of four. It
uses r3 as a scratch register and lets the compiler know about this by specifying r3 in the
clobber list. Furthermore the CPU status flags are modified by the ands instruction.
Adding the pseudo register cc to the clobber list will keep the compiler informed about
this modification as well.
asm (
"ands R3, %1, #3"
"eor %0, %0, r3"
: "=r"(len)
: "0"(len)
: "cc", "r3"
);

"Immediate out of range errors" when assigning 0.0 to a NEON register

If I understand it correctly, because ARM instructions are 32 bits long they can only hold so many bits of immediate value. What I'm trying to do is vmov.f32 s0, #0.0, and I get "immediate out of range" compiler error. Strange thing is that when I use an immediate value of, say #0.5 or #0.25 (all very neatly represented in binary), my code compiles. When I try to assign an immediate value of #0.1, I get the "garbage after following instruction" error, which makes sense if it's trying to represent those values with more bits that can fit into an ARM instruction. The #0.0 case is the only one where I get "immediate out of range", so I'm thinking it's got to be a bug if there's no other explanation.
Does anyone know how to assign an immediate value of #0.0 to a single word floating point register without having to convert it from somewhere else? If there's a good reason it shouldn't work in the first place, please let me know as well. I'm using GNU assembler with Android NDK build tool.
Update:
vmov.f32 d0, #0.0 does work. It keeps making less and less sense.
Update 2:
This doesn't work either: vmov.s32 s0, #0
0.0 is not representable as a VFP/NEON floating-point immediate. Representable floating-point immediates are between 1/8 and 31 in magnitude, which zero clearly isn't.
The corresponding bit pattern, however, is representable as an integer NEON immediate. Your assembler is being helpful and generating this encoding for you instead of an (impossible) floating-point immediate; when you write vmov.f32 d0, #0.0 it actually emits vmov.s32 d0, #0, which has the same effect as what you appear to be trying to do, but is actually a legal instruction.
vmov.s32 s0, #0 doesn't make any sense; NEON does not provide any instructions that operate on s registers.
If you just want to zero a NEON register, however, the preferred idiom is usually veor d0, d0. Is there a reason that you aren't using that?
If you want to assign 0 to an s register, you can easily do by using the instruction:
vsub.f32 s0, s0, s0
For assigning "0" to a register(doesn't matter if it's general register or NEON vector) just do this:
"eor s0, s0, s0 \n\t"
You could simply use this :
vmov.u32 d0, #0
because 0x00000000 is interpreted as 0.0f as well.
FYI, there can't be any "true" zero in float. It's actually 1.0 * (2^-128)
or 1.0 * (2^-129), I don't remember exactly.

Manipulating 256x256 bitmap crashing android-ndk's JNI

Perhaps I am attempting to do something I ought not.
I'm running a block of code in the emulator. It looks (more or less)
like this: http://pastie.org/1291380
This is to construct a live wallpaper background. I pass in a bitmap,
color palette, and tile array.The size of my bitmap is 256 x 256.
getRedPal / getGreenPal / getBluePal essentially does a call to
Color.red() / Color.green() / Color.blue() in order to get the rgb
color components of a palette object.
The loops chug along; I get all the way to the point where the j value
of drawInC hits 32, before the emulator crashes and burns:
11-11 15:34:44.032: INFO/distort_bmp(598): DrawInC: i: 0 j: 32
11-11 15:34:44.032: INFO/distort_bmp(598): DrawTiles: i: 0 j: 0
11-11 15:34:44.032: INFO/distort_bmp(598): DrawTiles: i: 0 j: 1
11-11 15:34:44.032: INFO/distort_bmp(598): DrawTiles: i: 0 j: 2
11-11 15:34:44.032: INFO/distort_bmp(598): DrawTiles: i: 0 j: 3
11-11 15:34:44.032: INFO/distort_bmp(598): DrawTiles: i: 0 j: 4
After which I get a dump file sent to /data/tombstones . Here is the
dump (but I sincerely don't find anything in it worth any value, just
a bunch of memory addresses): http://pastie.org/1291394
I added android:vmSafeMode="true" to my tag after
reading elsewhere that that could solve a problem. This is on 2.2,
using bitmap.h.
Personally I am dubious of that
jbyte* buffer =
(*env)->GetByteArrayElements(env, arr, &isCopy)
call; I plucked that
code from the net somewhere, as I was totally unable to get values
from my byte array "arr."
Any ideas?
EDIT
After manipulating my loop iterators (I shortened the number of loops), I now get an informative error:
"ReferenceTable overflow (max=512)"
JNI local reference table summary (512 entries):
509 of Ljava/lang/Class; 164B (3 unique)
2 of Ljava/lang/String; 28B (2 unique)
1 of [Ljava/lang/String; 28B
Memory held directly by tracked refs is 576 bytes
Failed adding to JNI local ref table (has 512 entries)
That "509 of java.lang.class" doesn't look too right to me...how can I optimize my code here?
From that error message, it appears that some bit of native code has called a function that returns a Class object, and has done so 509 times. 507 of those calls returned one particular class.
JNI local references let the GC know that native code is looking at an object, and therefore that object can't be collected even if there are no references to it elsewhere. These local refs are released when the native code returns to the VM. If the native code does a lot of work without returning, it's possible to overflow the local ref table.
You probably just need to add a DeleteLocalRef somewhere. My guess is you need to add one at the end of DrawTile, because of the GetObjectClass call. Better yet, move those GetMethodID calls to a one-time setup function. (They do string searches to find the method, making them not especially quick.)
For more info see JNI Tips.
i think this might be a memory problem. do you release the arrays?
if you get arrays with
(*env)->GetByteArrayElements(env, arr, &isCopy)
you must release the array on the c-side it after each procedure or you will fill your memory till you get over the limit (limit size depends on android version and/or manufacturer but is to my knowledge max 48MB per app)
(*env)->ReleaseByteArrayElements(env, arr, &isCopy, 0);
see here: http://www.iam.ubc.ca/guides/javatut99/native1.1/implementing/array.html
btw, this method does copy the arrays from java to a new memory block in c, you work there and at the end its copied back to java (which memory might have been moved to another location till then). for performance improvement you might look at https://groups.google.com/forum/?fromgroups#!msg/android-ndk/phDP5zqiYY4/BFMw4zTme8IJ

Categories

Resources