diff options
author | Tim Newsome <tim@sifive.com> | 2020-10-07 14:31:36 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-07 14:31:36 -0700 |
commit | 6c1bd050881c1ed1702218b1224d3eb7a5336ae8 (patch) | |
tree | c49823711f915d5c94ec5f9bb52f6680171ff693 /src/target/target.c | |
parent | e2cfd4e063523124aab21b979f2beced7db0347c (diff) | |
download | riscv-openocd-6c1bd050881c1ed1702218b1224d3eb7a5336ae8.zip riscv-openocd-6c1bd050881c1ed1702218b1224d3eb7a5336ae8.tar.gz riscv-openocd-6c1bd050881c1ed1702218b1224d3eb7a5336ae8.tar.bz2 |
Add memory sample feature (#541)
* Add memory sampling feature.
Currently only gets 10 samples per second, but the overall scaffolding
looks like it works.
Change-Id: I25a2bbcba322f2101c3de598c225f83c902680fa
* Basic memory sample speed-ups.
977 samples/second.
Change-Id: I6ea874f25051aca1cbe3aa2918567a4ee316c4be
* Add base64 dumping of sample buffer.
We can't just dump raw data, because the API we use to get data to the
"user" uses NULL-terminated strings.
Change-Id: I3f33faaa485a74735c13cdaad685e336c1e2095f
* WIP on optimizing PC sampling.
1k samples per second on my laptop, which is roughly double what it was.
Change-Id: I6a77df8aa53118e44928f96d22210df84be45eda
* WIP
Change-Id: I4300692355cb0cf997ec59ab5ca71543b295abb0
* Use small batch to sample memory.
5k samples/second. No error checking.
Change-Id: I8a7f08e49cb153699021e27f8006beb0e6db70ee
* Collect memory samples near continuously.
Rewrite OpenOCD's core loop to get rid of the fixed 100ms delay.
Now collecting 15k samples/second.
Change-Id: Iba5e73e96e8d226a0b5777ecac19453c152dc634
* Fix build.
Change-Id: If2fe7a0c77e0d6545c93fa0d4a013c50a9b9d896
* Fix the mess I left after resolving conflicts.
Change-Id: I96abd47a7834bf8f5e005ba63020f0a0cc429548
* Support 64-bit address in memory sampling.
* Support sampling 64-bit values.
* Better error reporting. WIP on 64-bit support.
* Speed up single 32-bit memory sample.
21k samples/second.
* WIP on review feedback.
Change-Id: I00e453fd685d173b0206d925090beb06c1f057ca
* Make memory sample buffers/config per-target.
Change-Id: I5c2f5997795c7a434e71b36ca4c712623daf993c
* Document, and add bucket clear option.
Change-Id: I922b883adfa787fb4f5a894db872d04fda126cbd
Signed-off-by: Tim Newsome <tim@sifive.com>
* Fix whitespace.
Change-Id: Iabfeb0068d7138d9b252ac127d1b1f949cf19632
Signed-off-by: Tim Newsome <tim@sifive.com>
* Document sample buffer full behavior.
Change-Id: Ib3c30d34b1f9f30cf403afda8fdccb850bc8b4df
Signed-off-by: Tim Newsome <tim@sifive.com>
* Actually clear the sample buffer in dump_sample_buf.
Change-Id: Ifda22643f1e58f69a6382abc90474659d7330ac5
Signed-off-by: Tim Newsome <tim@sifive.com>
* Use compatible string formatting.
Change-Id: Ia5e5333e036c1dbe457bc977fcee41983b9a9b77
Signed-off-by: Tim Newsome <tim@sifive.com>
Diffstat (limited to 'src/target/target.c')
-rw-r--r-- | src/target/target.c | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/src/target/target.c b/src/target/target.c index 3395b2a..ca1ded3 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -158,7 +158,7 @@ static struct target_event_callback *target_event_callbacks; static struct target_timer_callback *target_timer_callbacks; LIST_HEAD(target_reset_callback_list); LIST_HEAD(target_trace_callback_list); -static const int polling_interval = 100; +static const int polling_interval = TARGET_DEFAULT_POLLING_INTERVAL; static const Jim_Nvp nvp_assert[] = { { .name = "assert", NVP_ASSERT }, @@ -674,7 +674,7 @@ static int target_process_reset(struct command_invocation *cmd, enum target_rese } /* We want any events to be processed before the prompt */ - retval = target_call_timer_callbacks_now(); + retval = target_call_timer_callbacks_now(NULL); for (target = all_targets; target; target = target->next) { target->type->check_reset(target); @@ -1534,8 +1534,7 @@ int target_register_timer_callback(int (*callback)(void *priv), (*callbacks_p)->time_ms = time_ms; (*callbacks_p)->removed = false; - gettimeofday(&(*callbacks_p)->when, NULL); - timeval_add_time(&(*callbacks_p)->when, 0, time_ms * 1000); + (*callbacks_p)->when = timeval_ms() + time_ms; (*callbacks_p)->priv = priv; (*callbacks_p)->next = NULL; @@ -1669,15 +1668,14 @@ int target_call_trace_callbacks(struct target *target, size_t len, uint8_t *data } static int target_timer_callback_periodic_restart( - struct target_timer_callback *cb, struct timeval *now) + struct target_timer_callback *cb, int64_t *now) { - cb->when = *now; - timeval_add_time(&cb->when, 0, cb->time_ms * 1000L); + cb->when = *now + cb->time_ms; return ERROR_OK; } static int target_call_timer_callback(struct target_timer_callback *cb, - struct timeval *now) + int64_t *now) { cb->callback(cb->priv); @@ -1687,7 +1685,7 @@ static int target_call_timer_callback(struct target_timer_callback *cb, return target_unregister_timer_callback(cb->callback, cb->priv); } -static int target_call_timer_callbacks_check_time(int checktime) +static int target_call_timer_callbacks_check_time(int64_t *next_event, int checktime) { static bool callback_processing; @@ -1699,8 +1697,9 @@ static int target_call_timer_callbacks_check_time(int checktime) keep_alive(); - struct timeval now; - gettimeofday(&now, NULL); + int64_t now = timeval_ms(); + if (next_event) + *next_event = now + 1000; /* Store an address of the place containing a pointer to the * next item; initially, that's a standalone "root of the @@ -1716,11 +1715,14 @@ static int target_call_timer_callbacks_check_time(int checktime) bool call_it = (*callback)->callback && ((!checktime && (*callback)->type == TARGET_TIMER_TYPE_PERIODIC) || - timeval_compare(&now, &(*callback)->when) >= 0); + now >= (*callback)->when); if (call_it) target_call_timer_callback(*callback, &now); + if (next_event && (*callback)->when < *next_event) + *next_event = (*callback)->when; + callback = &(*callback)->next; } @@ -1728,15 +1730,19 @@ static int target_call_timer_callbacks_check_time(int checktime) return ERROR_OK; } -int target_call_timer_callbacks(void) +/** + * This function updates *next_event with the time (according to timeval_ms()) + * that it would next need to be called in order to run all callbacks on time. + */ +int target_call_timer_callbacks(int64_t *next_event) { - return target_call_timer_callbacks_check_time(1); + return target_call_timer_callbacks_check_time(next_event, 1); } /* invoke periodic callbacks immediately */ -int target_call_timer_callbacks_now(void) +int target_call_timer_callbacks_now(int64_t *next_event) { - return target_call_timer_callbacks_check_time(0); + return target_call_timer_callbacks_check_time(next_event, 0); } /* Prints the working area layout for debug purposes */ |