Skip to content

Instantly share code, notes, and snippets.

@tejainece
Created May 2, 2024 09:33
Show Gist options
  • Save tejainece/080467be0a1750fc4959faf23178acf2 to your computer and use it in GitHub Desktop.
Save tejainece/080467be0a1750fc4959faf23178acf2 to your computer and use it in GitHub Desktop.
WIP! Fiddling around with pthread_cond_t
//
// Created by tejag on 2024-04-26.
//
#include <cstdint>
#include <cstring>
#include <functional>
#include <iostream>
#include <queue>
#include <syncstream>
#include <thread>
#include <vector>
constexpr int iterations = 10;
std::chrono::steady_clock::time_point schedBegins[iterations];
std::chrono::steady_clock::time_point schedEnds[iterations];
std::chrono::steady_clock::time_point threadBegins[32][iterations];
std::atomic<uint16_t> jobId;
std::atomic<uint16_t> total = 0;
pthread_mutex_t *mutex;
pthread_cond_t *notifier;
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t notifier1 = PTHREAD_COND_INITIALIZER;
[[noreturn]] void thfunc(void *args) {
int threadNum = *(int *)args;
while (true) {
pthread_mutex_lock(&mutex[threadNum]);
pthread_cond_wait(&notifier[threadNum], &mutex[threadNum]);
threadBegins[threadNum][jobId] = std::chrono::steady_clock::now();
if (threadNum == 1)
total++;
pthread_mutex_unlock(&mutex[threadNum]);
}
}
int main() {
pthread_t thId = pthread_self();
pthread_attr_t thAttr;
int policy = 0;
int max_prio_for_policy = 0;
pthread_attr_init(&thAttr);
pthread_attr_getschedpolicy(&thAttr, &policy);
max_prio_for_policy = sched_get_priority_max(policy);
sched_param sp;
memset(&sp, 0, sizeof(struct sched_param));
sp.sched_priority = max_prio_for_policy;
pthread_setschedparam(thId, max_prio_for_policy, &sp);
pthread_attr_destroy(&thAttr);
/*
auto th = std::thread([begin]() {
auto end = std::chrono::steady_clock::now();
std::cout << "Time taken: "
<< std::chrono::duration_cast<std::chrono::microseconds>(
end - begin
)
.count()
<< "us" << std::endl;
});*/
mutex = new pthread_mutex_t[std::thread::hardware_concurrency()];
notifier = new pthread_cond_t[std::thread::hardware_concurrency()];
pthread_t th[std::thread::hardware_concurrency()];
int is[std::thread::hardware_concurrency()];
for (int i = 0; i < std::thread::hardware_concurrency() - 1; i++) {
is[i] = i;
pthread_mutex_init(&mutex[i], nullptr);
mutex[i] = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_init(&notifier[i], nullptr);
notifier[i] = PTHREAD_COND_INITIALIZER;
pthread_create(
&th[i], nullptr, reinterpret_cast<void *(*)(void *)>(thfunc), &is[i]
);
}
for (int iteration = 0; iteration < iterations; iteration++) {
std::cout << "--------------------";
jobId = iteration;
total = 0;
schedBegins[iteration] = std::chrono::steady_clock::now();
for (int threadNum = 0; threadNum < std::thread::hardware_concurrency() - 1;
threadNum++) {
pthread_mutex_lock(&mutex[threadNum]);
pthread_mutex_unlock(&mutex[threadNum]);
pthread_cond_broadcast(&notifier[threadNum]);
}
schedEnds[iteration] = std::chrono::steady_clock::now();
std::cout << "Total: " << total << std::endl;
}
for (int iteration = 0; iteration < iterations; iteration++) {
std::cout << "--------------------" << std::endl;
std::cout << "Scheduling took "
<< std::chrono::duration_cast<std::chrono::microseconds>(
schedEnds[iteration] - schedBegins[iteration]
)
.count()
<< "us" << std::endl;
for (int jobNum = 0; jobNum < std::thread::hardware_concurrency() - 1;
jobNum++) {
std::cout << "Thread " << jobNum << " took "
<< std::chrono::duration_cast<std::chrono::microseconds>(
threadBegins[jobNum][iteration] - schedBegins[iteration]
)
.count()
<< "us" << std::endl;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment