Compare commits

...

4 Commits

Author SHA1 Message Date
9ff5c03e6e Add custom implementation 2023-12-05 20:18:23 +01:00
35c98e180d fix issue 2023-12-05 10:57:17 +01:00
4144ab422e Revert "Remove unnecessary copy"
This reverts commit e732d062b6.
2023-12-05 10:54:45 +01:00
e732d062b6 Remove unnecessary copy 2023-12-05 10:53:51 +01:00
2 changed files with 68 additions and 51 deletions

View File

@ -19,28 +19,24 @@ public:
private: private:
auto parition(std::span<T> &data) -> std::pair<std::span<T>, std::span<T>> { auto parition(std::span<T> &data) -> std::pair<std::span<T>, std::span<T>> {
auto pivot = data.begin();
std::advance(pivot, std::distance(data.begin(), data.end()) / 2);
std::vector<T> buf(data); auto lefti = data.begin();
auto righti = data.end() - 1;
auto pivot = buf.begin();
std::advance(pivot, std::distance(buf.begin(), buf.end()) / 2);
auto lefti = buf.begin();
auto righti = buf.end();
while (1) { while (1) {
for (; cmp(*lefti, *pivot); lefti++); for (; cmp((*lefti), (*pivot)); lefti++);
for (; !cmp(*righti, *pivot); righti--); for (; !cmp((*righti), (*pivot)); righti--);
if (lefti >= righti) { if (lefti >= righti) {
break; break;
} }
std::swap(lefti, righti); std::swap(*lefti, *righti);
} }
std::move(buf.begin(), buf.end(), data.begin()); return {std::span<T>(data.begin(), pivot - 1), std::span<T>(pivot + 1, data.end())};
return {std::span<T>(data.begin(), lefti), std::span<T>(lefti, data.end())};
} }
@ -54,13 +50,9 @@ private:
} }
} }
// Determine mid of data auto res = parition(data);
auto mid = data.begin(); auto &left = res.first;
std::advance(mid, std::distance(data.begin(), data.end()) / 2); auto &right = res.second;
// Generate left and right view on data (no copies are made here)
std::span<T> left(data.begin(), mid);
std::span<T> right(mid, data.end());
if (depth < mdepth) { if (depth < mdepth) {
std::thread left_thread([&]() { qsort(left, depth + 1, mdepth); }); std::thread left_thread([&]() { qsort(left, depth + 1, mdepth); });

View File

@ -15,35 +15,52 @@
Use semaphores to solve the problem. Use semaphores to solve the problem.
*/ */
class Printer { struct IPrintable {
~IPrintable() = default;
virtual auto print() const -> void = 0;
};
class PrintA : public IPrintable {
private:
QSemaphore &lockBC_;
public:
explicit PrintA(QSemaphore &lockBc) : lockBC_(lockBc) {}
auto print() const -> void override {
this->lockBC_.release(1);
std::cout << "A";
}
};
class PrintB : public IPrintable {
private: private:
QSemaphore &lockBC_; QSemaphore &lockBC_;
QSemaphore &lockC_; QSemaphore &lockC_;
QString name_;
public: public:
explicit Printer(QSemaphore &lockBC, QSemaphore &lockC, QString name) : lockBC_(lockBC), lockC_(lockC), explicit PrintB(QSemaphore &lockBc, QSemaphore &lockC) : lockBC_(lockBc), lockC_(lockC) {}
name_(name) {};
void printA() { auto print() const -> void override {
this->lockBC_.release(1); if (this->lockBC_.tryAcquire(1)) {
std::cout << name_.toStdString() << " A\n";
}
void printB() {
if (this->lockBC_.tryAcquire(1, 10000)) {
if (this->lockC_.available() == 0) { if (this->lockC_.available() == 0) {
this->lockC_.release(1); this->lockC_.release(1);
} }
std::cout << name_.toStdString() << " B\n"; std::cout << "B";
} }
} }
};
void printC() { class PrintC : public IPrintable {
if (this->lockBC_.tryAcquire(1, 10000)) { private:
if (this->lockC_.tryAcquire(1, 10000)) { QSemaphore &lockBC_;
std::cout << name_.toStdString() << " C\n"; QSemaphore &lockC_;
public:
explicit PrintC(QSemaphore &lockBc, QSemaphore &lockC) : lockBC_(lockBc), lockC_(lockC) {}
auto print() const -> void override {
if (this->lockBC_.tryAcquire(1)) {
if (this->lockC_.tryAcquire(1)) {
std::cout << "C";
} else { } else {
this->lockBC_.release(1); this->lockBC_.release(1);
} }
@ -51,33 +68,41 @@ public:
} }
}; };
template<typename T, typename ...Argts>
class Worker : public QThread { class Worker : public QThread {
private: private:
Printer printer_; std::unique_ptr<IPrintable> printer_;
public: public:
Worker(QSemaphore &lockBC, QSemaphore &lockC, QString tname) : printer_(lockBC, lockC, tname) {}; Worker(QString tname, Argts &... args) : printer_(std::make_unique<T>(args...)) {};
protected: protected:
void run() { void run() {
printer_.printA(); while (true) {
printer_.printB(); printer_->print();
printer_.printC(); std::cout.flush();
sleep(1);
}
} }
}; };
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv); //QCoreApplication app(argc, argv);
QSemaphore lockC(1); QSemaphore lockC(1);
QSemaphore lockBC(0); QSemaphore lockBC(0);
int N = 3; Worker<PrintA, QSemaphore> t1("Thread 1", lockBC);
Worker *workers[N]; Worker<PrintB, QSemaphore, QSemaphore> t2("Thread 1", lockBC, lockC);
for (int i = 0; i < N; i++) { Worker<PrintC, QSemaphore, QSemaphore> t3("Thread 1", lockBC, lockC);
workers[i] = new Worker(lockBC, lockC, QString("Thread %1").arg(i));
workers[i]->start();
}
return app.exec(); t1.start();
t2.start();
t3.start();
t1.wait();
t2.wait();
t3.wait();
//return app.exec();
return 0;
} }