[PATCH] record: Add support for interrupt handlers

Chris Johns chrisj at rtems.org
Wed Sep 4 06:06:49 UTC 2019


On 4/9/19 3:55 pm, Sebastian Huber wrote:
> Update #3665.
> ---
>  trace/record/record-main-lttng.cc | 86 +++++++++++++++++++++++++++++++++++++--
>  1 file changed, 82 insertions(+), 4 deletions(-)
> 
> diff --git a/trace/record/record-main-lttng.cc b/trace/record/record-main-lttng.cc
> index 55ac294..340c511 100644
> --- a/trace/record/record-main-lttng.cc
> +++ b/trace/record/record-main-lttng.cc
> @@ -96,6 +96,24 @@ struct EventSchedSwitch {
>  static const size_t kEventSchedSwitchBits =
>      sizeof(EventSchedSwitch) * BITS_PER_CHAR;
>  
> +struct EventIRQHandlerEntry {
> +  EventHeaderCompact header;
> +  int32_t irq;
> +  uint8_t name[1];
> +} __attribute__((__packed__));
> +
> +static const size_t kEventIRQHandlerEntryBits =
> +    sizeof(EventIRQHandlerEntry) * BITS_PER_CHAR;
> +
> +struct EventIRQHandlerExit {
> +  EventHeaderCompact header;
> +  int32_t irq;
> +  int32_t ret;
> +} __attribute__((__packed__));
> +
> +static const size_t kEventIRQHandlerExitBits =
> +    sizeof(EventIRQHandlerExit) * BITS_PER_CHAR;
> +
>  struct PerCPUContext {
>    FILE* event_stream;
>    uint64_t timestamp_begin;
> @@ -106,6 +124,8 @@ struct PerCPUContext {
>    uint64_t thread_ns;
>    size_t thread_name_index;
>    EventSchedSwitch sched_switch;
> +  EventIRQHandlerEntry irq_handler_entry;
> +  EventIRQHandlerExit irq_handler_exit;
>  };
>  
>  class LTTNGClient : public Client {
> @@ -116,6 +136,17 @@ class LTTNGClient : public Client {
>      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 (size_t i = 0; i < RTEMS_RECORD_CLIENT_MAXIMUM_CPU_COUNT; ++i) {
> +      PerCPUContext& pcpu = per_cpu_[i];
> +      pcpu.sched_switch.header.id = COMPACT_HEADER_ID;
> +      pcpu.sched_switch.header.event_id = 0;
> +      pcpu.irq_handler_entry.header.id = COMPACT_HEADER_ID;
> +      pcpu.irq_handler_entry.header.event_id = 1;
> +      pcpu.irq_handler_entry.name[0] = '\0';
> +      pcpu.irq_handler_exit.header.id = COMPACT_HEADER_ID;
> +      pcpu.irq_handler_exit.header.event_id = 2;
> +    }
>    }
>  
>    void Destroy() {
> @@ -158,6 +189,10 @@ class LTTNGClient : public Client {
>  
>    void WriteSchedSwitch(PerCPUContext* pcpu, const ClientItem& item);
>  
> +  void WriteIRQHandlerEntry(PerCPUContext* pcpu, const ClientItem& item);
> +
> +  void WriteIRQHandlerExit(PerCPUContext* pcpu, const ClientItem& item);
Why pass pointers and not references when ...

> +
>    void AddThreadName(PerCPUContext* pcpu, const ClientItem& item);
>  
>    void PrintItem(const ClientItem& item);
> @@ -218,8 +253,6 @@ void LTTNGClient::WriteSchedSwitch(PerCPUContext* pcpu,
>    pcpu->packet_size += kEventSchedSwitchBits;
>  
>    EventSchedSwitch& ss = pcpu->sched_switch;
> -  ss.header.id = COMPACT_HEADER_ID;
> -  ss.header.event_id = 0;
>    ss.header.ns = item.ns;
>  
>    uint32_t api_index = GetAPIIndexOfID(item.data);
> @@ -229,6 +262,26 @@ void LTTNGClient::WriteSchedSwitch(PerCPUContext* pcpu,
>    fwrite(&ss, sizeof(ss), 1, pcpu->event_stream);
>  }
>  
> +void LTTNGClient::WriteIRQHandlerEntry(PerCPUContext* pcpu, const ClientItem& item) {
> +  pcpu->content_size += kEventIRQHandlerEntryBits;
> +  pcpu->packet_size += kEventIRQHandlerEntryBits;
> +
> +  EventIRQHandlerEntry& ih = pcpu->irq_handler_entry;
> +  ih.header.ns = item.ns;
> +  ih.irq = static_cast<int32_t>(item.data);
> +  fwrite(&ih, sizeof(ih), 1, pcpu->event_stream);
> +}
> +
> +void LTTNGClient::WriteIRQHandlerExit(PerCPUContext* pcpu, const ClientItem& item) {
> +  pcpu->content_size += kEventIRQHandlerExitBits;
> +  pcpu->packet_size += kEventIRQHandlerExitBits;
> +
> +  EventIRQHandlerExit& ih = pcpu->irq_handler_exit;
> +  ih.header.ns = item.ns;
> +  ih.irq = static_cast<int32_t>(item.data);
> +  fwrite(&ih, sizeof(ih), 1, pcpu->event_stream);

https://en.cppreference.com/w/cpp/io :)

> +}
> +
>  void LTTNGClient::AddThreadName(PerCPUContext* pcpu, const ClientItem& item) {
>    if (pcpu->thread_name_index >= THREAD_NAME_SIZE) {
>      return;
> @@ -286,6 +339,12 @@ void LTTNGClient::PrintItem(const ClientItem& item) {
>        pcpu.thread_ns = item.ns;
>        pcpu.thread_name_index = 0;
>        break;
> +    case RTEMS_RECORD_INTERRUPT_ENTRY:
> +      WriteIRQHandlerEntry(&pcpu, item);
> +      break;
> +    case RTEMS_RECORD_INTERRUPT_EXIT:
> +      WriteIRQHandlerExit(&pcpu, item);

... then take the address of? I prefer to see references being used where possible.

Chris

> +      break;
>      case RTEMS_RECORD_THREAD_NAME:
>        AddThreadName(&pcpu, item);
>        break;
> @@ -371,7 +430,6 @@ static const char kMetadata[] =
>      "\tmap = clock.monotonic.value;\n"
>      "} := uint64_clock_monotonic_t;\n"
>      "\n"
> -    "\n"
>      "trace {\n"
>      "\tmajor = 1;\n"
>      "\tminor = 8;\n"
> @@ -435,7 +493,7 @@ static const char kMetadata[] =
>      "};\n"
>      "\n"
>      "event {\n"
> -    "\tname = \"sched_switch\";\n"
> +    "\tname = sched_switch;\n"
>      "\tid = 0;\n"
>      "\tstream_id = 0;\n"
>      "\tfields := struct {\n"
> @@ -447,6 +505,26 @@ static const char kMetadata[] =
>      "\t\tint32_t _next_tid;\n"
>      "\t\tint32_t _next_prio;\n"
>      "\t};\n"
> +    "};\n"
> +    "\n"
> +    "event {\n"
> +    "\tname = irq_handler_entry;\n"
> +    "\tid = 1;\n"
> +    "\tstream_id = 0;\n"
> +    "\tfields := struct {\n"
> +    "\t\tint32_t _irq;\n"
> +    "\t\tstring _name;\n"
> +    "\t};\n"
> +    "};\n"
> +    "\n"
> +    "event {\n"
> +    "\tname = irq_handler_exit;\n"
> +    "\tid = 2;\n"
> +    "\tstream_id = 0;\n"
> +    "\tfields := struct {\n"
> +    "\t\tint32_t _irq;\n"
> +    "\t\tint32_t _ret;\n"
> +    "\t};\n"
>      "};\n";
>  
>  static void GenerateMetadata() {
> 



More information about the devel mailing list