fivdi / epoll

A low-level Node.js binding for the Linux epoll API
MIT License
84 stars 13 forks source link

Removing fd from epoll does not work #18

Closed mathiask88 closed 8 years ago

mathiask88 commented 8 years ago

Hi,

I got a 3300Hz pulse attached to a RPI2 GPIO pin. And if I test the interrupts with this script

// echo 17 > /sys/class/gpio/export
// echo in > /sys/class/gpio/gpio17/direction
// echo rising > /sys/class/gpio/gpio17/edge

var Epoll = require('epoll').Epoll,
  fs = require('fs'),
  inputfd = fs.openSync('/sys/class/gpio/gpio17/value', 'r+'),
  value = new Buffer(1),  // The three Buffers here are global
  count = 0,
  time;

// Create a new Epoll. The callback is the interrupt handler.
var poller = new Epoll(function (err, fd, events) {
  count++;
  // Read GPIO value file. Reading also clears the interrupt.
  fs.readSync(inputfd, value, 0, 1, 0);
});

time = process.hrtime(); // Get start time.

// Start watching for interrupts. This will trigger the first interrupt
// as the value file already has data waiting for a read.
poller.add(inputfd, Epoll.EPOLLPRI);

// Print interrupt rate to console after 5 seconds.
setTimeout(function () {
  var rate;

  time = process.hrtime(time); // Get run time.
  rate = Math.floor(count / (time[0] + time[1] / 1E9));
  console.log(rate + ' interrupts per second');

  // Stop watching.
  poller.remove(inputfd).close();
}, 5000);

the kworker process still is at ~8% cpu usage after the script has finished. If I disconnect the source from the pin the cpu usage goes down to 0%, so I think the deregistration of the fd does not work properly.

// Edit: Linux raspberrypi 4.1.17-v7+ #838 SMP Tue Feb 9 13:15:09 GMT 2016 armv7l GNU/Linux

fivdi commented 8 years ago

Do things improve if echo 17 > /sys/class/gpio/unexport is executed from the command line after the script terminates?

mathiask88 commented 8 years ago

Unexporting the pin solves the problem, but there must be a way to delete the epoll event listener properly and leave the pin exportet?

fivdi commented 8 years ago

The issue isn't related to the file descriptor that's being (that was) monitored by epoll. The monitoring stopped when the remove method was called. In addition, the process has terminated so it can't be monitoring the file descriptor any more.

The issue is occurring because interrupts are activated and occurring at a rate of 3300 per second. The OS is still processing them. The GPIO needs to be unexported or interrupts should be disabled with echo none > /sys/class/gpio/gpio17/edge

I haven't tried it out but the CPU usage may even be visible after the export and setting of interrupts and before the script is run.

mathiask88 commented 8 years ago

Ahh okay that makes sense. I will try that tomorrow and report back. Thanks!

mathiask88 commented 8 years ago

Couldn't wait until tomorrow, tested with my smartphone's ssh client :) You were right, if I set the edge to none the cpu load drops. Thanks for your help!

fivdi commented 8 years ago

No problem :) Thanks for the feedback.