Don't restart procfs reads from scratch
android_os_Process_readProcFile is mainly used for small files. It
tries to minimize memory use by first attempting to read into a stack
buffer, and only after that buffer is found to be too small does it use
a heap-allocated buffer. The heap buffer starts out small and grows as
the file size is found to exceed the size of the buffer. However on both
the transition from the stack buffer to the heap buffer, and when
enlarging the heap buffer, the data that has already been read gets
thrown away and the read of the file restarts from the beginning.
The dominating runtime cost for the function is the kernel work to
produce the output. Copying the already-read data into a larger buffer
in userspace is more efficient than throwing it away and rereading from
the beginning. So this commit changes the function to do that.
This reduces cpu-cycles by about 35% for reads of the largest
/proc/pid/maps file on Android. Tested on a Pixel 6 Pro with
system_server's maps file across 20 runs:
Simpleperf event count (cpu-cycles)
Copy Reread
Average 13,338,222 20,254,826
StdDev 4,791,640 9,644,942
Min 7,460,801 12,576,877
Max 25,403,534 45,759,654
Eliminating the 1024 byte stack buffer and just using an expandable heap
buffer indicates further improvement with an average of 12,835,802
cycles, code simplification, and a .text savings of between about 50-200
bytes depending on compiler optimizations. I suspect the memory savings
from attempting to read small files into the stack buffer is not that
meaningful, however I didn't measure peak memory use for either small or
large reads so I did not remove it in this commit.
Bug: 351917521
Test: cuttlefish boot
Change-Id: Ifa4a739ca43415b1d8dd85177a7c50eb86955160
1 file changed