-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ncham/duration #31
base: master
Are you sure you want to change the base?
Ncham/duration #31
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1 @@ | ||
add_subdirectory(tutorials) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
add_subdirectory(hello_world) | ||
add_subdirectory(simple_duration) | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
add_executable(simple_duration simple_duration.cpp) | ||
target_link_libraries(simple_duration hawktracer) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#include <hawktracer.h> | ||
#include <unistd.h> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess you need it for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. :) sure I didn't actually notice this was c++... I'll change that. |
||
|
||
int main(int argc, char** argv) | ||
{ | ||
ht_init(argc, argv); | ||
|
||
HT_FileDumpListener* file_dump_listener = ht_file_dump_listener_create("test_output.htdump", 4096u, NULL); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could the output file name contain an example name? |
||
if (file_dump_listener != NULL) | ||
{ | ||
ht_timeline_register_listener(ht_global_timeline_get(), ht_file_dump_listener_callback, file_dump_listener); | ||
} | ||
|
||
ht_feature_duration_enable(ht_global_timeline_get()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The function might fail. I know it's very unlikely, and the error code will be mostly ignored in that case, but since it's an example, I'd prefer to capture all possible errors here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, I think we might actually enable this feature in global timeline by default (see global_timeline.cpp file, we already enable e.g. callstack feature) |
||
|
||
const int NUM_MEASUREMENTS = 10; | ||
HT_DurationId ids[NUM_MEASUREMENTS]; | ||
char names[NUM_MEASUREMENTS][128]; | ||
|
||
printf ("Gathering %d measurements\n", NUM_MEASUREMENTS); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't put spaces between function name and |
||
for (int i = 0; i < NUM_MEASUREMENTS; i++) | ||
{ | ||
sprintf(names[i], "Measurement_name_%d", i); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you use |
||
printf("Starting measurement %d, named %s\n", i, names[i]); | ||
ids[i] = ht_feature_duration_start_string(ht_global_timeline_get(), names[i]); | ||
sleep(1); | ||
} | ||
|
||
for (int i = 0; i < NUM_MEASUREMENTS; i++) | ||
{ | ||
HT_DurationNs duration = ht_feature_duration_stop(ht_global_timeline_get(), ids[i]); | ||
printf("ID: %llu, Duration: %llu nanoseconds.\n", ids[i], duration); | ||
} | ||
|
||
ht_timeline_flush(ht_global_timeline_get()); | ||
ht_timeline_unregister_all_listeners(ht_global_timeline_get()); | ||
ht_file_dump_listener_destroy(file_dump_listener); | ||
ht_feature_duration_disable(ht_global_timeline_get()); | ||
|
||
ht_deinit(); | ||
|
||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,12 @@ | ||
#include "internal/bag.h" | ||
#include "hawktracer/alloc.h" | ||
|
||
#include <string.h> | ||
|
||
static inline HT_Boolean | ||
_ht_bag_resize(HT_Bag* bag, size_t new_capacity) | ||
{ | ||
void** ptr = (void**)ht_realloc(bag->data, new_capacity * sizeof(void*)); | ||
void* ptr = ht_realloc(bag->data, new_capacity * bag->element_size); | ||
|
||
if (ptr == NULL) | ||
{ | ||
|
@@ -18,9 +20,9 @@ _ht_bag_resize(HT_Bag* bag, size_t new_capacity) | |
} | ||
|
||
HT_ErrorCode | ||
ht_bag_init(HT_Bag* bag, size_t min_capacity) | ||
ht_bag_init(HT_Bag* bag, size_t min_capacity, size_t element_size) | ||
{ | ||
bag->data = ht_alloc(min_capacity * sizeof(void*)); | ||
bag->data = ht_alloc(min_capacity * element_size); | ||
|
||
if (bag->data == NULL) | ||
{ | ||
|
@@ -30,6 +32,7 @@ ht_bag_init(HT_Bag* bag, size_t min_capacity) | |
bag->min_capacity = min_capacity; | ||
bag->capacity = min_capacity; | ||
bag->size = 0; | ||
bag->element_size = element_size; | ||
|
||
return HT_ERR_OK; | ||
} | ||
|
@@ -40,7 +43,7 @@ ht_bag_remove(HT_Bag* bag, void* data) | |
size_t i; | ||
for (i = 0; i < bag->size; i++) | ||
{ | ||
if (bag->data[i] == data) | ||
if (!memcmp(ht_bag_get_n(bag, i), data, bag->element_size)) | ||
{ | ||
ht_bag_remove_nth(bag, i); | ||
} | ||
|
@@ -53,7 +56,7 @@ ht_bag_remove_nth(HT_Bag* bag, size_t n) | |
bag->size--; | ||
if (bag->size > 0) | ||
{ | ||
bag->data[n] = bag->data[bag->size]; | ||
memcpy(ht_bag_get_n(bag, n), ht_bag_get_n(bag, bag->size), bag->element_size); | ||
} | ||
|
||
if (bag->capacity > bag->min_capacity && bag->size < bag->capacity / 4) | ||
|
@@ -73,7 +76,8 @@ ht_bag_add(HT_Bag* bag, void* data) | |
} | ||
} | ||
|
||
bag->data[bag->size++] = data; | ||
memcpy(ht_bag_get_n(bag, bag->size), data, bag->element_size); | ||
bag->size++; | ||
|
||
return HT_ERR_OK; | ||
} | ||
|
@@ -90,6 +94,13 @@ ht_bag_deinit(HT_Bag* bag) | |
{ | ||
ht_free(bag->data); | ||
bag->data = NULL; | ||
bag->element_size = 0; | ||
bag->capacity = 0; | ||
bag->size = 0; | ||
} | ||
|
||
void* | ||
ht_bag_get_n(HT_Bag* bag, size_t n) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shouldn't it be |
||
{ | ||
return HT_PTR_ADD(bag->data, n * bag->element_size); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#include "hawktracer/feature_duration.h" | ||
#include "hawktracer/alloc.h" | ||
#include "hawktracer/thread.h" | ||
#include "internal/bag.h" | ||
|
||
typedef struct | ||
{ | ||
HT_Bag bag; | ||
} HT_FeatureDuration; | ||
|
||
HT_ErrorCode | ||
ht_feature_duration_enable(HT_Timeline* timeline) | ||
{ | ||
HT_FeatureDuration* feature = HT_CREATE_TYPE(HT_FeatureDuration); | ||
HT_ErrorCode error_code; | ||
|
||
if (feature == NULL) | ||
{ | ||
return HT_ERR_OUT_OF_MEMORY; | ||
} | ||
|
||
error_code = ht_bag_init(&feature->bag, 1024, sizeof(HT_DurationStringEvent)); | ||
|
||
if (error_code != HT_ERR_OK) | ||
{ | ||
ht_free(feature); | ||
return error_code; | ||
} | ||
|
||
ht_timeline_set_feature(timeline, HT_FEATURE_DURATION, feature); | ||
|
||
return HT_ERR_OK; | ||
} | ||
|
||
void | ||
ht_feature_duration_disable(HT_Timeline* timeline) | ||
{ | ||
HT_FeatureDuration* f = HT_TIMELINE_FEATURE(timeline, HT_FEATURE_DURATION, HT_FeatureDuration); | ||
ht_bag_deinit(&f->bag); | ||
ht_free(f); | ||
ht_timeline_set_feature(timeline, HT_FEATURE_DURATION, NULL); | ||
} | ||
|
||
HT_DurationId ht_feature_duration_start(HT_Timeline* timeline, HT_DurationBaseEvent* event) | ||
{ | ||
HT_FeatureDuration* f = HT_TIMELINE_FEATURE(timeline, HT_FEATURE_DURATION, HT_FeatureDuration); | ||
|
||
ht_timeline_init_event(timeline, HT_EVENT(event)); | ||
/* TODO: handle ht_bag_add() error */ | ||
ht_bag_add(&f->bag, event); | ||
return f->bag.size - 1; | ||
} | ||
|
||
HT_DurationNs ht_feature_duration_stop(HT_Timeline* timeline, HT_DurationId id) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if you want this to return duration? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's very handy to have this duration as a return value |
||
{ | ||
HT_FeatureDuration* f = HT_TIMELINE_FEATURE(timeline, HT_FEATURE_DURATION, HT_FeatureDuration); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know you've copied it from callstack feature, and I'm ok with merging it as it is. But I think it'd be better to not generate any event here, but just return the value, and it's caller's responsibility to create an event. Current implementation is quite convenient, but from the other hand it always generates an event which is a bit problematic because:
Maybe we could have base functionality which doesn't generate any event, but just returns the duration, and on top of it, build a feature which generates actual events? Then it'd be easy for user to extend it. Ofc. we have the same problem in callstack feature. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, I just copied this behaviour but see your point. If we don't create the event here then I can simplify this PR quite a lot since i'd only need to store a timestamp in the bag. |
||
HT_DurationBaseEvent* event = (HT_DurationBaseEvent*) ht_bag_get_n(&f->bag, id); | ||
|
||
HT_DurationNs duration = ht_monotonic_clock_get_timestamp() - HT_EVENT(event)->timestamp; | ||
event->duration = duration; | ||
ht_timeline_push_event((HT_Timeline*)timeline, HT_EVENT(event)); | ||
ht_bag_remove_nth(&f->bag, id); | ||
return duration; | ||
} | ||
|
||
HT_DurationId ht_feature_duration_start_int(HT_Timeline* timeline, HT_DurationEventLabel label) | ||
{ | ||
HT_DECL_EVENT(HT_DurationIntEvent, event); | ||
event.label = label; | ||
|
||
return ht_feature_duration_start(timeline, (HT_DurationBaseEvent*)&event); | ||
} | ||
|
||
HT_DurationId ht_feature_duration_start_string(HT_Timeline* timeline, const char* label) | ||
{ | ||
HT_DECL_EVENT(HT_DurationStringEvent, event); | ||
event.label = label; | ||
|
||
return ht_feature_duration_start(timeline, (HT_DurationBaseEvent*)&event); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#ifndef HT_FEATURE_DURATION_H | ||
#define HT_FEATURE_DURATION_H | ||
|
||
#include <hawktracer/core_events.h> | ||
#include <hawktracer/timeline.h> | ||
|
||
HT_DECLS_BEGIN | ||
|
||
#define HT_FEATURE_DURATION 2 | ||
|
||
HT_API HT_ErrorCode ht_feature_duration_enable(HT_Timeline* timeline); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know that currently we don't have documentation for most of the API, but we try add it at least to a new code. So I'd be very grateful if you could add the documentation here :) |
||
|
||
HT_API void ht_feature_duration_disable(HT_Timeline* timeline); | ||
|
||
HT_API HT_DurationId ht_feature_duration_start(HT_Timeline* timeline, HT_DurationBaseEvent* event); | ||
|
||
HT_API HT_DurationNs ht_feature_duration_stop(HT_Timeline* timeline, HT_DurationId id); | ||
|
||
HT_API HT_DurationId ht_feature_duration_start_int(HT_Timeline* timeline, HT_DurationEventLabel label); | ||
|
||
HT_API HT_DurationId ht_feature_duration_start_string(HT_Timeline* timeline, const char* label); | ||
|
||
HT_DECLS_END | ||
|
||
#endif /* HT_FEATURE_DURATION_H */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if tutorials/ is the best place for it, as we don't have article in the documentation for this feature. You could move it to examples/duration_feature, and once we have an article for it, we can move it back to tutorials