Zth (libzth)
Loading...
Searching...
No Matches
socks.cpp

More complex fiber and synchronization example.

More complex fiber and synchronization example.Invoked with command line argument 5, this will program will print something like:

Take socks 1
  Wear socks 1
  I don't do the dirty work for socks 1
Take socks 2
    Wash right sock 1
    Wash left sock 1
Take socks 3
    Iron right sock 1
  Wear socks 3
  Wear socks 2
    Wash right sock 3
Take socks 4
  I don't do the dirty work for socks 2
    Wash right sock 2
    Iron left sock 1
    Iron right sock 3
  I don't do the dirty work for socks 3
Take socks 5
    Wash left sock 3
    Iron right sock 2
    Wash left sock 2
  Fold socks 1
  Wear socks 4
    Iron left sock 2
    Iron left sock 3
  I don't do the dirty work for socks 4
Store socks 1
Release socks 1
  Wear socks 5
  I don't do the dirty work for socks 5
  Fold socks 2
Store socks 2
Release socks 2
  Fold socks 3
Store socks 3
Release socks 3
    Wash right sock 5
    Wash left sock 5
    Iron left sock 5
    Wash left sock 4
    Wash right sock 4
    Iron right sock 4
    Iron left sock 4
    Iron right sock 5
  Fold socks 4
  Fold socks 5
Store socks 4
Release socks 4
Store socks 5
Release socks 5
/*
* SPDX-FileCopyrightText: 2019-2026 Jochem Rutgers
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <zth>
#include <cstdio>
using namespace std;
#ifdef ZTH_OS_WINDOWS
# define srand48(seed) srand(seed)
# define drand48() ((double)rand() / (double)RAND_MAX)
#endif
static void nap_a_bit()
{
// NOLINTNEXTLINE(concurrency-mt-unsafe)
zth::nap(drand48());
}
struct Sock {
enum Side { Left, Right };
Sock(int i, Side side)
: str(zth::format("%s sock %d", side == Left ? "left" : "right", i))
{}
};
class Socks : public zth::RefCounted {
public:
explicit Socks(int i)
: left(i, Sock::Left)
, right(i, Sock::Right)
, str(zth::format("socks %d", i))
{}
virtual ~Socks() noexcept override
{
printf("Release %s\n", str.c_str());
}
Sock left;
Sock right;
};
static void washSock(Sock& sock)
{
nap_a_bit();
printf(" Wash %s\n", sock.str.c_str());
nap_a_bit();
printf(" Iron %s\n", sock.str.c_str());
nap_a_bit();
}
static Socks* useSocks(Socks& socks)
{
nap_a_bit();
printf(" Wear %s\n", socks.str.c_str());
// Done wearing, go wash both socks.
{
zth::joiner j(zth::fiber(washSock, socks.left), zth::fiber(washSock, socks.right));
nap_a_bit();
printf(" I don't do the dirty work for %s\n", socks.str.c_str());
// j is out of scope here, so this is the point where the join actually happens.
}
printf(" Fold %s\n", socks.str.c_str());
nap_a_bit();
return &socks;
}
static void takeSocks(int count)
{
std::list<zth::fiber_future<Socks*> > allSocks;
for(int i = 1; i <= count; i++) {
Socks* socks = new Socks(i);
socks->used();
printf("Take %s\n", socks->str.c_str());
// Give the pair of socks to someone else to use.
allSocks.push_back(zth::fiber(useSocks, *socks));
zth::nap(0.5);
}
// Store the socks in the same order as they were worn.
for(decltype(allSocks.begin()) it = allSocks.begin(); it != allSocks.end(); ++it) {
// *it is a SharedReference<Future<Socks*> >
Socks* socks = **it;
printf("Store %s\n", socks->str.c_str());
socks->unused();
}
}
int main_fiber(int argc, char** argv)
{
int count = 10;
if(argc > 1)
count = (int)strtol(argv[1], nullptr, 0);
// NOLINTNEXTLINE(concurrency-mt-unsafe)
srand48((long)time(nullptr));
zth::fiber(takeSocks, count);
return 0;
}
char const * c_str() const
Definition util.h:396
RAII class to join fibers and futures on destruction.
Definition async.h:1375
int main_fiber(int argc, char **argv)
Definition main.cpp:11
void nap(Timestamp const &sleepUntil)
Sleep until the given time stamp.
Definition waiter.h:274
fiber_type< F >::fiber fiber(F &&f, Args &&... args)
Create and start a new fiber.
Definition async.h:1192
std::basic_string< char, std::char_traits< char >, Config::Allocator< char >::type > string
std::string type using Config::Allocator::type.
Definition util.h:315
STL namespace.
cow_string str(T value)
Returns an zth::string representation of the given value.
Definition util.h:497
string format(char const *fmt,...)
Format like sprintf(), but save the result in an zth::string.
Definition util.h:483
#define ZTH_CLASS_NOCOPY(Class)
Definition util.h:234