Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No man page for xo_emit_field() #77

Closed
rwatson opened this issue Dec 30, 2020 · 6 comments
Closed

No man page for xo_emit_field() #77

rwatson opened this issue Dec 30, 2020 · 6 comments
Assignees
Labels

Comments

@rwatson
Copy link

rwatson commented Dec 30, 2020

libxo seems to have convenient APIs to allow various compile-time field names to be used. However, sometimes in life, I have a set of dynamically determined field names, and it wasn't clear to me that the API made that convenient. Possibly I've suffered a documentation spelunking fail, in which case please just point me in the right direction and close. But here is an example:

#include <libxo/xo.h>

/*
 * Sometimes with libxo, I have a set of field names only known at run time.
 * For example, if a program self instruments using hardware performance
 * counters, and because of a limited number of hardware counter registers,
 * the user has to select up to 6 at a time, but we need to support hundreds
 * of potential values.  In this example code, I want to allow the field name
 * to be a string generated at run time .. but I wasn't sure how to do that in 
 * a way that was elegant with libxo.
 */
void
what_I_wanted_to_do(const char *variable, const char *value)
{

        xo_open_container("wanted_to_do");
        xo_emit("{:%s/%s}", variable, value);
        xo_close_container("wanted_to_do");
}

void
what_I_did(const char *variable, const char *value)
{
        char buffer[128];

        snprintf(buffer, sizeof(buffer), "{:%s/%%s}", variable);
        xo_open_container("did");
        xo_emit(buffer, value);
        xo_close_container("did");
}

int
main(int argc, char *argv[])
{

        xo_set_style(NULL, XO_STYLE_JSON);
        xo_set_flags(NULL, XOF_PRETTY);
        what_I_wanted_to_do("L1D_CACHE_ACCESS", "10");
        what_I_did("L1D_CACHE_ACCESS", "10");
        xo_finish();
        return(0);
}

Which outputs:

{
  "wanted_to_do": {
    "%s": "L1D_CACHE_ACCESS"
  },
  "did": {
    "L1D_CACHE_ACCESS": "10"
  }
}

In this scenario, the A72 core we're using has dozens of performance counter events that can be configured, but due to an architectural limit, only 6 can be used at a time. The strings for those registers are already defined in other headers, and I definitely don't want to retype them or do anything to replicate that. Instead, I want to have the user pass the names via the command line, validate them using the PMC library, and then use them as field names with libxo.

Pointers most welcome!

@rwatson
Copy link
Author

rwatson commented Dec 30, 2020

xo_emit_field() pointed out to me by @allanjude -- apparently it does exactly what I need for exactly this reason. Unfortunately, I failed to find it when spelunking. Can I suggest an Xref from the xo_emit(3) man page?

@rwatson rwatson closed this as completed Dec 30, 2020
@rwatson rwatson changed the title More easy syntax for dynamically generated field names? No man page for xo_emit_field() Dec 30, 2020
@rwatson
Copy link
Author

rwatson commented Dec 30, 2020

Apparently this is, in fact, because it doesn't have a man page. Reopening as a bug report. :-)

@rwatson rwatson reopened this Dec 30, 2020
@philshafer philshafer self-assigned this Dec 31, 2020
@philshafer philshafer added the bug label Dec 31, 2020
@philshafer
Copy link
Contributor

I should also comment that you should avoid underscores and upper case field names. Please review the guidelines at:

https://libxo.readthedocs.io/en/latest/faq.html#what-makes-a-good-field-name

I'm guessing these are real concrete register names, so perhaps these don't apply, or perhaps you should use a more flexible schema, like:

<register>
    <name>L1D_CACHE_ACCESS</name>
    <value>10</value>
<register>
<register>
    <name>L1D_CACHE_LIMIT</name>
    <value>1024</value>
</register>

This gives you some benefits:

  • allows the receiver to look for specific values (e.g. 'register[name=="L1D_CACHE_ACCESS"]/value')
  • allows the receiver to handle values generically ('for-each (register) { call foo(name, value); }')
  • allows names that are not xml-compatible (starting with a number)
  • allows names to vary while having a simple, fixed schema
  • lets you use the native hardware names that violate the field name guidelines

Thanks,
Phil

@rwatson
Copy link
Author

rwatson commented Dec 31, 2020

They are names defined by the architecture spec itself, so we can't change those. I agree that they are not very desirable (for all the reasons you suggest).

I did originally use the schedule you described, but it made things rather more messy to deal with in Python in our lab templates. This model removes a level of data-structure indirection, which does actually simplify things substantially.

@philshafer
Copy link
Contributor

Fix is in 'develop' branch:

https://raw.githubusercontent.com/Juniper/libxo/develop/libxo/xo_emit_field.3

Thanks,
Phil

@philshafer
Copy link
Contributor

Fixed in libxo-1.5.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants