void utime_to_timeval(int64_t v, struct timeval *tv) { tv->tv_sec = timestamp_seconds(v); tv->tv_usec = timestamp_useconds(v); }
void utime_to_timespec(int64_t v, struct timespec *ts) { ts->tv_sec = timestamp_seconds(v); ts->tv_nsec = timestamp_useconds(v)*1000; }
static void* write_thread(void *user_data) { logger_t *logger = (logger_t*) user_data; GTimeVal start_time; g_get_current_time(&start_time); int num_splits = 0; int64_t next_split_sec = start_time.tv_sec + logger->auto_split_hours * SECONDS_PER_HOUR; while(1) { void *msg = g_async_queue_pop(logger->write_queue); // Is it time to start a new logfile? int split_log = 0; if(logger->auto_split_hours) { GTimeVal now; g_get_current_time(&now); split_log = (now.tv_sec > next_split_sec); } else if(logger->auto_split_mb) { double logsize_mb = (double)logger->logsize / (1 << 20); split_log = (logsize_mb > logger->auto_split_mb); } if(_reset_logfile) { split_log = 1; _reset_logfile = 0; } if(split_log) { // Yes. open up a new log file lcm_eventlog_destroy(logger->log); if(0 != open_logfile(logger)) exit(1); num_splits++; int64_t log_duration_sec = logger->auto_split_hours * SECONDS_PER_HOUR; next_split_sec = start_time.tv_sec + (num_splits + 1) * log_duration_sec; logger->logsize = 0; logger->last_report_logsize = 0; } // Should the write thread exit? g_mutex_lock(logger->mutex); if(logger->write_thread_exit_flag) { g_mutex_unlock(logger->mutex); return NULL; } // nope. write the event to disk lcm_eventlog_event_t *le = (lcm_eventlog_event_t*) msg; int64_t sz = sizeof(lcm_eventlog_event_t) + le->channellen + 1 + le->datalen; logger->write_queue_size -= sz; g_mutex_unlock(logger->mutex); if(0 != lcm_eventlog_write_event(logger->log, le)) { static int64_t last_spew_utime = 0; char *reason = strdup(strerror(errno)); int64_t now = timestamp_now(); if(now - last_spew_utime > 500000) { fprintf(stderr, "lcm_eventlog_write_event: %s\n", reason); last_spew_utime = now; } free(reason); free(le); if(errno == ENOSPC) { exit(1); } else { continue; } } if (logger->fflush_interval_ms >= 0 && (le->timestamp - logger->last_fflush_time) > logger->fflush_interval_ms*1000) { fflush(logger->log->f); logger->last_fflush_time = le->timestamp; } // bookkeeping, cleanup int64_t offset_utime = le->timestamp - logger->time0; logger->nevents++; logger->events_since_last_report ++; logger->logsize += 4 + 8 + 8 + 4 + le->channellen + 4 + le->datalen; free(le); if (offset_utime - logger->last_report_time > 1000000) { double dt = (offset_utime - logger->last_report_time)/1000000.0; double tps = logger->events_since_last_report / dt; double kbps = (logger->logsize - logger->last_report_logsize) / dt / 1024.0; printf("Summary: %s ti:%4"PRIi64"sec Events: %-9"PRIi64" ( %4"PRIi64" MB ) TPS: %8.2f KB/s: %8.2f\n", logger->fname, timestamp_seconds(offset_utime), logger->nevents, logger->logsize/1048576, tps, kbps); logger->last_report_time = offset_utime; logger->events_since_last_report = 0; logger->last_report_logsize = logger->logsize; } } }