This round we had mixed success in lowering lantency. Three tests were conducted, using asynchronous Libusb transfers without glib, using ioctls, and trying both with additional load on the bus.
In the first test, Libusb without glib, we can see that it's not significantly different from what was happening with glib. That is, hovering around a 1.6ms mean with 2.1ms max. Note the occasional lower latency submissions, we'll talk about them later.
In the second test, using ioctls, we shave about 0.2ms off of the time, which is nice but not terribly significant. Also in some sense it's a validation of libusb being fairly speedy. Note that the original version of this test had two frees and two callocs in the loop and this slowed it down to on par with libusb, about 1.6ms mean.
The final test is something that I've been meaning to get a screenshot of for a while, and it's something we've observed previously when we had less of an idea of what we've been doing. When adding additional load to the USB (by dd if=/dev/ttyUSB0 of=/dev/null) suddenly the latency drops down into the sub-millisecond range that we want. This occurs using both ioctls and libusb.
Our interpretation of this is that for some reason without additional load the kernel driver will wait a usb frame before returning results to user space. Given the simplicity of the latest iteration of the user space driver, especially the ioctl one this strongly suggests to us a kernel issue.
Next up, writing a kernel device driver!