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

PTHREAD_PRIO_INHERIT seems to result in starvation #5023

Closed
fly-potato-100 opened this issue Mar 28, 2020 · 2 comments
Closed

PTHREAD_PRIO_INHERIT seems to result in starvation #5023

fly-potato-100 opened this issue Mar 28, 2020 · 2 comments
Labels

Comments

@fly-potato-100
Copy link

fly-potato-100 commented Mar 28, 2020

Please fill out the below information:

  • Your Windows build number: (Type ver at a Windows Command Prompt)

Windows: 10.0.18363.720
Distro: Ubuntu-18.04

  • What you're doing and what's happening: (Copy&paste the full set of specific command-line steps necessary to reproduce the behavior, and their output. Include screen shots if that helps demonstrate the problem.)

Here is a simple case:
mutex_priority.cpp

#include <array>
#include <cstdio>
#include <thread>
#include <pthread.h>

// A snippet from Physx3.4 which implements mutex for unix
class MutexUnixImpl
{
	public:
		MutexUnixImpl()
		{
			pthread_mutexattr_t attr;
			pthread_mutexattr_init(&attr);
			pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
			pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
			pthread_mutex_init(&_lock, &attr);
			pthread_mutexattr_destroy(&attr);
		}
		~MutexUnixImpl()
		{
			pthread_mutex_destroy(&_lock);
		}
		void lock()
		{
			pthread_mutex_lock(&_lock);
		}
		void unlock()
		{
			pthread_mutex_unlock(&_lock);
		}
	private:
		pthread_mutex_t _lock;
		size_t _owner = 0;
};

// record&print worker thread's executions
struct Counter
{
	// use 3 workers
	constexpr static int WORKER_COUNT = 3;

	// _count_array[N] records the N'th thread's exec count
	std::array<int, WORKER_COUNT> _count_array;

	MutexUnixImpl _mtx;

	Counter()
	{
		for (int i = 0; i < WORKER_COUNT; ++i)
		{
			_count_array[i] = 0;
		}
	}

	int inc(size_t i)
	{
		if (i < WORKER_COUNT)
		{
			return ++_count_array[i];
		}
		return -1;
	}
	void Print()
	{
		for (int i = 0; i < WORKER_COUNT; ++i)
		{
			printf("counter: %d -> %d\n", i, _count_array[i]);
		}
	}

	void Worker(int id)
	{
		while (true)
		{
			_mtx.lock();
			int c = inc(id);
			printf("[%d] working, count=%d\n", id, c);
			_mtx.unlock();
		}
	}

	void StartAllWorkers()
	{
		for (int i = 0; i < WORKER_COUNT; ++i)
		{
			std::thread(&Counter::Worker, this, i).detach();
		}
	}
};

int main(int argc, char **argv)
{
	Counter counter;
	counter.StartAllWorkers();

	// wait 3 secs
	// then use another thread to print counter
	std::this_thread::sleep_for(std::chrono::seconds(3));
	std::thread([&counter]()
			{
				// stop all workers and print counter for 2 secs
				counter._mtx.lock();
				counter.Print();
				std::this_thread::sleep_for(std::chrono::seconds(2));
				counter._mtx.unlock();
			}).detach();

	// pending
	std::this_thread::sleep_for(std::chrono::seconds(300));
	return 0;
}

compile: g++ -pthread -std=c++11 mutex_priority.cpp
run: ./a.out

  • What's wrong / what should be happening instead:

Work threads ran very well at first.

After 3 seconds, only one worker thread printed the count and the other workers never awoke as if they were starving.

Commenting the line pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); fixed it.

I've checked #1006 which was tagged fixedin1809 and got a bit puzzled.

Could someone help?
thx

@therealkenc
Copy link
Collaborator

Thank-you for the detailed repro. It is always appreciated. The thread starvation didn't get better on WSL1 between 18363 and 21370. It is better on WSL2, natch.

Copy link
Contributor

This issue has been automatically closed since it has not had any activity for the past year. If you're still experiencing this issue please re-file this as a new issue or feature request.

Thank you!

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

No branches or pull requests

2 participants