Reboot prevention while saving parameters

There is a mechanism in place to prevent board reboot/shutdown while the parameters are being saved.

  • Take shutdown mutex - px4_shutdown_lock()
  • Save parameters
  • Release shutdown mutex - px4_shutdown_unlock()

This looks like a good solution. The confusing part to me is the implementation of px4_shutdown_lock() and px4_shutdown_unlock():

int px4_shutdown_lock()
{
	int ret = pthread_mutex_lock(&shutdown_mutex);

	if (ret == 0) {
		++shutdown_lock_counter;
		px4_indicate_external_reset_lockout(LockoutComponent::SystemShutdownLock, true);
		return pthread_mutex_unlock(&shutdown_mutex);
	}

	return ret;
}
int px4_shutdown_unlock()
{
	int ret = pthread_mutex_lock(&shutdown_mutex);

	if (ret == 0) {
		if (shutdown_lock_counter > 0) {
			--shutdown_lock_counter;

			if (shutdown_lock_counter == 0) {
				px4_indicate_external_reset_lockout(LockoutComponent::SystemShutdownLock, false);
			}

		} else {
			PX4_ERR("unmatched number of px4_shutdown_unlock() calls");
		}

		return pthread_mutex_unlock(&shutdown_mutex);
	}

	return ret;
}

Both functions wait for the mutex and release it immediately, so the actual param saving is not done with the mutex in this case.

My question is how does this work?

The mutex is used to access shutdown_lock_counter, basically a semaphore that holds the state whether reboot should be prevented or not. I assume that’s because there could be multiple writers, each of them bumping shutdown_lock_counter by one, and decreasing it again when they are done.

(By the way, this sort of question can probably be answered by an LLM quite well, maybe because you well formulated the question, so I appreciate that.)

1 Like