1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 /* 17 * Miscellaneous utility functions. 18 */ 19 #include "Dalvik.h" 20 21 #include <stdlib.h> 22 #include <stddef.h> 23 #include <string.h> 24 #include <strings.h> 25 #include <ctype.h> 26 #include <time.h> 27 #include <sys/time.h> 28 #include <fcntl.h> 29 30 31 /* 32 * Print a hex dump in this format: 33 * 34 01234567: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 0123456789abcdef\n 35 * 36 * If "mode" is kHexDumpLocal, we start at offset zero, and show a full 37 * 16 bytes on the first line. If it's kHexDumpMem, we make this look 38 * like a memory dump, using the actual address, outputting a partial line 39 * if "vaddr" isn't aligned on a 16-byte boundary. 40 * 41 * "priority" and "tag" determine the values passed to the log calls. 42 * 43 * Does not use printf() or other string-formatting calls. 44 */ 45 void dvmPrintHexDumpEx(int priority, const char* tag, const void* vaddr, 46 size_t length, HexDumpMode mode) 47 { 48 static const char gHexDigit[] = "0123456789abcdef"; 49 const unsigned char* addr = vaddr; 50 char out[77]; /* exact fit */ 51 unsigned int offset; /* offset to show while printing */ 52 char* hex; 53 char* asc; 54 int gap; 55 //int trickle = 0; 56 57 if (mode == kHexDumpLocal) 58 offset = 0; 59 else 60 offset = (int) addr; 61 62 memset(out, ' ', sizeof(out)-1); 63 out[8] = ':'; 64 out[sizeof(out)-2] = '\n'; 65 out[sizeof(out)-1] = '\0'; 66 67 gap = (int) offset & 0x0f; 68 while (length) { 69 unsigned int lineOffset = offset & ~0x0f; 70 int i, count; 71 72 hex = out; 73 asc = out + 59; 74 75 for (i = 0; i < 8; i++) { 76 *hex++ = gHexDigit[lineOffset >> 28]; 77 lineOffset <<= 4; 78 } 79 hex++; 80 hex++; 81 82 count = ((int)length > 16-gap) ? 16-gap : (int)length; /* cap length */ 83 assert(count != 0); 84 assert(count+gap <= 16); 85 86 if (gap) { 87 /* only on first line */ 88 hex += gap * 3; 89 asc += gap; 90 } 91 92 for (i = gap ; i < count+gap; i++) { 93 *hex++ = gHexDigit[*addr >> 4]; 94 *hex++ = gHexDigit[*addr & 0x0f]; 95 hex++; 96 if (*addr >= 0x20 && *addr < 0x7f /*isprint(*addr)*/) 97 *asc++ = *addr; 98 else 99 *asc++ = '.'; 100 addr++; 101 } 102 for ( ; i < 16; i++) { 103 /* erase extra stuff; only happens on last line */ 104 *hex++ = ' '; 105 *hex++ = ' '; 106 hex++; 107 *asc++ = ' '; 108 } 109 110 LOG_PRI(priority, tag, "%s", out); 111 #if 0 //def HAVE_ANDROID_OS 112 /* 113 * We can overrun logcat easily by writing at full speed. On the 114 * other hand, we can make Eclipse time out if we're showing 115 * packet dumps while debugging JDWP. 116 */ 117 { 118 if (trickle++ == 8) { 119 trickle = 0; 120 usleep(20000); 121 } 122 } 123 #endif 124 125 gap = 0; 126 length -= count; 127 offset += count; 128 } 129 } 130 131 132 /* 133 * Fill out a DebugOutputTarget, suitable for printing to the log. 134 */ 135 void dvmCreateLogOutputTarget(DebugOutputTarget* target, int priority, 136 const char* tag) 137 { 138 assert(target != NULL); 139 assert(tag != NULL); 140 141 target->which = kDebugTargetLog; 142 target->data.log.priority = priority; 143 target->data.log.tag = tag; 144 } 145 146 /* 147 * Fill out a DebugOutputTarget suitable for printing to a file pointer. 148 */ 149 void dvmCreateFileOutputTarget(DebugOutputTarget* target, FILE* fp) 150 { 151 assert(target != NULL); 152 assert(fp != NULL); 153 154 target->which = kDebugTargetFile; 155 target->data.file.fp = fp; 156 } 157 158 /* 159 * Free "target" and any associated data. 160 */ 161 void dvmFreeOutputTarget(DebugOutputTarget* target) 162 { 163 free(target); 164 } 165 166 /* 167 * Print a debug message, to either a file or the log. 168 */ 169 void dvmPrintDebugMessage(const DebugOutputTarget* target, const char* format, 170 ...) 171 { 172 va_list args; 173 174 va_start(args, format); 175 176 switch (target->which) { 177 case kDebugTargetLog: 178 LOG_PRI_VA(target->data.log.priority, target->data.log.tag, 179 format, args); 180 break; 181 case kDebugTargetFile: 182 vfprintf(target->data.file.fp, format, args); 183 break; 184 default: 185 LOGE("unexpected 'which' %d\n", target->which); 186 break; 187 } 188 189 va_end(args); 190 } 191 192 193 /* 194 * Allocate a bit vector with enough space to hold at least the specified 195 * number of bits. 196 */ 197 BitVector* dvmAllocBitVector(int startBits, bool expandable) 198 { 199 BitVector* bv; 200 int count; 201 202 assert(sizeof(bv->storage[0]) == 4); /* assuming 32-bit units */ 203 assert(startBits >= 0); 204 205 bv = (BitVector*) malloc(sizeof(BitVector)); 206 207 count = (startBits + 31) >> 5; 208 209 bv->storageSize = count; 210 bv->expandable = expandable; 211 bv->storage = (u4*) malloc(count * sizeof(u4)); 212 memset(bv->storage, 0x00, count * sizeof(u4)); 213 return bv; 214 } 215 216 /* 217 * Free a BitVector. 218 */ 219 void dvmFreeBitVector(BitVector* pBits) 220 { 221 if (pBits == NULL) 222 return; 223 224 free(pBits->storage); 225 free(pBits); 226 } 227 228 /* 229 * "Allocate" the first-available bit in the bitmap. 230 * 231 * This is not synchronized. The caller is expected to hold some sort of 232 * lock that prevents multiple threads from executing simultaneously in 233 * dvmAllocBit/dvmFreeBit. 234 */ 235 int dvmAllocBit(BitVector* pBits) 236 { 237 int word, bit; 238 239 retry: 240 for (word = 0; word < pBits->storageSize; word++) { 241 if (pBits->storage[word] != 0xffffffff) { 242 /* 243 * There are unallocated bits in this word. Return the first. 244 */ 245 bit = ffs(~(pBits->storage[word])) -1; 246 assert(bit >= 0 && bit < 32); 247 pBits->storage[word] |= 1 << bit; 248 return (word << 5) | bit; 249 } 250 } 251 252 /* 253 * Ran out of space, allocate more if we're allowed to. 254 */ 255 if (!pBits->expandable) 256 return -1; 257 258 pBits->storage = realloc(pBits->storage, 259 (pBits->storageSize + kBitVectorGrowth) * sizeof(u4)); 260 memset(&pBits->storage[pBits->storageSize], 0x00, 261 kBitVectorGrowth * sizeof(u4)); 262 pBits->storageSize += kBitVectorGrowth; 263 goto retry; 264 } 265 266 /* 267 * Mark the specified bit as "set". 268 * 269 * Returns "false" if the bit is outside the range of the vector and we're 270 * not allowed to expand. 271 */ 272 bool dvmSetBit(BitVector* pBits, int num) 273 { 274 assert(num >= 0); 275 if (num >= pBits->storageSize * (int)sizeof(u4) * 8) { 276 if (!pBits->expandable) 277 return false; 278 279 int newSize = (num + 31) >> 5; 280 assert(newSize > pBits->storageSize); 281 pBits->storage = realloc(pBits->storage, newSize * sizeof(u4)); 282 memset(&pBits->storage[pBits->storageSize], 0x00, 283 (newSize - pBits->storageSize) * sizeof(u4)); 284 pBits->storageSize = newSize; 285 } 286 287 pBits->storage[num >> 5] |= 1 << (num & 0x1f); 288 return true; 289 } 290 291 /* 292 * Mark the specified bit as "clear". 293 */ 294 void dvmClearBit(BitVector* pBits, int num) 295 { 296 assert(num >= 0 && num < (int) pBits->storageSize * (int)sizeof(u4) * 8); 297 298 pBits->storage[num >> 5] &= ~(1 << (num & 0x1f)); 299 } 300 301 /* 302 * Mark all bits bit as "clear". 303 */ 304 void dvmClearAllBits(BitVector* pBits) 305 { 306 int count = pBits->storageSize; 307 memset(pBits->storage, 0, count * sizeof(u4)); 308 } 309 310 /* 311 * Determine whether or not the specified bit is set. 312 */ 313 bool dvmIsBitSet(const BitVector* pBits, int num) 314 { 315 assert(num >= 0 && num < (int) pBits->storageSize * (int)sizeof(u4) * 8); 316 317 int val = pBits->storage[num >> 5] & (1 << (num & 0x1f)); 318 return (val != 0); 319 } 320 321 /* 322 * Count the number of bits that are set. 323 */ 324 int dvmCountSetBits(const BitVector* pBits) 325 { 326 int word, bit; 327 int count = 0; 328 329 for (word = 0; word < pBits->storageSize; word++) { 330 u4 val = pBits->storage[word]; 331 332 if (val != 0) { 333 if (val == 0xffffffff) { 334 count += 32; 335 } else { 336 /* count the number of '1' bits */ 337 while (val != 0) { 338 val &= val - 1; 339 count++; 340 } 341 } 342 } 343 } 344 345 return count; 346 } 347 348 /* 349 * Copy a whole vector to the other. Only do that when the both vectors have 350 * the same size and attribute. 351 */ 352 bool dvmCopyBitVector(BitVector *dest, const BitVector *src) 353 { 354 if (dest->storageSize != src->storageSize || 355 dest->expandable != src->expandable) 356 return false; 357 memcpy(dest->storage, src->storage, sizeof(u4) * dest->storageSize); 358 return true; 359 } 360 361 /* 362 * Intersect two bit vectores and merge the result on top of the pre-existing 363 * value in the dest vector. 364 */ 365 bool dvmIntersectBitVectors(BitVector *dest, const BitVector *src1, 366 const BitVector *src2) 367 { 368 if (dest->storageSize != src1->storageSize || 369 dest->storageSize != src2->storageSize || 370 dest->expandable != src1->expandable || 371 dest->expandable != src2->expandable) 372 return false; 373 374 int i; 375 for (i = 0; i < dest->storageSize; i++) { 376 dest->storage[i] |= src1->storage[i] & src2->storage[i]; 377 } 378 return true; 379 } 380 381 /* 382 * Return a newly-allocated string in which all occurrences of '.' have 383 * been changed to '/'. If we find a '/' in the original string, NULL 384 * is returned to avoid ambiguity. 385 */ 386 char* dvmDotToSlash(const char* str) 387 { 388 char* newStr = strdup(str); 389 char* cp = newStr; 390 391 if (newStr == NULL) 392 return NULL; 393 394 while (*cp != '\0') { 395 if (*cp == '/') { 396 assert(false); 397 return NULL; 398 } 399 if (*cp == '.') 400 *cp = '/'; 401 cp++; 402 } 403 404 return newStr; 405 } 406 407 /* 408 * Return a newly-allocated string for the "dot version" of the class 409 * name for the given type descriptor. That is, The initial "L" and 410 * final ";" (if any) have been removed and all occurrences of '/' 411 * have been changed to '.'. 412 */ 413 char* dvmDescriptorToDot(const char* str) 414 { 415 size_t at = strlen(str); 416 char* newStr; 417 418 if ((at >= 2) && (str[0] == 'L') && (str[at - 1] == ';')) { 419 at -= 2; /* Two fewer chars to copy. */ 420 str++; /* Skip the 'L'. */ 421 } 422 423 newStr = malloc(at + 1); /* Add one for the '\0'. */ 424 if (newStr == NULL) 425 return NULL; 426 427 newStr[at] = '\0'; 428 429 while (at > 0) { 430 at--; 431 newStr[at] = (str[at] == '/') ? '.' : str[at]; 432 } 433 434 return newStr; 435 } 436 437 /* 438 * Return a newly-allocated string for the type descriptor 439 * corresponding to the "dot version" of the given class name. That 440 * is, non-array names are surrounded by "L" and ";", and all 441 * occurrences of '.' are changed to '/'. 442 */ 443 char* dvmDotToDescriptor(const char* str) 444 { 445 size_t length = strlen(str); 446 int wrapElSemi = 0; 447 char* newStr; 448 char* at; 449 450 if (str[0] != '[') { 451 length += 2; /* for "L" and ";" */ 452 wrapElSemi = 1; 453 } 454 455 newStr = at = malloc(length + 1); /* + 1 for the '\0' */ 456 457 if (newStr == NULL) { 458 return NULL; 459 } 460 461 if (wrapElSemi) { 462 *(at++) = 'L'; 463 } 464 465 while (*str) { 466 char c = *(str++); 467 if (c == '.') { 468 c = '/'; 469 } 470 *(at++) = c; 471 } 472 473 if (wrapElSemi) { 474 *(at++) = ';'; 475 } 476 477 *at = '\0'; 478 return newStr; 479 } 480 481 /* 482 * Return a newly-allocated string for the internal-form class name for 483 * the given type descriptor. That is, the initial "L" and final ";" (if 484 * any) have been removed. 485 */ 486 char* dvmDescriptorToName(const char* str) 487 { 488 if (str[0] == 'L') { 489 size_t length = strlen(str) - 1; 490 char* newStr = malloc(length); 491 492 if (newStr == NULL) { 493 return NULL; 494 } 495 496 strlcpy(newStr, str + 1, length); 497 return newStr; 498 } 499 500 return strdup(str); 501 } 502 503 /* 504 * Return a newly-allocated string for the type descriptor for the given 505 * internal-form class name. That is, a non-array class name will get 506 * surrounded by "L" and ";", while array names are left as-is. 507 */ 508 char* dvmNameToDescriptor(const char* str) 509 { 510 if (str[0] != '[') { 511 size_t length = strlen(str); 512 char* descriptor = malloc(length + 3); 513 514 if (descriptor == NULL) { 515 return NULL; 516 } 517 518 descriptor[0] = 'L'; 519 strcpy(descriptor + 1, str); 520 descriptor[length + 1] = ';'; 521 descriptor[length + 2] = '\0'; 522 523 return descriptor; 524 } 525 526 return strdup(str); 527 } 528 529 /* 530 * Get a notion of the current time, in nanoseconds. This is meant for 531 * computing durations (e.g. "operation X took 52nsec"), so the result 532 * should not be used to get the current date/time. 533 */ 534 u8 dvmGetRelativeTimeNsec(void) 535 { 536 #ifdef HAVE_POSIX_CLOCKS 537 struct timespec now; 538 clock_gettime(CLOCK_MONOTONIC, &now); 539 return (u8)now.tv_sec*1000000000LL + now.tv_nsec; 540 #else 541 struct timeval now; 542 gettimeofday(&now, NULL); 543 return (u8)now.tv_sec*1000000000LL + now.tv_usec * 1000LL; 544 #endif 545 } 546 547 /* 548 * Get the per-thread CPU time, in nanoseconds. 549 * 550 * Only useful for time deltas. 551 */ 552 u8 dvmGetThreadCpuTimeNsec(void) 553 { 554 #ifdef HAVE_POSIX_CLOCKS 555 struct timespec now; 556 clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now); 557 return (u8)now.tv_sec*1000000000LL + now.tv_nsec; 558 #else 559 return (u8) -1; 560 #endif 561 } 562 563 /* 564 * Get the per-thread CPU time, in nanoseconds, for the specified thread. 565 */ 566 u8 dvmGetOtherThreadCpuTimeNsec(pthread_t thread) 567 { 568 #if 0 /*def HAVE_POSIX_CLOCKS*/ 569 int clockId; 570 571 if (pthread_getcpuclockid(thread, &clockId) != 0) 572 return (u8) -1; 573 574 struct timespec now; 575 clock_gettime(clockId, &now); 576 return (u8)now.tv_sec*1000000000LL + now.tv_nsec; 577 #else 578 return (u8) -1; 579 #endif 580 } 581 582 583 /* 584 * Call this repeatedly, with successively higher values for "iteration", 585 * to sleep for a period of time not to exceed "maxTotalSleep". 586 * 587 * For example, when called with iteration==0 we will sleep for a very 588 * brief time. On the next call we will sleep for a longer time. When 589 * the sum total of all sleeps reaches "maxTotalSleep", this returns false. 590 * 591 * The initial start time value for "relStartTime" MUST come from the 592 * dvmGetRelativeTimeUsec call. On the device this must come from the 593 * monotonic clock source, not the wall clock. 594 * 595 * This should be used wherever you might be tempted to call sched_yield() 596 * in a loop. The problem with sched_yield is that, for a high-priority 597 * thread, the kernel might not actually transfer control elsewhere. 598 * 599 * Returns "false" if we were unable to sleep because our time was up. 600 */ 601 bool dvmIterativeSleep(int iteration, int maxTotalSleep, u8 relStartTime) 602 { 603 const int minSleep = 10000; 604 u8 curTime; 605 int curDelay; 606 607 /* 608 * Get current time, and see if we've already exceeded the limit. 609 */ 610 curTime = dvmGetRelativeTimeUsec(); 611 if (curTime >= relStartTime + maxTotalSleep) { 612 LOGVV("exsl: sleep exceeded (start=%llu max=%d now=%llu)\n", 613 relStartTime, maxTotalSleep, curTime); 614 return false; 615 } 616 617 /* 618 * Compute current delay. We're bounded by "maxTotalSleep", so no 619 * real risk of overflow assuming "usleep" isn't returning early. 620 * (Besides, 2^30 usec is about 18 minutes by itself.) 621 * 622 * For iteration==0 we just call sched_yield(), so the first sleep 623 * at iteration==1 is actually (minSleep * 2). 624 */ 625 curDelay = minSleep; 626 while (iteration-- > 0) 627 curDelay *= 2; 628 assert(curDelay > 0); 629 630 if (curTime + curDelay >= relStartTime + maxTotalSleep) { 631 LOGVV("exsl: reduced delay from %d to %d\n", 632 curDelay, (int) ((relStartTime + maxTotalSleep) - curTime)); 633 curDelay = (int) ((relStartTime + maxTotalSleep) - curTime); 634 } 635 636 if (iteration == 0) { 637 LOGVV("exsl: yield\n"); 638 sched_yield(); 639 } else { 640 LOGVV("exsl: sleep for %d\n", curDelay); 641 usleep(curDelay); 642 } 643 return true; 644 } 645 646 647 /* 648 * Set the "close on exec" flag so we don't expose our file descriptors 649 * to processes launched by us. 650 */ 651 bool dvmSetCloseOnExec(int fd) 652 { 653 int flags; 654 655 /* 656 * There's presently only one flag defined, so getting the previous 657 * value of the fd flags is probably unnecessary. 658 */ 659 flags = fcntl(fd, F_GETFD); 660 if (flags < 0) { 661 LOGW("Unable to get fd flags for fd %d\n", fd); 662 return false; 663 } 664 if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) { 665 LOGW("Unable to set close-on-exec for fd %d\n", fd); 666 return false; 667 } 668 return true; 669 } 670 671 #if (!HAVE_STRLCPY) 672 /* Implementation of strlcpy() for platforms that don't already have it. */ 673 size_t strlcpy(char *dst, const char *src, size_t size) { 674 size_t srcLength = strlen(src); 675 size_t copyLength = srcLength; 676 677 if (srcLength > (size - 1)) { 678 copyLength = size - 1; 679 } 680 681 if (size != 0) { 682 strncpy(dst, src, copyLength); 683 dst[copyLength] = '\0'; 684 } 685 686 return srcLength; 687 } 688 #endif 689