#include using namespace Upp; #ifdef PLATFORM_POSIX __thread int threadid; #else __declspec(thread) int threadid; #endif #define LLOG(x) LOG((threadid) << " " << x << ", count " << count) RWMutex rwlock; VectorMap cache; String Fn(int x) { return AsString(sin(sqrt((double)x))); } void CheckResult(int x, const String& r) { if(r != Fn(x)) { DUMP(r); DUMP(Fn(x)); Panic("Failure! " + AsString(threadid)); } } int writes, removes; void WorkThread(int id) { threadid = id; for(int i = 0; i < 1000000; i++) { if(i % 1000000 == 0) INTERLOCKED Cout() << id << ": " << i << ", writes: " << writes << ", removes: " << removes << "\n"; int x = rand() & 0x7fff; rwlock.EnterRead(); int q = cache.Find(x); if(q >= 0) { String r = cache[q]; CheckResult(x, r); // for(int i = 0; i < 100; i++) // Fn(x); rwlock.LeaveRead(); } else { rwlock.LeaveRead(); rwlock.EnterWrite(); RTIMING("Write!"); q = cache.Find(x); if(q >= 0) CheckResult(x, cache[q]); else { writes++; if(cache.GetCount() >= 0x7ff0) { removes++; cache.Remove(0, 100); } cache.Add(x, Fn(x)); } rwlock.LeaveWrite(); } } } CONSOLE_APP_MAIN { RTIMING("All"); Thread t[20]; for(int i = 0; i < 9; i++) t[i].Run(callback1(WorkThread, i + 1)); WorkThread(0); for(int i = 0; i < 9; i++) t[i].Wait(); RDUMP(writes); RDUMP(removes); }