Skip to content

Instantly share code, notes, and snippets.

@foamdino
Created April 24, 2025 05:03
Show Gist options
  • Select an option

  • Save foamdino/847b2639864ccad2c7f694fb1acd0b03 to your computer and use it in GitHub Desktop.

Select an option

Save foamdino/847b2639864ccad2c7f694fb1acd0b03 to your computer and use it in GitHub Desktop.
Read /proc/interrupts
/**
* Read /proc/interrupts and collect resulting current irq information into a list
* filtered by a pattern adapted from irqbalance
*
* @param teb Pointer to our teb
* @param pattern Pointer to const pattern to check in /proc/interrupts for
* @param irq_head Pointer to bl_pal_irq_info linked_list (initially empty)
*
* @retval BL_OK on success, BL_ERR otherwise
*/
__BL_STATIC int
bl_pal_linux_collect_filtered_irq_list(bl_teb_t *teb,
const char *pattern,
bl_pal_irq_info_t **irq_head)
{
FILE *file;
char *line = NULL;
size_t size = 0;
bl_assert(teb != NULL);
bl_assert(!bl_empty(pattern));
bl_assert(irq_head != NULL);
file = fopen("/proc/interrupts", "r");
if (!file)
{
bl_error_set_aux(
teb, BL_ERR_PAL_UNABLE_TO_OPEN_INTERRUPTS, errno, "/proc/interrupts");
return BL_ERR;
}
/* first line is the header we don't need; nuke it */
if (getline(&line, &size, file) <= 0)
{
bl_error_set_aux(
teb, BL_ERR_PAL_UNABLE_TO_READ_INTERRUPTS, errno, "getline()");
/* we use free instead of bl_free as getline contains an internal realloc
* which we do not track */
free(line);
fclose(file);
return BL_ERR;
}
while (!feof(file))
{
int irq_number;
char *c;
char *savedline = NULL;
if (getline(&line, &size, file) <= 0)
break;
/* lines with letters in front are special, like NMI count. Ignore */
c = line;
while (bl_char_space(*c))
c++;
if (!bl_char_digit(*c))
break;
c = strchr(line, ':');
if (!c)
continue;
/* skip if line doesn't contain pattern */
if (strstr(line, pattern) == NULL)
continue;
/* remove trailing CR */
bl_string_trim(line);
savedline = bl_string_strdup(teb, line);
*c = '\0';
irq_number = bl_strtoul(line);
bl_pal_irq_info_t *irq_info = bl_malloc(teb, sizeof(bl_pal_irq_info_t));
bl_pal_linux_init_irq_class_and_type(
teb, savedline, irq_info, irq_number);
if (*irq_head != NULL)
irq_info->next = *(irq_head);
*irq_head = irq_info;
/* we must bl_free the savedline as it was created via bl_string_dup which
* uses bl_malloc */
bl_free(savedline);
}
fclose(file);
/* we use free instead of bl_free as getline contains an internal realloc which we
* do not track */
free(line);
return BL_OK;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment