muduo/examples/procmon/dummyload.cc
2024-03-08 14:03:37 +08:00

182 lines
2.9 KiB
C++

#include "muduo/base/Atomic.h"
#include "muduo/base/Condition.h"
#include "muduo/base/CurrentThread.h"
#include "muduo/base/Mutex.h"
#include "muduo/base/Thread.h"
#include "muduo/base/Timestamp.h"
#include "muduo/net/EventLoop.h"
#include <math.h>
#include <stdio.h>
using namespace muduo;
using namespace muduo::net;
int g_cycles = 0;
int g_percent = 82;
AtomicInt32 g_done;
bool g_busy = false;
MutexLock g_mutex;
Condition g_cond(g_mutex);
double busy(int cycles)
{
double result = 0;
for (int i = 0; i < cycles; ++i)
{
result += sqrt(i) * sqrt(i+1);
}
return result;
}
double getSeconds(int cycles)
{
Timestamp start = Timestamp::now();
busy(cycles);
return timeDifference(Timestamp::now(), start);
}
void findCycles()
{
g_cycles = 1000;
while (getSeconds(g_cycles) < 0.001)
g_cycles = g_cycles + g_cycles / 4; // * 1.25
printf("cycles %d\n", g_cycles);
}
void threadFunc()
{
while (g_done.get() == 0)
{
{
MutexLockGuard guard(g_mutex);
while (!g_busy)
g_cond.wait();
}
busy(g_cycles);
}
printf("thread exit\n");
}
// this is open-loop control
void load(int percent)
{
percent = std::max(0, percent);
percent = std::min(100, percent);
// Bresenham's line algorithm
int err = 2*percent - 100;
int count = 0;
for (int i = 0; i < 100; ++i)
{
bool busy = false;
if (err > 0)
{
busy = true;
err += 2*(percent - 100);
++count;
// printf("%2d, ", i);
}
else
{
err += 2*percent;
}
{
MutexLockGuard guard(g_mutex);
g_busy = busy;
g_cond.notifyAll();
}
CurrentThread::sleepUsec(10*1000); // 10 ms
}
assert(count == percent);
}
void fixed()
{
while (true)
{
load(g_percent);
}
}
void cosine()
{
while (true)
for (int i = 0; i < 200; ++i)
{
int percent = static_cast<int>((1.0 + cos(i * 3.14159 / 100)) / 2 * g_percent + 0.5);
load(percent);
}
}
void sawtooth()
{
while (true)
for (int i = 0; i <= 100; ++i)
{
int percent = static_cast<int>(i / 100.0 * g_percent);
load(percent);
}
}
int main(int argc, char* argv[])
{
if (argc < 2)
{
printf("Usage: %s [fctsz] [percent] [num_threads]\n", argv[0]);
return 0;
}
printf("pid %d\n", getpid());
findCycles();
g_percent = argc > 2 ? atoi(argv[2]) : 43;
int numThreads = argc > 3 ? atoi(argv[3]) : 1;
std::vector<std::unique_ptr<Thread>> threads;
for (int i = 0; i < numThreads; ++i)
{
threads.emplace_back(new Thread(threadFunc));
threads.back()->start();
}
switch (argv[1][0])
{
case 'f':
{
fixed();
}
break;
case 'c':
{
cosine();
}
break;
case 'z':
{
sawtooth();
}
break;
// TODO: square and triangle waves
default:
break;
}
g_done.getAndSet(1);
{
MutexLockGuard guard(g_mutex);
g_busy = true;
g_cond.notifyAll();
}
for (int i = 0; i < numThreads; ++i)
{
threads[i]->join();
}
}