Commit c13c0a3f authored by Pedro Gonnet's avatar Pedro Gonnet
Browse files

keep a separate log buffer per thread id. this avoids having to protect...

keep a separate log buffer per thread id. this avoids having to protect against concurrent access to the logs.
parent b32c270b
...@@ -45,33 +45,28 @@ ...@@ -45,33 +45,28 @@
*/ */
void threadpool_log(struct threadpool *tp, int tid, size_t chunk_size, void threadpool_log(struct threadpool *tp, int tid, size_t chunk_size,
ticks tic, ticks toc) { ticks tic, ticks toc) {
struct mapper_log *log = &tp->logs[tid];
/* Only one cell logs at a time. */
pthread_mutex_lock(&tp->log_mutex);
/* Check if we need to re-allocate the log buffer. */ /* Check if we need to re-allocate the log buffer. */
if (tp->log_count == tp->log_size) { if (log->count == log->size) {
tp->log_size *= 2; log->size *= 2;
struct mapper_log_entry *new_log; struct mapper_log_entry *new_log;
if ((new_log = (struct mapper_log_entry *)malloc( if ((new_log = (struct mapper_log_entry *)malloc(
sizeof(struct mapper_log_entry) * tp->log_size)) == NULL) sizeof(struct mapper_log_entry) * log->size)) == NULL)
error("Failed to re-allocate mapper log."); error("Failed to re-allocate mapper log.");
memcpy(new_log, tp->log, sizeof(struct mapper_log_entry) * tp->log_count); memcpy(new_log, log->log, sizeof(struct mapper_log_entry) * log->count);
free(tp->log); free(log->log);
tp->log = new_log; log->log = new_log;
} }
/* Store the new entry. */ /* Store the new entry. */
struct mapper_log_entry *entry = &tp->log[tp->log_count]; struct mapper_log_entry *entry = &log->log[log->count];
entry->tid = tid; entry->tid = tid;
entry->chunk_size = chunk_size; entry->chunk_size = chunk_size;
entry->tic = tic; entry->tic = tic;
entry->toc = toc; entry->toc = toc;
entry->map_function = tp->map_function; entry->map_function = tp->map_function;
tp->log_count++; log->count++;
/* Release the logging mutex. */
pthread_mutex_unlock(&tp->log_mutex);
} }
void threadpool_dump_log(struct threadpool *tp, const char *filename, void threadpool_dump_log(struct threadpool *tp, const char *filename,
...@@ -96,34 +91,39 @@ void threadpool_dump_log(struct threadpool *tp, const char *filename, ...@@ -96,34 +91,39 @@ void threadpool_dump_log(struct threadpool *tp, const char *filename,
fprintf(fd, "# {'num_threads': %i, 'cpufreq': %lli}\n", tp->num_threads, fprintf(fd, "# {'num_threads': %i, 'cpufreq': %lli}\n", tp->num_threads,
clocks_get_cpufreq()); clocks_get_cpufreq());
/* Loop over the log entries and dump them. */ /* Loop over the per-tid logs and dump them. */
for (int i = 0; i < tp->log_count; i++) { for (int k = 0; k < tp->num_threads; k++) {
struct mapper_log *log = &tp->logs[k];
struct mapper_log_entry *entry = &tp->log[i];
/* Loop over the log entries and dump them. */
/* Look for the function pointer in the buffer. */ for (int i = 0; i < log->count; i++) {
int nid = 0;
while (nid < max_names && names[nid].map_function != entry->map_function) struct mapper_log_entry *entry = &log->log[i];
nid++;
/* Look for the function pointer in the buffer. */
/* If the name was not found, make a new entry. */ int nid = 0;
if (nid == max_names) { while (nid < max_names && names[nid].map_function != entry->map_function)
for (int j = 1; j < max_names; j++) names[j - 1] = names[j]; nid++;
names[0].map_function = entry->map_function;
Dl_info dl_info; /* If the name was not found, make a new entry. */
dladdr(entry->map_function, &dl_info); if (nid == max_names) {
names[0].name = dl_info.dli_sname; for (int j = 1; j < max_names; j++) names[j - 1] = names[j];
nid = 0; names[0].map_function = entry->map_function;
Dl_info dl_info;
dladdr(entry->map_function, &dl_info);
names[0].name = dl_info.dli_sname;
nid = 0;
}
/* Log a line to the file. */
fprintf(fd, "%s %i %i %lli %lli\n", names[nid].name, entry->tid,
entry->chunk_size, entry->tic, entry->toc);
} }
/* Log a line to the file. */ /* Clear the log if requested. */
fprintf(fd, "%s %i %i %lli %lli\n", names[nid].name, entry->tid, if (reset) log->count = 0;
entry->chunk_size, entry->tic, entry->toc);
} }
/* Clear the log if requested. */
if (reset) tp->log_count = 0;
/* Close the file. */ /* Close the file. */
fclose(fd); fclose(fd);
} }
...@@ -214,13 +214,16 @@ void threadpool_init(struct threadpool *tp, int num_threads) { ...@@ -214,13 +214,16 @@ void threadpool_init(struct threadpool *tp, int num_threads) {
tp->map_function = NULL; tp->map_function = NULL;
#ifdef SWIFT_DEBUG_THREADPOOL #ifdef SWIFT_DEBUG_THREADPOOL
tp->log_size = threadpool_log_initial_size; if ((tp->logs = (struct mapper_log *)malloc(sizeof(struct mapper_log) *
tp->log_count = 0; num_threads)) == NULL)
if (pthread_mutex_init(&tp->log_mutex, NULL) != 0) error("Failed to allocate mapper logs.");
error("Failed to initialize log mutex."); for (int k = 0; k < num_threads; k++) {
if ((tp->log = (struct mapper_log_entry *)malloc( tp->logs[k].size = threadpool_log_initial_size;
sizeof(struct mapper_log_entry) * tp->log_size)) == NULL) tp->logs[k].count = 0;
error("Failed to allocate mapper log."); if ((tp->logs[k].log = (struct mapper_log_entry *)malloc(
sizeof(struct mapper_log_entry) * tp->logs[k].size)) == NULL)
error("Failed to allocate mapper log.");
}
#endif #endif
/* Allocate the threads. */ /* Allocate the threads. */
...@@ -300,7 +303,9 @@ void threadpool_map(struct threadpool *tp, threadpool_map_function map_function, ...@@ -300,7 +303,9 @@ void threadpool_map(struct threadpool *tp, threadpool_map_function map_function,
* @brief Re-sets the log for this #threadpool. * @brief Re-sets the log for this #threadpool.
*/ */
#ifdef SWIFT_DEBUG_THREADPOOL #ifdef SWIFT_DEBUG_THREADPOOL
void threadpool_reset_log(struct threadpool *tp) { tp->log_count = 0; } void threadpool_reset_log(struct threadpool *tp) {
for (int k = 0; k < tp->num_threads; k++) tp->logs[k].count = 0;
}
#endif #endif
/** /**
...@@ -309,6 +314,9 @@ void threadpool_reset_log(struct threadpool *tp) { tp->log_count = 0; } ...@@ -309,6 +314,9 @@ void threadpool_reset_log(struct threadpool *tp) { tp->log_count = 0; }
void threadpool_clean(struct threadpool *tp) { void threadpool_clean(struct threadpool *tp) {
free(tp->threads); free(tp->threads);
#ifdef SWIFT_DEBUG_THREADPOOL #ifdef SWIFT_DEBUG_THREADPOOL
free(tp->log); for (int k = 0; k < tp->num_threads; k++) {
free(tp->logs[k].log);
}
free(tp->logs);
#endif #endif
} }
...@@ -52,6 +52,17 @@ struct mapper_log_entry { ...@@ -52,6 +52,17 @@ struct mapper_log_entry {
ticks tic, toc; ticks tic, toc;
}; };
struct mapper_log {
/* Log of threadpool mapper calls. */
struct mapper_log_entry *log;
/* Size of the allocated log. */
int size;
/* Number of entries in the log. */
int count;
};
/* Data of a threadpool. */ /* Data of a threadpool. */
struct threadpool { struct threadpool {
...@@ -75,17 +86,7 @@ struct threadpool { ...@@ -75,17 +86,7 @@ struct threadpool {
volatile int num_threads_waiting, num_threads_running; volatile int num_threads_waiting, num_threads_running;
#ifdef SWIFT_DEBUG_THREADPOOL #ifdef SWIFT_DEBUG_THREADPOOL
/* Log of threadpool mapper calls. */ struct mapper_log *logs;
struct mapper_log_entry *log;
/* Size of the allocated log. */
int log_size;
/* Number of entries in the log. */
int log_count;
/* Mutex for log access/reallocation. */
pthread_mutex_t log_mutex;
#endif #endif
}; };
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment