You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.5 KiB
87 lines
2.5 KiB
/* |
|
* This file is free software: you can redistribute it and/or modify it |
|
* under the terms of the GNU General Public License as published by the |
|
* Free Software Foundation, either version 3 of the License, or |
|
* (at your option) any later version. |
|
* |
|
* This file is distributed in the hope that it will be useful, but |
|
* WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
* See the GNU General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License along |
|
* with this program. If not, see <http://www.gnu.org/licenses/>. |
|
* |
|
*/ |
|
#ifdef ENABLE_PROFILE |
|
#include <AP_HAL/AP_HAL.h> |
|
#include <stdio.h> |
|
#include <errno.h> |
|
|
|
#define ARRAY_SIZE(_arr) (sizeof(_arr) / sizeof(_arr[0])) |
|
|
|
struct FI { |
|
uint32_t address; |
|
uint32_t count; |
|
struct FI * next; |
|
}; |
|
|
|
FI* ht[1024]; |
|
|
|
extern "C" __attribute__((section(".iram1"))) __attribute__((no_instrument_function)) |
|
void _mcount() |
|
{ |
|
void *a = __builtin_return_address(0); |
|
a = __builtin_extract_return_addr(a); |
|
uint32_t address = (uint32_t) a; |
|
uint32_t hash = address; |
|
hash = ((hash >> 16)^hash)*0x45d9f3b; |
|
hash = ((hash >> 16)^hash)*0x45d9f3b; |
|
uint32_t index = ((hash >> 16)^hash)%ARRAY_SIZE(ht); |
|
FI **current = &(ht[index]); |
|
while (*current != nullptr && (*current)->address != address) { |
|
current = &((*current)->next); |
|
} |
|
if (*current != nullptr) { |
|
(*current)->count++; |
|
} else { |
|
FI* next = (FI *)calloc(1, sizeof(FI)); |
|
next->address = address; |
|
next->count = 1; |
|
next->next = nullptr; |
|
*current = next; |
|
} |
|
} |
|
|
|
void print_profile() |
|
{ |
|
static int64_t last_run = 0; |
|
static int counter = 0; |
|
if (AP_HAL::millis64() - last_run > 60000) { |
|
//char fname[50]; |
|
//snprintf(fname, sizeof(fname), "/SDCARD/APM/PROF%03d.TXT", counter); |
|
++counter; |
|
//FILE *f = fopen(fname, "w"); |
|
// if (f != nullptr) { |
|
for (size_t i=0; i < ARRAY_SIZE(ht); i++) { |
|
for (FI *current = ht[i]; current != nullptr; current = current->next) { |
|
if (current->count != 0) { |
|
printf("0x%016x 0x%x\n", current->address, current->count); |
|
current->count = 0; |
|
} |
|
} |
|
} |
|
// fclose(f); |
|
printf("------- profile dumped %d\n", counter); |
|
/*} else { |
|
printf("profile open error %d %d\n", counter, errno); |
|
}*/ |
|
last_run = AP_HAL::millis64(); |
|
} |
|
} |
|
#else |
|
void print_profile() |
|
{ |
|
} |
|
#endif |
|
|
|
|