I am trying to implement something similar to pthread_tryjoin_np
on OSX.
For this purpose I need a reliable way to find if a pthreat_t has been terminated.
I found the mach_port API and I am wondering if I can use thread_info() for this usecase. https://www.gnu.org/software/hurd/gnumach-doc/Thread-Information.html
#include <mach/mach_init.h>
#include <mach/thread_act.h>
#include <mach/mach_port.h>
bool info_available(mach_port_t thread)
{
mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
thread_basic_info_data_t info;
kern_return_t kr = thread_info(thread, THREAD_BASIC_INFO, (thread_info_t) &info, &count);
if (kr == KERN_SUCCESS && (info.flags & TH_FLAGS_IDLE) == 0) {
std::cout << "thread runnable state: " << info.run_state << std::endl;
return true;
}
else
{
std::cout << "invalid call to display info, thread might not be available: " << kr << std::endl;
return false;
}
}
void* thread_info_func(void *parameters)
{
info_available(mach_thread_self());
sleep(8);
pthread_exit(NULL);
}
int main()
{
pthread_t thread;
pthread_attr_t thread_attr;
pthread_attr_init(&thread_attr);
int create_result = pthread_create(&thread, &thread_attr, thread_info_func, NULL);
mach_port_t test_port = pthread_mach_thread_np(thread);
// works display running 1 or waiting 3
info_available(test_port);
pthread_join(m_thread, NULL);
// return 0, is is standard ? Is it reliable ?
mach_port_t test_port = pthread_mach_thread_np(thread);
// bool thread_terminated = test_port == MACH_PORT_NULL;
// doesn't work, kr == KERN_INVALID_ARGUMENT
info_available(test_port);
// reliable ?
// thread_terminated = !info_available();
}
thread_info()
should return TH_STATE_HALTED if the thread has been terminated but I suppose it fails if the thread doesn't exist anymore. In my case thread_info exits with KERN_INVALID_ARGUMENT. Should it mean the thread doesn't exist anymore?
On a side note can pthread_mach_thread_np(thread)
returning 0 also mean the thread has been terminated?
macOS has a function called pthread_getschedparam
which takes a pthread_t
as a parameter and returns an error (ESRCH
) if the thread ID passed in doesn't represent a running thread.
You still run the risk that the thread you're interested in has ended and a new one has been launched which winds up with the same thread ID. I don't know how quickly they are recycled so you'd have to run some tests to see how much of a problem this actually is in practise.