Hacker News new | ask | show | jobs
by senozhatsky 455 days ago
That's sort of how Linux kernel trace-events are implemented [1]. E.g.

    DECLARE_EVENT_CLASS(sched_wakeup_template,
    
     TP_PROTO(struct task_struct *p),
    
     TP_ARGS(__perf_task(p)),
    
     TP_STRUCT__entry(
          __array( char, comm, TASK_COMM_LEN )
          __field( pid_t, pid   )
          __field( int, prio   )
          __field( int, target_cpu  )
     ),
    
     TP_fast_assign(
          memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
          __entry->pid  = p->pid;
          __entry->prio  = p->prio; /* XXX SCHED_DEADLINE */
          __entry->target_cpu = task_cpu(p);
     ),
    
     TP_printk("comm=%s pid=%d prio=%d target_cpu=%03d",
          __entry->comm, __entry->pid, __entry->prio,
          __entry->target_cpu)
    );
[1] https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds...
1 comments

At first I though this was just normal macros, not X-macros. But you're right, and at first I just wasn't understanding it. In linux/include/trace/stages/stage1_struct_define.h, linux/include/trace/stages/stage2_data_offsets.h, etc., we see the different definitions of __field and __array.

Also, in linux/include/linux/genl_magic_struct.h we see multiple different definitions of __field and __array, each followed by #include GENL_MAGIC_INCLUDE_FILE, and I had no idea you could even source the name of a file to #include from a preprocessor macro! But that's a different __array with a different number of arguments.