summaryrefslogtreecommitdiffstats
path: root/trace
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2019-08-30 06:30:28 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2019-09-03 14:59:33 +0200
commita124bdb8513615a4be3c9a2cd1e46ee3fd93c7d9 (patch)
tree69f3ca824fa5e98aa7a0e013969bb5a5201c146c /trace
parentrecord: Convert to C++ (diff)
downloadrtems-tools-a124bdb8513615a4be3c9a2cd1e46ee3fd93c7d9.tar.bz2
record: Add Client base class
Update #3665.
Diffstat (limited to 'trace')
-rw-r--r--trace/record/client.h70
-rw-r--r--trace/record/record-client-base.cc90
-rw-r--r--trace/record/record-main-lttng.cc334
-rw-r--r--trace/wscript4
4 files changed, 309 insertions, 189 deletions
diff --git a/trace/record/client.h b/trace/record/client.h
new file mode 100644
index 0000000..2d55052
--- /dev/null
+++ b/trace/record/client.h
@@ -0,0 +1,70 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2018, 2019 embedded brains GmbH
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RTEMS_TOOLS_TRACE_RECORD_CLIENT_H_
+#define RTEMS_TOOLS_TRACE_RECORD_CLIENT_H_
+
+#include <rtems/recordclient.h>
+#include <rtems/recorddata.h>
+
+#include <sys/types.h>
+
+#include <csignal>
+
+class Client {
+ public:
+ Client() = default;
+
+ Client(const Client&) = delete;
+
+ Client& operator=(const Client&) = delete;
+
+ void Open(const char* file);
+
+ void Connect(const char* host, uint16_t port);
+
+ void Run();
+
+ void RequestStop() { stop_ = 1; }
+
+ void Destroy();
+
+ protected:
+ void Initialize(rtems_record_client_handler handler) {
+ rtems_record_client_init(&base_, handler, this);
+ }
+
+ size_t data_size() const { return base_.data_size; };
+
+ private:
+ rtems_record_client_context base_;
+ int fd_ = -1;
+ ssize_t (*reader_)(int fd, void* buf, size_t n) = nullptr;
+ sig_atomic_t stop_ = 0;
+};
+
+#endif // RTEMS_TOOLS_TRACE_RECORD_CLIENT_H_
diff --git a/trace/record/record-client-base.cc b/trace/record/record-client-base.cc
new file mode 100644
index 0000000..e56608c
--- /dev/null
+++ b/trace/record/record-client-base.cc
@@ -0,0 +1,90 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2018, 2019 embedded brains GmbH
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "client.h"
+
+#include <arpa/inet.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <cstring>
+
+static ssize_t ReadFile(int fd, void* buf, size_t n) {
+ return read(fd, buf, n);
+}
+
+static ssize_t ReadSocket(int fd, void* buf, size_t n) {
+ return recv(fd, buf, n, 0);
+}
+
+void Client::Open(const char* file) {
+ assert(fd_ == -1);
+ fd_ = open(file, O_RDONLY);
+ assert(fd_ >= 0);
+ reader_ = ReadFile;
+}
+
+void Client::Connect(const char* host, uint16_t port) {
+ assert(fd_ == -1);
+ fd_ = socket(PF_INET, SOCK_STREAM, 0);
+ assert(fd_ >= 0);
+
+ struct sockaddr_in in_addr;
+ memset(&in_addr, 0, sizeof(in_addr));
+ in_addr.sin_family = AF_INET;
+ in_addr.sin_port = htons(port);
+ in_addr.sin_addr.s_addr = inet_addr(host);
+
+ int rv = connect(fd_, (struct sockaddr*)&in_addr, sizeof(in_addr));
+ assert(rv == 0);
+
+ reader_ = ReadSocket;
+}
+
+void Client::Run() {
+ while (stop_ == 0) {
+ int buf[8192];
+ ssize_t n = (*reader_)(fd_, buf, sizeof(buf));
+
+ if (n > 0) {
+ rtems_record_client_run(&base_, buf, static_cast<size_t>(n));
+ } else {
+ break;
+ }
+ }
+}
+
+void Client::Destroy() {
+ int rv = close(fd_);
+ assert(rv == 0);
+
+ rtems_record_client_destroy(&base_);
+}
diff --git a/trace/record/record-main-lttng.cc b/trace/record/record-main-lttng.cc
index 9e10c5e..51d4f0e 100644
--- a/trace/record/record-main-lttng.cc
+++ b/trace/record/record-main-lttng.cc
@@ -26,20 +26,13 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <rtems/recordclient.h>
-#include <rtems/recorddata.h>
+#include "client.h"
-#include <arpa/inet.h>
#include <assert.h>
-#include <fcntl.h>
#include <getopt.h>
#include <inttypes.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <unistd.h>
+#include <cstring>
#include <iostream>
#define CTF_MAGIC 0xC1FC1FC1
@@ -82,6 +75,8 @@ struct PacketContext {
uint32_t cpu_id;
} __attribute__((__packed__));
+static const size_t kPacketContextBits = sizeof(PacketContext) * BITS_PER_CHAR;
+
struct EventHeaderCompact {
uint8_t id;
uint32_t event_id;
@@ -99,6 +94,9 @@ struct EventSchedSwitch {
int32_t next_prio;
} __attribute__((__packed__));
+static const size_t kEventSchedSwitchBits =
+ sizeof(EventSchedSwitch) * BITS_PER_CHAR;
+
struct PerCPUContext {
FILE* event_stream;
uint64_t timestamp_begin;
@@ -111,8 +109,21 @@ struct PerCPUContext {
EventSchedSwitch sched_switch;
};
-struct LTTNGClient {
- rtems_record_client_context base;
+class LTTNGClient : public Client {
+ public:
+ LTTNGClient() {
+ Initialize(LTTNGClient::HandlerCaller);
+
+ memset(&pkt_ctx_, 0, sizeof(pkt_ctx_));
+ memcpy(pkt_ctx_.header.uuid, kUUID, sizeof(pkt_ctx_.header.uuid));
+ pkt_ctx_.header.ctf_magic = CTF_MAGIC;
+ }
+
+ void OpenStreamFiles();
+
+ void CloseStreamFiles();
+
+ private:
PerCPUContext per_cpu_[RTEMS_RECORD_CLIENT_MAXIMUM_CPU_COUNT];
/*
@@ -122,32 +133,33 @@ struct LTTNGClient {
* POSIX API.
*/
uint8_t thread_names_[THREAD_API_COUNT][THREAD_ID_COUNT][THREAD_NAME_SIZE];
-};
-static int ConnectClient(const char* host,
- uint16_t port,
- const char* input_file,
- bool input_file_flag) {
- struct sockaddr_in in_addr;
- int fd;
- int rv;
-
- fd = (input_file_flag) ? open(input_file, O_RDONLY)
- : socket(PF_INET, SOCK_STREAM, 0);
- assert(fd >= 0);
-
- memset(&in_addr, 0, sizeof(in_addr));
- in_addr.sin_family = AF_INET;
- in_addr.sin_port = htons(port);
- in_addr.sin_addr.s_addr = inet_addr(host);
-
- if (!input_file_flag) {
- rv = connect(fd, (struct sockaddr*)&in_addr, sizeof(in_addr));
- assert(rv == 0);
+ PacketContext pkt_ctx_;
+
+ static rtems_record_client_status HandlerCaller(uint64_t bt,
+ uint32_t cpu,
+ rtems_record_event event,
+ uint64_t data,
+ void* arg) {
+ LTTNGClient& self = *static_cast<LTTNGClient*>(arg);
+ return self.Handler(bt, cpu, event, data);
}
- return fd;
-}
+ rtems_record_client_status Handler(uint64_t bt,
+ uint32_t cpu,
+ rtems_record_event event,
+ uint64_t data);
+
+ void CopyThreadName(const ClientItem& item,
+ size_t api_index,
+ uint8_t* dst) const;
+
+ void WriteSchedSwitch(PerCPUContext* pcpu, const ClientItem& item);
+
+ void AddThreadName(PerCPUContext* pcpu, const ClientItem& item);
+
+ void PrintItem(const ClientItem& item);
+};
static uint32_t GetAPIIndexOfID(uint32_t id) {
return ((id >> 24) & 0x7) - 1;
@@ -161,14 +173,13 @@ static bool IsIdleTaskByAPIIndex(uint32_t api_index) {
return api_index == 0;
}
-static void CopyThreadName(const LTTNGClient* ctx,
- const ClientItem* item,
- size_t api_index,
- uint8_t* dst) {
+void LTTNGClient::CopyThreadName(const ClientItem& item,
+ size_t api_index,
+ uint8_t* dst) const {
const uint8_t* name;
if (api_index < THREAD_API_COUNT) {
- name = ctx->thread_names_[api_index][GetObjIndexOfID(item->data)];
+ name = thread_names_[api_index][GetObjIndexOfID(item.data)];
} else {
name = kEmptyThreadName;
}
@@ -181,115 +192,96 @@ static void CopyThreadName(const LTTNGClient* ctx,
* RTEMS, the idle threads can move around, so mimic this Linux behaviour.
*/
snprintf(reinterpret_cast<char*>(dst) + 4, THREAD_NAME_SIZE - 4,
- "/%" PRIu32, item->cpu);
+ "/%" PRIu32, item.cpu);
}
}
-static void WriteSchedSwitch(LTTNGClient* ctx,
- PerCPUContext* pcpu,
- const ClientItem* item) {
- size_t se_size;
- EventSchedSwitch* se;
- uint32_t api_index;
-
- se_size = sizeof(*se) * BITS_PER_CHAR;
- pcpu->content_size += se_size;
- pcpu->packet_size += se_size;
+void LTTNGClient::WriteSchedSwitch(PerCPUContext* pcpu,
+ const ClientItem& item) {
+ pcpu->content_size += kEventSchedSwitchBits;
+ pcpu->packet_size += kEventSchedSwitchBits;
- api_index = GetAPIIndexOfID(item->data);
- se = &pcpu->sched_switch;
+ EventSchedSwitch& ss = pcpu->sched_switch;
+ ss.header.id = COMPACT_HEADER_ID;
+ ss.header.event_id = 0;
+ ss.header.ns = item.ns;
- se->header.id = COMPACT_HEADER_ID;
- se->header.event_id = 0;
- se->header.ns = item->ns;
- se->next_tid = IsIdleTaskByAPIIndex(api_index) ? 0 : item->data;
+ uint32_t api_index = GetAPIIndexOfID(item.data);
+ ss.next_tid = IsIdleTaskByAPIIndex(api_index) ? 0 : item.data;
- CopyThreadName(ctx, item, api_index, se->next_comm);
- fwrite(se, sizeof(*se), 1, pcpu->event_stream);
+ CopyThreadName(item, api_index, ss.next_comm);
+ fwrite(&ss, sizeof(ss), 1, pcpu->event_stream);
}
-static void AddThreadName(LTTNGClient* ctx,
- PerCPUContext* pcpu,
- const ClientItem* item) {
- uint64_t name;
- uint32_t api_index;
- uint32_t obj_index;
- size_t i;
-
+void LTTNGClient::AddThreadName(PerCPUContext* pcpu, const ClientItem& item) {
if (pcpu->thread_name_index >= THREAD_NAME_SIZE) {
return;
}
- api_index = GetAPIIndexOfID(pcpu->thread_id);
-
+ uint32_t api_index = GetAPIIndexOfID(pcpu->thread_id);
if (api_index >= THREAD_API_COUNT) {
return;
}
- obj_index = GetObjIndexOfID(pcpu->thread_id);
- name = item->data;
-
- for (i = pcpu->thread_name_index;
- i < pcpu->thread_name_index + ctx->base.data_size; ++i) {
- ctx->thread_names_[api_index][obj_index][i] = static_cast<uint8_t>(name);
+ uint32_t obj_index = GetObjIndexOfID(pcpu->thread_id);
+ uint64_t name = item.data;
+ size_t i;
+ for (i = pcpu->thread_name_index; i < pcpu->thread_name_index + data_size();
+ ++i) {
+ thread_names_[api_index][obj_index][i] = static_cast<uint8_t>(name);
name >>= BITS_PER_CHAR;
}
pcpu->thread_name_index = i;
}
-static void PrintItem(LTTNGClient* ctx, const ClientItem* item) {
- PerCPUContext* pcpu;
- EventSchedSwitch* se;
- uint32_t api_index;
-
- pcpu = &ctx->per_cpu_[item->cpu];
- se = &pcpu->sched_switch;
-
- if (pcpu->timestamp_begin == 0) {
- pcpu->timestamp_begin = item->ns;
+void LTTNGClient::PrintItem(const ClientItem& item) {
+ PerCPUContext& pcpu = per_cpu_[item.cpu];
+ if (pcpu.timestamp_begin == 0) {
+ pcpu.timestamp_begin = item.ns;
}
- pcpu->timestamp_end = item->ns;
+ pcpu.timestamp_end = item.ns;
- switch (item->event) {
- case RTEMS_RECORD_THREAD_SWITCH_OUT:
- api_index = GetAPIIndexOfID(item->data);
- se->header.ns = item->ns;
+ EventSchedSwitch& ss = pcpu.sched_switch;
+ switch (item.event) {
+ case RTEMS_RECORD_THREAD_SWITCH_OUT: {
+ uint32_t api_index = GetAPIIndexOfID(item.data);
+ ss.header.ns = item.ns;
if (IsIdleTaskByAPIIndex(api_index)) {
- se->prev_tid = 0;
- se->prev_state = TASK_IDLE;
+ ss.prev_tid = 0;
+ ss.prev_state = TASK_IDLE;
} else {
- se->prev_tid = item->data;
- se->prev_state = TASK_RUNNING;
+ ss.prev_tid = item.data;
+ ss.prev_state = TASK_RUNNING;
}
- CopyThreadName(ctx, item, api_index, se->prev_comm);
+ CopyThreadName(item, api_index, ss.prev_comm);
break;
+ }
case RTEMS_RECORD_THREAD_SWITCH_IN:
- if (item->ns == se->header.ns) {
- WriteSchedSwitch(ctx, pcpu, item);
+ if (item.ns == ss.header.ns) {
+ WriteSchedSwitch(&pcpu, item);
}
break;
case RTEMS_RECORD_THREAD_ID:
- pcpu->thread_id = item->data;
- pcpu->thread_ns = item->ns;
- pcpu->thread_name_index = 0;
+ pcpu.thread_id = item.data;
+ pcpu.thread_ns = item.ns;
+ pcpu.thread_name_index = 0;
break;
case RTEMS_RECORD_THREAD_NAME:
- AddThreadName(ctx, pcpu, item);
+ AddThreadName(&pcpu, item);
break;
default:
break;
}
}
-static rtems_record_client_status Handler(uint64_t bt,
- uint32_t cpu,
- rtems_record_event event,
- uint64_t data,
- void* arg) {
+rtems_record_client_status LTTNGClient::Handler(uint64_t bt,
+ uint32_t cpu,
+ rtems_record_event event,
+ uint64_t data) {
ClientItem item;
item.ns = rtems_record_client_bintime_to_nanoseconds(bt);
@@ -297,11 +289,39 @@ static rtems_record_client_status Handler(uint64_t bt,
item.event = event;
item.data = data;
- PrintItem(static_cast<LTTNGClient*>(arg), &item);
+ PrintItem(item);
return RTEMS_RECORD_CLIENT_SUCCESS;
}
+void LTTNGClient::OpenStreamFiles() {
+ for (size_t i = 0; i < RTEMS_RECORD_CLIENT_MAXIMUM_CPU_COUNT; ++i) {
+ char filename[256];
+ snprintf(filename, sizeof(filename), "event_%zu", i);
+ FILE* f = fopen(filename, "wb");
+ assert(f != NULL);
+ per_cpu_[i].event_stream = f;
+ fwrite(&pkt_ctx_, sizeof(pkt_ctx_), 1, f);
+ }
+}
+
+void LTTNGClient::CloseStreamFiles() {
+ for (size_t i = 0; i < RTEMS_RECORD_CLIENT_MAXIMUM_CPU_COUNT; ++i) {
+ PerCPUContext* pcpu = &per_cpu_[i];
+ fseek(pcpu->event_stream, 0, SEEK_SET);
+
+ pkt_ctx_.header.stream_instance_id = i;
+ pkt_ctx_.timestamp_begin = pcpu->timestamp_begin;
+ pkt_ctx_.timestamp_end = pcpu->timestamp_end;
+ pkt_ctx_.content_size = pcpu->content_size + kPacketContextBits;
+ pkt_ctx_.packet_size = pcpu->packet_size + kPacketContextBits;
+ pkt_ctx_.cpu_id = i;
+
+ fwrite(&pkt_ctx_, sizeof(pkt_ctx_), 1, pcpu->event_stream);
+ fclose(pcpu->event_stream);
+ }
+}
+
static const char kMetadata[] =
"/* CTF 1.8 */\n"
"\n"
@@ -411,6 +431,13 @@ static void GenerateMetadata() {
fclose(file);
}
+static LTTNGClient client;
+
+static void SignalHandler(int s) {
+ client.RequestStop();
+ signal(s, SIG_DFL);
+}
+
static const struct option kLongOpts[] = {{"help", 0, NULL, 'h'},
{"host", 1, NULL, 'H'},
{"port", 1, NULL, 'p'},
@@ -434,28 +461,11 @@ static void Usage(char** argv) {
}
int main(int argc, char** argv) {
- LTTNGClient ctx;
- PacketContext pkt_ctx;
- size_t pkt_ctx_size;
- const char* host;
- uint16_t port;
- const char* input_file;
- bool input_file_flag;
- bool input_TCP_host;
- bool input_TCP_port;
- int fd;
- int rv;
+ const char* host = "127.0.0.1";
+ uint16_t port = 1234;
+ const char* file = nullptr;
int opt;
int longindex;
- size_t i;
- char filename[256];
-
- host = "127.0.0.1";
- port = 1234;
- input_file = "raw_data";
- input_file_flag = false;
- input_TCP_host = false;
- input_TCP_port = false;
while ((opt = getopt_long(argc, argv, "hH:p:i:", &kLongOpts[0],
&longindex)) != -1) {
@@ -465,83 +475,31 @@ int main(int argc, char** argv) {
return 0;
case 'H':
host = optarg;
- input_TCP_host = true;
break;
case 'p':
port = (uint16_t)strtoul(optarg, NULL, 10);
- input_TCP_port = true;
break;
case 'i':
- input_file = optarg;
- assert(input_file != NULL);
- input_file_flag = true;
+ file = optarg;
break;
default:
return 1;
}
}
- if (input_file_flag && (input_TCP_host || input_TCP_port)) {
- printf("There should be one input medium\n");
- exit(EXIT_SUCCESS);
- }
-
- memset(&ctx, 0, sizeof(ctx));
-
GenerateMetadata();
+ client.OpenStreamFiles();
- memset(&pkt_ctx, 0, sizeof(pkt_ctx));
- memcpy(pkt_ctx.header.uuid, kUUID, sizeof(pkt_ctx.header.uuid));
- pkt_ctx.header.ctf_magic = CTF_MAGIC;
-
- for (i = 0; i < RTEMS_RECORD_CLIENT_MAXIMUM_CPU_COUNT; ++i) {
- FILE* f;
-
- snprintf(filename, sizeof(filename), "event_%zu", i);
- f = fopen(filename, "wb");
- assert(f != NULL);
- ctx.per_cpu_[i].event_stream = f;
- fwrite(&pkt_ctx, sizeof(pkt_ctx), 1, f);
- }
-
- fd = ConnectClient(host, port, input_file, input_file_flag);
- rtems_record_client_init(&ctx.base, Handler, &ctx);
-
- while (true) {
- int buf[8192];
- ssize_t n;
-
- n = (input_file_flag) ? read(fd, buf, sizeof(buf))
- : recv(fd, buf, sizeof(buf), 0);
- if (n > 0) {
- rtems_record_client_run(&ctx.base, buf, (size_t)n);
- } else {
- break;
- }
- }
-
- rtems_record_client_destroy(&ctx.base);
- pkt_ctx_size = sizeof(pkt_ctx) * BITS_PER_CHAR;
-
- for (i = 0; i < RTEMS_RECORD_CLIENT_MAXIMUM_CPU_COUNT; ++i) {
- PerCPUContext* pcpu;
-
- pcpu = &ctx.per_cpu_[i];
- fseek(pcpu->event_stream, 0, SEEK_SET);
-
- pkt_ctx.header.stream_instance_id = i;
- pkt_ctx.timestamp_begin = pcpu->timestamp_begin;
- pkt_ctx.timestamp_end = pcpu->timestamp_end;
- pkt_ctx.content_size = pcpu->content_size + pkt_ctx_size;
- pkt_ctx.packet_size = pcpu->packet_size + pkt_ctx_size;
- pkt_ctx.cpu_id = i;
-
- fwrite(&pkt_ctx, sizeof(pkt_ctx), 1, pcpu->event_stream);
- fclose(pcpu->event_stream);
+ if (file != nullptr) {
+ client.Open(file);
+ } else {
+ client.Connect(host, port);
}
- rv = close(fd);
- assert(rv == 0);
+ signal(SIGINT, SignalHandler);
+ client.Run();
+ client.Destroy();
+ client.CloseStreamFiles();
return 0;
}
diff --git a/trace/wscript b/trace/wscript
index bc28e85..d2b5625 100644
--- a/trace/wscript
+++ b/trace/wscript
@@ -59,7 +59,9 @@ def build(bld):
# Build rtems-record-lttng
#
bld.program(target = 'rtems-record-lttng',
- source = ['record/record-client.c', 'record/record-main-lttng.cc'],
+ source = ['record/record-client.c',
+ 'record/record-client-base.cc',
+ 'record/record-main-lttng.cc'],
includes = ['record'],
defines = defines,
cflags = conf['cflags'] + conf['warningflags'],