Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LinkInterface/Vehicle uses mutexes to synchronize writing bytes #8835

Merged
merged 3 commits into from Jun 14, 2020

Conversation

DonLakeFlyer
Copy link
Contributor

@DonLakeFlyer DonLakeFlyer commented Jun 13, 2020

Previously writing bytes out to a link went through a sequence of multiple queued messages in Vehicle and LinkInterface to prevent thread safety issues. The problem is that doing it that way is dog slow. So slow that in cases where a joystick was being used on a device with a very slow CPU the MANUAL_CONTROL messages didn't make it through to the vehicle at a high enough frequency. It also chew more CPU than needed.

What happens now is that both Vehicle and LinkInterface use mutexes for thread safety in the following calls which are threadsafe:

  • LinkInterface::writeBytesThreadSafe
  • Vehicle::sendMessageOnLinkThreadSafe
  • Vehicle::sendJoystickDataThreadSafe - Joystick calls this directly instead of posting queued signal

The end result is Mavlink message sending QGC->Vehicle which is measured in nanoseconds instead of 100s of milliseconds. And also when using a joystick a significant reduction in CPU usage.


return true;
}
QMutexLocker lock(&_sendMessageOnLinkMutex);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this lock needed given that link->writeBytesThreadSafe() has its own lock? What is it protecting?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sure this stuff is thread safe as well:

    if (!link->isConnected()) {
        return false;
    }

    // Give the plugin a chance to adjust
    _firmwarePlugin->adjustOutgoingMavlinkMessage(this, link, &message);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the joystick send will come through this path from another thread.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This link->isConnected() probably isn't too problematic. But this _firmwarePlugin->adjustOutgoingMavlinkMessage is since it maintains a mavlink channel status if I remember correctly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, It doesn't look like it is needed. The adjustOutgoingMavlinkMessage() function is 99.9% void. The only time something actually is done is for this:

    case MAVLINK_MSG_ID_PARAM_SET:
        _handleOutgoingParamSet(vehicle, outgoingLink, message);

Might as well put a mutex in there rather than annoying the other 99.9% of the time this never used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that it's a firmwareplugin override so you have no idea what can happen in there in a custom build. Without a change to the FirmwarePlugin method to mark as threadsafe required and likely a name change to prevent old unthreadsafe code from leaking through it needed. I can certainly do that. Seems like a better way to go intstead of the upper layers doing things which won't be needed most of the time.

@DonLakeFlyer
Copy link
Contributor Author

Also there is gimbal control signal which when that gets fully implemented should switch to using this path as well.

@DonLakeFlyer
Copy link
Contributor Author

I should have also mentioned that this pull removes all the advanced joystick modes. Only joystick usage for RC is now supported.

@DonLakeFlyer
Copy link
Contributor Author

Crap, closed by accident.

@DonLakeFlyer
Copy link
Contributor Author

@dogmaphobic All good now?

@dogmaphobic
Copy link
Contributor

@dogmaphobic All good now?

Yup! :)

@DonLakeFlyer DonLakeFlyer merged commit ccedbbe into mavlink:master Jun 14, 2020
@DonLakeFlyer DonLakeFlyer deleted the VehicleSendMessage branch June 14, 2020 17:39
@lukegluke
Copy link
Contributor

@DonLakeFlyer, @dogmaphobic this one leads to #9751

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants