2 * Copyright (C) 2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * Miscellaneous utility functions.
29 #include <cutils/ashmem.h>
32 #define ALIGN_UP_TO_PAGE_SIZE(p) \
33 (((size_t)(p) + (SYSTEM_PAGE_SIZE - 1)) & ~(SYSTEM_PAGE_SIZE - 1))
36 * Print a hex dump in this format:
38 01234567: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 0123456789abcdef\n
40 * If "mode" is kHexDumpLocal, we start at offset zero, and show a full
41 * 16 bytes on the first line. If it's kHexDumpMem, we make this look
42 * like a memory dump, using the actual address, outputting a partial line
43 * if "vaddr" isn't aligned on a 16-byte boundary.
45 * "priority" and "tag" determine the values passed to the log calls.
47 * Does not use printf() or other string-formatting calls.
49 void dvmPrintHexDumpEx(int priority, const char* tag, const void* vaddr,
50 size_t length, HexDumpMode mode)
52 static const char gHexDigit[] = "0123456789abcdef";
53 const unsigned char* addr = vaddr;
54 char out[77]; /* exact fit */
55 unsigned int offset; /* offset to show while printing */
61 if (mode == kHexDumpLocal)
66 memset(out, ' ', sizeof(out)-1);
68 out[sizeof(out)-2] = '\n';
69 out[sizeof(out)-1] = '\0';
71 gap = (int) offset & 0x0f;
73 unsigned int lineOffset = offset & ~0x0f;
79 for (i = 0; i < 8; i++) {
80 *hex++ = gHexDigit[lineOffset >> 28];
86 count = ((int)length > 16-gap) ? 16-gap : (int)length; /* cap length */
88 assert(count+gap <= 16);
91 /* only on first line */
96 for (i = gap ; i < count+gap; i++) {
97 *hex++ = gHexDigit[*addr >> 4];
98 *hex++ = gHexDigit[*addr & 0x0f];
100 if (*addr >= 0x20 && *addr < 0x7f /*isprint(*addr)*/)
106 for ( ; i < 16; i++) {
107 /* erase extra stuff; only happens on last line */
114 LOG_PRI(priority, tag, "%s", out);
115 #if 0 //def HAVE_ANDROID_OS
117 * We can overrun logcat easily by writing at full speed. On the
118 * other hand, we can make Eclipse time out if we're showing
119 * packet dumps while debugging JDWP.
122 if (trickle++ == 8) {
137 * Fill out a DebugOutputTarget, suitable for printing to the log.
139 void dvmCreateLogOutputTarget(DebugOutputTarget* target, int priority,
142 assert(target != NULL);
145 target->which = kDebugTargetLog;
146 target->data.log.priority = priority;
147 target->data.log.tag = tag;
151 * Fill out a DebugOutputTarget suitable for printing to a file pointer.
153 void dvmCreateFileOutputTarget(DebugOutputTarget* target, FILE* fp)
155 assert(target != NULL);
158 target->which = kDebugTargetFile;
159 target->data.file.fp = fp;
163 * Free "target" and any associated data.
165 void dvmFreeOutputTarget(DebugOutputTarget* target)
171 * Print a debug message, to either a file or the log.
173 void dvmPrintDebugMessage(const DebugOutputTarget* target, const char* format,
178 va_start(args, format);
180 switch (target->which) {
181 case kDebugTargetLog:
182 LOG_PRI_VA(target->data.log.priority, target->data.log.tag,
185 case kDebugTargetFile:
186 vfprintf(target->data.file.fp, format, args);
189 LOGE("unexpected 'which' %d\n", target->which);
198 * Allocate a bit vector with enough space to hold at least the specified
201 BitVector* dvmAllocBitVector(int startBits, bool expandable)
206 assert(sizeof(bv->storage[0]) == 4); /* assuming 32-bit units */
207 assert(startBits >= 0);
209 bv = (BitVector*) malloc(sizeof(BitVector));
211 count = (startBits + 31) >> 5;
213 bv->storageSize = count;
214 bv->expandable = expandable;
215 bv->storage = (u4*) malloc(count * sizeof(u4));
216 memset(bv->storage, 0x00, count * sizeof(u4));
223 void dvmFreeBitVector(BitVector* pBits)
228 free(pBits->storage);
233 * "Allocate" the first-available bit in the bitmap.
235 * This is not synchronized. The caller is expected to hold some sort of
236 * lock that prevents multiple threads from executing simultaneously in
237 * dvmAllocBit/dvmFreeBit.
239 int dvmAllocBit(BitVector* pBits)
244 for (word = 0; word < pBits->storageSize; word++) {
245 if (pBits->storage[word] != 0xffffffff) {
247 * There are unallocated bits in this word. Return the first.
249 bit = ffs(~(pBits->storage[word])) -1;
250 assert(bit >= 0 && bit < 32);
251 pBits->storage[word] |= 1 << bit;
252 return (word << 5) | bit;
257 * Ran out of space, allocate more if we're allowed to.
259 if (!pBits->expandable)
262 pBits->storage = realloc(pBits->storage,
263 (pBits->storageSize + kBitVectorGrowth) * sizeof(u4));
264 memset(&pBits->storage[pBits->storageSize], 0x00,
265 kBitVectorGrowth * sizeof(u4));
266 pBits->storageSize += kBitVectorGrowth;
271 * Mark the specified bit as "set".
273 * Returns "false" if the bit is outside the range of the vector and we're
274 * not allowed to expand.
276 bool dvmSetBit(BitVector* pBits, int num)
279 if (num >= pBits->storageSize * (int)sizeof(u4) * 8) {
280 if (!pBits->expandable)
283 /* Round up to word boundaries for "num+1" bits */
284 int newSize = (num + 1 + 31) >> 5;
285 assert(newSize > pBits->storageSize);
286 pBits->storage = realloc(pBits->storage, newSize * sizeof(u4));
287 memset(&pBits->storage[pBits->storageSize], 0x00,
288 (newSize - pBits->storageSize) * sizeof(u4));
289 pBits->storageSize = newSize;
292 pBits->storage[num >> 5] |= 1 << (num & 0x1f);
297 * Mark the specified bit as "clear".
299 void dvmClearBit(BitVector* pBits, int num)
301 assert(num >= 0 && num < (int) pBits->storageSize * (int)sizeof(u4) * 8);
303 pBits->storage[num >> 5] &= ~(1 << (num & 0x1f));
307 * Mark all bits bit as "clear".
309 void dvmClearAllBits(BitVector* pBits)
311 int count = pBits->storageSize;
312 memset(pBits->storage, 0, count * sizeof(u4));
316 * Determine whether or not the specified bit is set.
318 bool dvmIsBitSet(const BitVector* pBits, int num)
320 assert(num >= 0 && num < (int) pBits->storageSize * (int)sizeof(u4) * 8);
322 int val = pBits->storage[num >> 5] & (1 << (num & 0x1f));
327 * Count the number of bits that are set.
329 int dvmCountSetBits(const BitVector* pBits)
334 for (word = 0; word < pBits->storageSize; word++) {
335 u4 val = pBits->storage[word];
338 if (val == 0xffffffff) {
341 /* count the number of '1' bits */
354 * Copy a whole vector to the other. Only do that when the both vectors have
355 * the same size and attribute.
357 bool dvmCopyBitVector(BitVector *dest, const BitVector *src)
359 if (dest->storageSize != src->storageSize ||
360 dest->expandable != src->expandable)
362 memcpy(dest->storage, src->storage, sizeof(u4) * dest->storageSize);
367 * Intersect two bit vectores and merge the result on top of the pre-existing
368 * value in the dest vector.
370 bool dvmIntersectBitVectors(BitVector *dest, const BitVector *src1,
371 const BitVector *src2)
373 if (dest->storageSize != src1->storageSize ||
374 dest->storageSize != src2->storageSize ||
375 dest->expandable != src1->expandable ||
376 dest->expandable != src2->expandable)
380 for (i = 0; i < dest->storageSize; i++) {
381 dest->storage[i] |= src1->storage[i] & src2->storage[i];
387 * Return a newly-allocated string in which all occurrences of '.' have
388 * been changed to '/'. If we find a '/' in the original string, NULL
389 * is returned to avoid ambiguity.
391 char* dvmDotToSlash(const char* str)
393 char* newStr = strdup(str);
399 while (*cp != '\0') {
412 char* dvmHumanReadableDescriptor(const char* descriptor)
414 // Count the number of '['s to get the dimensionality.
415 const char* c = descriptor;
422 // Work out how large the result will be.
425 // "[[La/b/C;" -> "a.b.C[][]".
426 resultLength = strlen(c) - 2 + 2*dim;
427 c++; // Skip the 'L'.
429 // "[[B" -> "byte[][]".
430 // To make life easier, we make primitives look like unqualified
433 case 'B': c = "byte;"; break;
434 case 'C': c = "char;"; break;
435 case 'D': c = "double;"; break;
436 case 'F': c = "float;"; break;
437 case 'I': c = "int;"; break;
438 case 'J': c = "long;"; break;
439 case 'S': c = "short;"; break;
440 case 'Z': c = "boolean;"; break;
441 default: return strdup(descriptor);
443 resultLength = strlen(c) - 1 + 2*dim;
446 // Allocate enough space.
447 char* result = malloc(resultLength + 1);
448 if (result == NULL) {
452 // At this point, 'c' is a string of the form "fully/qualified/Type;"
453 // or "primitive;". Rewrite the type with '.' instead of '/':
463 // ...and replace the semicolon with 'dim' "[]" pairs:
473 * Return a newly-allocated string for the "dot version" of the class
474 * name for the given type descriptor. That is, The initial "L" and
475 * final ";" (if any) have been removed and all occurrences of '/'
476 * have been changed to '.'.
478 * "Dot version" names are used in the class loading machinery.
479 * See also dvmHumanReadableDescriptor.
481 char* dvmDescriptorToDot(const char* str)
483 size_t at = strlen(str);
486 if ((at >= 2) && (str[0] == 'L') && (str[at - 1] == ';')) {
487 at -= 2; /* Two fewer chars to copy. */
488 str++; /* Skip the 'L'. */
491 newStr = malloc(at + 1); /* Add one for the '\0'. */
499 newStr[at] = (str[at] == '/') ? '.' : str[at];
506 * Return a newly-allocated string for the type descriptor
507 * corresponding to the "dot version" of the given class name. That
508 * is, non-array names are surrounded by "L" and ";", and all
509 * occurrences of '.' have been changed to '/'.
511 * "Dot version" names are used in the class loading machinery.
513 char* dvmDotToDescriptor(const char* str)
515 size_t length = strlen(str);
521 length += 2; /* for "L" and ";" */
525 newStr = at = malloc(length + 1); /* + 1 for the '\0' */
527 if (newStr == NULL) {
552 * Return a newly-allocated string for the internal-form class name for
553 * the given type descriptor. That is, the initial "L" and final ";" (if
554 * any) have been removed.
556 char* dvmDescriptorToName(const char* str)
559 size_t length = strlen(str) - 1;
560 char* newStr = malloc(length);
562 if (newStr == NULL) {
566 strlcpy(newStr, str + 1, length);
574 * Return a newly-allocated string for the type descriptor for the given
575 * internal-form class name. That is, a non-array class name will get
576 * surrounded by "L" and ";", while array names are left as-is.
578 char* dvmNameToDescriptor(const char* str)
581 size_t length = strlen(str);
582 char* descriptor = malloc(length + 3);
584 if (descriptor == NULL) {
589 strcpy(descriptor + 1, str);
590 descriptor[length + 1] = ';';
591 descriptor[length + 2] = '\0';
600 * Get a notion of the current time, in nanoseconds. This is meant for
601 * computing durations (e.g. "operation X took 52nsec"), so the result
602 * should not be used to get the current date/time.
604 u8 dvmGetRelativeTimeNsec(void)
606 #ifdef HAVE_POSIX_CLOCKS
608 clock_gettime(CLOCK_MONOTONIC, &now);
609 return (u8)now.tv_sec*1000000000LL + now.tv_nsec;
612 gettimeofday(&now, NULL);
613 return (u8)now.tv_sec*1000000000LL + now.tv_usec * 1000LL;
618 * Get the per-thread CPU time, in nanoseconds.
620 * Only useful for time deltas.
622 u8 dvmGetThreadCpuTimeNsec(void)
624 #ifdef HAVE_POSIX_CLOCKS
626 clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now);
627 return (u8)now.tv_sec*1000000000LL + now.tv_nsec;
634 * Get the per-thread CPU time, in nanoseconds, for the specified thread.
636 u8 dvmGetOtherThreadCpuTimeNsec(pthread_t thread)
638 #if 0 /*def HAVE_POSIX_CLOCKS*/
641 if (pthread_getcpuclockid(thread, &clockId) != 0)
645 clock_gettime(clockId, &now);
646 return (u8)now.tv_sec*1000000000LL + now.tv_nsec;
654 * Call this repeatedly, with successively higher values for "iteration",
655 * to sleep for a period of time not to exceed "maxTotalSleep".
657 * For example, when called with iteration==0 we will sleep for a very
658 * brief time. On the next call we will sleep for a longer time. When
659 * the sum total of all sleeps reaches "maxTotalSleep", this returns false.
661 * The initial start time value for "relStartTime" MUST come from the
662 * dvmGetRelativeTimeUsec call. On the device this must come from the
663 * monotonic clock source, not the wall clock.
665 * This should be used wherever you might be tempted to call sched_yield()
666 * in a loop. The problem with sched_yield is that, for a high-priority
667 * thread, the kernel might not actually transfer control elsewhere.
669 * Returns "false" if we were unable to sleep because our time was up.
671 bool dvmIterativeSleep(int iteration, int maxTotalSleep, u8 relStartTime)
673 const int minSleep = 10000;
678 * Get current time, and see if we've already exceeded the limit.
680 curTime = dvmGetRelativeTimeUsec();
681 if (curTime >= relStartTime + maxTotalSleep) {
682 LOGVV("exsl: sleep exceeded (start=%llu max=%d now=%llu)\n",
683 relStartTime, maxTotalSleep, curTime);
688 * Compute current delay. We're bounded by "maxTotalSleep", so no
689 * real risk of overflow assuming "usleep" isn't returning early.
690 * (Besides, 2^30 usec is about 18 minutes by itself.)
692 * For iteration==0 we just call sched_yield(), so the first sleep
693 * at iteration==1 is actually (minSleep * 2).
696 while (iteration-- > 0)
698 assert(curDelay > 0);
700 if (curTime + curDelay >= relStartTime + maxTotalSleep) {
701 LOGVV("exsl: reduced delay from %d to %d\n",
702 curDelay, (int) ((relStartTime + maxTotalSleep) - curTime));
703 curDelay = (int) ((relStartTime + maxTotalSleep) - curTime);
706 if (iteration == 0) {
707 LOGVV("exsl: yield\n");
710 LOGVV("exsl: sleep for %d\n", curDelay);
718 * Set the "close on exec" flag so we don't expose our file descriptors
719 * to processes launched by us.
721 bool dvmSetCloseOnExec(int fd)
726 * There's presently only one flag defined, so getting the previous
727 * value of the fd flags is probably unnecessary.
729 flags = fcntl(fd, F_GETFD);
731 LOGW("Unable to get fd flags for fd %d\n", fd);
734 if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
735 LOGW("Unable to set close-on-exec for fd %d\n", fd);
742 /* Implementation of strlcpy() for platforms that don't already have it. */
743 size_t strlcpy(char *dst, const char *src, size_t size) {
744 size_t srcLength = strlen(src);
745 size_t copyLength = srcLength;
747 if (srcLength > (size - 1)) {
748 copyLength = size - 1;
752 strncpy(dst, src, copyLength);
753 dst[copyLength] = '\0';
761 * Allocates a memory region using ashmem and mmap, initialized to
762 * zero. Actual allocation rounded up to page multiple. Returns
765 void *dvmAllocRegion(size_t size, int prot, const char *name) {
769 size = ALIGN_UP_TO_PAGE_SIZE(size);
770 fd = ashmem_create_region(name, size);
774 base = mmap(NULL, size, prot, MAP_PRIVATE, fd, 0);
776 if (base == MAP_FAILED) {
786 * Get some per-thread stats.
788 * This is currently generated by opening the appropriate "stat" file
789 * in /proc and reading the pile of stuff that comes out.
791 bool dvmGetThreadStats(ProcStatData* pData, pid_t tid)
797 int ppid, pgrp, session, tty_nr, tpgid;
798 unsigned long flags, minflt, cminflt, majflt, cmajflt, utime, stime;
799 long cutime, cstime, priority, nice, zero, itrealvalue;
800 unsigned long starttime, vsize;
802 unsigned long rlim, startcode, endcode, startstack, kstkesp, kstkeip;
803 unsigned long signal, blocked, sigignore, sigcatch, wchan, nswap, cnswap;
804 int exit_signal, processor;
805 unsigned long rt_priority, policy;
807 scanf("%d %s %c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld "
808 "%ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu "
809 "%lu %lu %lu %d %d %lu %lu",
810 &pid, comm, &state, &ppid, &pgrp, &session, &tty_nr, &tpgid,
811 &flags, &minflt, &cminflt, &majflt, &cmajflt, &utime, &stime,
812 &cutime, &cstime, &priority, &nice, &zero, &itrealvalue,
813 &starttime, &vsize, &rss, &rlim, &startcode, &endcode,
814 &startstack, &kstkesp, &kstkeip, &signal, &blocked, &sigignore,
815 &sigcatch, &wchan, &nswap, &cnswap, &exit_signal, &processor,
816 &rt_priority, &policy);
818 (new: delayacct_blkio_ticks %llu (since Linux 2.6.18))
825 * Open and read the appropriate file. This is expected to work on
826 * Linux but will fail on other platforms (e.g. Mac sim).
828 sprintf(nameBuf, "/proc/self/task/%d/stat", (int) tid);
829 fd = open(nameBuf, O_RDONLY);
831 LOGV("Unable to open '%s': %s\n", nameBuf, strerror(errno));
835 char lineBuf[512]; /* > 2x typical */
836 int cc = read(fd, lineBuf, sizeof(lineBuf)-1);
838 const char* msg = (cc == 0) ? "unexpected EOF" : strerror(errno);
839 LOGI("Unable to read '%s': %s\n", nameBuf, msg);
847 * Skip whitespace-separated tokens. For the most part we can assume
848 * that tokens do not contain spaces, and are separated by exactly one
849 * space character. The only exception is the second field ("comm")
850 * which may contain spaces but is surrounded by parenthesis.
852 char* cp = strchr(lineBuf, ')');
856 for (i = 2; i < 13; i++) {
857 cp = strchr(cp+1, ' ');
866 pData->utime = strtoul(cp+1, &endp, 10);
868 LOGI("Warning: strtoul failed on utime ('%.30s...')\n", cp);
870 cp = strchr(cp+1, ' ');
874 pData->stime = strtoul(cp+1, &endp, 10);
876 LOGI("Warning: strtoul failed on stime ('%.30s...')\n", cp);
879 * Skip more stuff we don't care about.
881 for (i = 14; i < 38; i++) {
882 cp = strchr(cp+1, ' ');
888 * Grab processor number.
890 pData->processor = strtol(cp+1, &endp, 10);
892 LOGI("Warning: strtoul failed on processor ('%.30s...')\n", cp);
897 LOGI("stat parse failed (%s)\n", lineBuf);
901 /* documented in header file */
902 const char* dvmPathToAbsolutePortion(const char* path) {
907 if (path[0] == '/') {
908 /* It's a regular absolute path. Return it. */
912 const char* sentinel = strstr(path, "/./");
914 if (sentinel != NULL) {
915 /* It's got the sentinel. Return a pointer to the second slash. */