182 lines
2.9 KiB
C++
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();
|
|
}
|
|
}
|