Issue
When I cat /proc/interrupts
, I can also see system internal interrupts (as described in the doc), e.g. all the IPIs occurring on the cores.
However, when I read the content of /proc/interrupts in C, these additional lines are not there. E.g. this code:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int source, n;
unsigned char buffer[8192];
source = open("/proc/interrupts", O_RDONLY);
n=read(source, buffer, 8192);
close(source);
buffer[n] = 0;
printf("%d chars in /proc/interrupts:\n", n);
printf("%s", buffer);
return 0;
}
delivers the same output as cat except for the lines about IPIs missing at the end. Why are the IPI lines not read by my C code and how can I fix that?
EDIT: Adding the output of the two different approaches
uuser@mpsoc:~/git/rt-benchmarking/ARM64/tif$ cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
3: 64464514 20153532 359399 132413 GICv2 30 Level arch_timer
6: 0 0 0 0 GICv2 67 Level zynqmp_ipi
7: 0 0 0 0 GICv2 175 Level arm-pmu
8: 0 0 0 0 GICv2 176 Level arm-pmu
9: 0 0 0 0 GICv2 177 Level arm-pmu
10: 0 0 0 0 GICv2 178 Level arm-pmu
13: 0 0 0 0 GICv2 156 Level zynqmp-dma
14: 0 0 0 0 GICv2 157 Level zynqmp-dma
15: 0 0 0 0 GICv2 158 Level zynqmp-dma
16: 0 0 0 0 GICv2 159 Level zynqmp-dma
17: 0 0 0 0 GICv2 160 Level zynqmp-dma
18: 0 0 0 0 GICv2 161 Level zynqmp-dma
19: 0 0 0 0 GICv2 162 Level zynqmp-dma
20: 0 0 0 0 GICv2 163 Level zynqmp-dma
22: 0 0 0 0 GICv2 109 Level zynqmp-dma
23: 0 0 0 0 GICv2 110 Level zynqmp-dma
24: 0 0 0 0 GICv2 111 Level zynqmp-dma
25: 0 0 0 0 GICv2 112 Level zynqmp-dma
26: 0 0 0 0 GICv2 113 Level zynqmp-dma
27: 0 0 0 0 GICv2 114 Level zynqmp-dma
28: 0 0 0 0 GICv2 115 Level zynqmp-dma
29: 0 0 0 0 GICv2 116 Level zynqmp-dma
30: 1 0 0 0 GICv2 144 Level fd070000.memory-controller
31: 0 0 0 0 GICv2 89 Level eth0, eth0
32: 9075012 0 0 0 GICv2 95 Level eth1, eth1
34: 0 0 0 0 GICv2 49 Level cdns-i2c
35: 0 0 0 0 GICv2 50 Level cdns-i2c
36: 0 0 0 0 GICv2 42 Level ff960000.memory-controller
37: 0 0 0 0 GICv2 57 Level axi-pmon, axi-pmon
38: 0 0 0 0 GICv2 155 Level axi-pmon, axi-pmon
39: 6215 0 0 0 GICv2 47 Level ff0f0000.spi
40: 0 0 0 0 GICv2 58 Level ffa60000.rtc
41: 0 0 0 0 GICv2 59 Level ffa60000.rtc
42: 674 0 0 0 GICv2 80 Level mmc0
43: 439018 0 0 0 GICv2 81 Level mmc1
44: 0 0 0 0 GICv2 51 Level ff040000.spi
45: 0 0 0 0 GICv2 52 Level ff050000.spi
46: 300 0 0 0 GICv2 53 Level xuartps
48: 0 0 0 0 GICv2 88 Level ams-irq
49: 12 0 0 0 GICv2 154 Level fd4c0000.dma
50: 0 0 0 0 GICv2 151 Level fd4a0000.zynqmp-display
51: 0 0 0 0 GICv2 97 Level xhci-hcd:usb1
IPI0: 2913422 5267435 34552519 34586268 Rescheduling interrupts
IPI1: 146402 147211 18371 29840 Function call interrupts
IPI2: 0 0 0 0 CPU stop interrupts
IPI3: 0 0 0 0 CPU stop (for crash dump) interrupts
IPI4: 0 0 0 0 Timer broadcast interrupts
IPI5: 28636 345 203 125 IRQ work interrupts
IPI6: 0 0 0 0 CPU wake-up interrupts
Err: 0
uuser@mpsoc:~/git/rt-benchmarking/ARM64/tif$ ./a.out
3626 chars in /proc/interrupts:
CPU0 CPU1 CPU2 CPU3
3: 64465302 20153650 359399 132413 GICv2 30 Level arch_timer
6: 0 0 0 0 GICv2 67 Level zynqmp_ipi
7: 0 0 0 0 GICv2 175 Level arm-pmu
8: 0 0 0 0 GICv2 176 Level arm-pmu
9: 0 0 0 0 GICv2 177 Level arm-pmu
10: 0 0 0 0 GICv2 178 Level arm-pmu
13: 0 0 0 0 GICv2 156 Level zynqmp-dma
14: 0 0 0 0 GICv2 157 Level zynqmp-dma
15: 0 0 0 0 GICv2 158 Level zynqmp-dma
16: 0 0 0 0 GICv2 159 Level zynqmp-dma
17: 0 0 0 0 GICv2 160 Level zynqmp-dma
18: 0 0 0 0 GICv2 161 Level zynqmp-dma
19: 0 0 0 0 GICv2 162 Level zynqmp-dma
20: 0 0 0 0 GICv2 163 Level zynqmp-dma
22: 0 0 0 0 GICv2 109 Level zynqmp-dma
23: 0 0 0 0 GICv2 110 Level zynqmp-dma
24: 0 0 0 0 GICv2 111 Level zynqmp-dma
25: 0 0 0 0 GICv2 112 Level zynqmp-dma
26: 0 0 0 0 GICv2 113 Level zynqmp-dma
27: 0 0 0 0 GICv2 114 Level zynqmp-dma
28: 0 0 0 0 GICv2 115 Level zynqmp-dma
29: 0 0 0 0 GICv2 116 Level zynqmp-dma
30: 1 0 0 0 GICv2 144 Level fd070000.memory-controller
31: 0 0 0 0 GICv2 89 Level eth0, eth0
32: 9075115 0 0 0 GICv2 95 Level eth1, eth1
34: 0 0 0 0 GICv2 49 Level cdns-i2c
35: 0 0 0 0 GICv2 50 Level cdns-i2c
36: 0 0 0 0 GICv2 42 Level ff960000.memory-controller
37: 0 0 0 0 GICv2 57 Level axi-pmon, axi-pmon
38: 0 0 0 0 GICv2 155 Level axi-pmon, axi-pmon
39: 6215 0 0 0 GICv2 47 Level ff0f0000.spi
40: 0 0 0 0 GICv2 58 Level ffa60000.rtc
41: 0 0 0 0 GICv2 59 Level ffa60000.rtc
42: 674 0 0 0 GICv2 80 Level mmc0
43: 439018 0 0 0 GICv2 81 Level mmc1
44: 0 0 0 0 GICv2 51 Level ff040000.spi
45: 0 0 0 0 GICv2 52 Level ff050000.spi
46: 300 0 0 0 GICv2 53 Level xuartps
48: 0 0 0 0 GICv2 88 Level ams-irq
49: 12 0 0 0 GICv2 154 Level fd4c0000.dma
50: 0 0 0 0 GICv2 151 Level fd4a0000.zynqmp-display
51: 0 0 0 0 GICv2 97 Level xhci-hcd:usb1
Solution
The solution is reading from the open file descriptor twice in a row, even though not a full buffer was read at the first iteration. That's also how cat
does it. Therefore, the following code will produce the desired output:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int source, n;
unsigned char buffer[8192];
source = open("/proc/interrupts", O_RDONLY);
for(int i = 0; i < 2; i++)
{
n=read(source, buffer, 8192);
buffer[n] = 0;
printf("%d chars in /proc/interrupts:\n", n);
printf("%s", buffer);
}
close(source);
return 0;
}
Answered By - IRatherStayPrivate