Unhandled? RMP Interrupts

In the past, when we didn’t turn interrupts off, we saw some pretty bad memory bloat because we weren’t handling any of the interrupts generated by RMP, and thus, the queue was being endlessly populated.

We’re now trying to employ interrupts to do user limits. I’m attempting to do this correctly, but I’m still seeing some pretty bad bloat.

Here’s the config code.

	controller->InterruptMaskClear();
	controller->InterruptMaskOnSet( RSI::RapidCode::RSIEventTypeUSER_LIMIT );
	controller->InterruptEnableSet(true);

In another thread, I’m waiting for interrupts, and attempting to handle them.

	RSI::RapidCode::RSIEventType event_type;
	
	while (true) {
		event_type = controller->InterruptWait(interrupt_loop_wait_max_ms);
	
		// Handle the Interrupt
		switch (event_type) {
		case RSI::RapidCode::RSIEventTypeUSER_LIMIT:
			My__HandleUserLimitInterrupt();
			break;
	
		case RSI::RapidCode::RSIEventTypeTIMEOUT:
			// OK do nothing, process health checks, etc.
			break;
	
		// warning: we shouldn't be receiving unhandled interrupts
		default:
			break;
		};
	}

While we’re streaming motion, I’m seeing bloat on the order of 1.0+ MiB / minute.

Am I doing something wrong? Are there others coming in that I’m not looking for that could result in bloat? Do I have to do something to free memory?

The samples I found, userLimit.cpp and controllerInterrupts.cpp, don’t look remarkably different than what I’m doing, though neither of those examples are really doing anything with the interrupt(s).

@ todd_mm

Memory bloat will occur when we create but fail to handle interrupts. There are quite a few events that are generated and a thread may be unable to keep up. The best way to address this is by limiting those interrupts generated as you tried to do with the config code. The motion controller and each Axis/MultiAxis have their own InterruptMask.

I believe you just need to go into each of the Axis/MultiAxis and Clear out those events you aren’t interested from it.

I’m already doing that (axis->InterruptMaskClear()) for each axis. The code above is for the (only) multiaxis.

Is there any way to inspect the queue or verify that no interrupts are coming in?

@todd_mm

You can check which masks are enabled with InterruptMaskOnGet just to confirm that the clear went through during execution. You could also disable interrupts on various objects to see if you still had memory accumulation. I wouldn’t expect the memory bloat if you are handling the limited set of interrupts you enabled.

So, it turns out that I had cleared interrupts on the MotionController and every Axis, but not the MultiAxis.
If you’re taking nominations for appropriate default behavior, I would vote for having interrupts disabled until they’re masked/enabled. I don’t know about the rest of your customers, but I would prefer “safer” behavior out of the box.

At the very least, I recommend that the code samples include explicitly configuring interrupts corresponding to whether or not they use them.