<commit_before>#ifndef LIGHT_THREAD
#define LIGHT_THREAD

#include <thread>
#include <mutex>
#include <queue>
#include <set>
#include <condition_variable>
#include <memory>
static std::mutex mtx;


static std::queue<void*> threads;


class Thread {
public:
	std::thread thread;
	std::mutex mtx;
	std::condition_variable evt;
	std::function<void()> work;
	bool hasWork;
	Thread() {
		hasWork = false;
		thread = std::thread([=](){
			bool first = true;
			while(true) {
				{
					if(!first) {
					//Add ourselves to the availability list
					std::unique_lock<std::mutex> ml(::mtx);
					threads.push(this);
					}
				}
			if(!hasWork) {
				std::unique_lock<std::mutex> l(mtx);
			evt.wait(l);
			}
			//It is the caller's responsibility to remove us from the list of available threads
			first = false;
			work();
			hasWork = false;
			//Free the lambda by swapping it out
			work = std::function<void()>();
			}
		});
	}
	~Thread() {

	}
};
static void SubmitWork(const std::function<void()>& item) {
	std::unique_lock<std::mutex> l(mtx);
	//We don't like to be kept waiting! Add a new thread immediately!
	if(threads.empty()) {
		auto bot = new Thread();
		bot->work = item;
		bot->hasWork = true;
		bot->evt.notify_one();
	}else {
		auto bot = ((Thread*)threads.front());
		threads.pop();
		bot->work = item;
		bot->hasWork = true;
		bot->evt.notify_one();

	}

}


class TimerEvent {
public:
	std::function<void()> functor;
	uint64_t timeout;
	bool cancellationToken;
	std::shared_ptr<TimerEvent> next;
	bool operator<(const TimerEvent& other) const {
		return other.timeout>timeout;
	}
	TimerEvent() {
		next = 0;
	}
};
template<typename T>
class shared_ref {
public:
	std::shared_ptr<T> val;
	shared_ref(const std::shared_ptr<T>& obj) {
		val = obj;
	}
	T& operator*() const {
		return *val;
	}
	T* operator->() const {
		return val.get();
	}
	operator std::shared_ptr<T>() const {
		return val;
	}
	bool operator<(const shared_ref<T>& other) const {
		return (*val)<(*other.val);
	}
};

class TimerPool {
public:
	std::thread thread;
	std::set<shared_ref<TimerEvent>> events;
	std::mutex mtx;
	std::condition_variable c;
	//Global time correction
	uint64_t offset;
	void Insert(std::shared_ptr<TimerEvent> evt) {
		evt->timeout += offset;
		if(events.find(evt) == events.end()) {
			events.insert(evt);
			}else {
				std::shared_ptr<TimerEvent> found = *events.find(evt);
				events.erase(found);
				evt->next = found;
				//evt->next = found->next;
				//found->next = evt;
				events.insert(evt);
				printf("LL\n");
			}
	}
	TimerPool() {
		offset = 0;
		thread = std::thread([=](){
			while(true) {
				{
					{
					std::unique_lock<std::mutex> l(mtx);
					while(!events.empty()) {
						std::vector<std::shared_ptr<TimerEvent>> currentEvents;
						std::shared_ptr<TimerEvent> cevt = *events.begin();
						uint64_t ctimeout = cevt->timeout;
						while(true) {
							currentEvents.push_back(cevt);
							if(cevt->next == 0) {
								break;
							}
							std::shared_ptr<TimerEvent> ptr = cevt->next;
							cevt->next = 0;
							cevt = ptr;
							printf("Append\n");
						}
						events.erase(events.begin());
						uint64_t offset = this->offset;
						l.unlock();
						auto start = std::chrono::steady_clock::now();

						std::mutex mx;
						std::unique_lock<std::mutex> ml(mx);
						if(offset>ctimeout) {
							printf("IERR\n");
							offset = 0;
						}
						if(c.wait_for(ml,std::chrono::milliseconds(ctimeout-offset)) == std::cv_status::timeout) {


						for(auto i = currentEvents.begin(); i != currentEvents.end();i++) {
							if((*i)->cancellationToken) {
							SubmitWork((*i)->functor);
							}
						}
						}else {
							this->mtx.lock();
							for(auto i = currentEvents.begin();i != currentEvents.end(); i++) {
								Insert(*i);
							}
							auto end = std::chrono::steady_clock::now();
							auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count();
							offset = this->offset;
							this->offset+=milliseconds;
							this->mtx.unlock();

							printf("Interrupt %i\n",(int)this->offset);
						}
						l.lock();
					}

				}
				}
				std::mutex mx;
				std::unique_lock<std::mutex> ml(mx);
				c.wait(ml);

			}
		});
	}
};
static TimerPool timerPool;
static std::shared_ptr<TimerEvent> CreateTimer(const std::function<void()>& callback, size_t timeout) {

	std::shared_ptr<TimerEvent> evt = std::make_shared<TimerEvent>();
	evt->functor = callback;
	evt->timeout = timeout;
	evt->cancellationToken = true;
	{
	std::lock_guard<std::mutex> mg(timerPool.mtx);
	timerPool.Insert(evt);
	timerPool.c.notify_one();
	}
	return evt;<commit_msg>FIXED!<commit_after>#ifndef LIGHT_THREAD
#define LIGHT_THREAD

#include <thread>
#include <mutex>
#include <queue>
#include <set>
#include <condition_variable>
#include <memory>
static std::mutex mtx;


static std::queue<void*> threads;


class Thread {
public:
	std::thread thread;
	std::mutex mtx;
	std::condition_variable evt;
	std::function<void()> work;
	bool hasWork;
	Thread() {
		hasWork = false;
		thread = std::thread([=](){
			bool first = true;
			while(true) {
				{
					if(!first) {
					//Add ourselves to the availability list
					std::unique_lock<std::mutex> ml(::mtx);
					threads.push(this);
					}
				}
			if(!hasWork) {
				std::unique_lock<std::mutex> l(mtx);
			evt.wait(l);
			}
			//It is the caller's responsibility to remove us from the list of available threads
			first = false;
			work();
			hasWork = false;
			//Free the lambda by swapping it out
			work = std::function<void()>();
			}
		});
	}
	~Thread() {

	}
};
static void SubmitWork(const std::function<void()>& item) {
	std::unique_lock<std::mutex> l(mtx);
	//We don't like to be kept waiting! Add a new thread immediately!
	if(threads.empty()) {
		auto bot = new Thread();
		bot->work = item;
		bot->hasWork = true;
		bot->evt.notify_one();
	}else {
		auto bot = ((Thread*)threads.front());
		threads.pop();
		bot->work = item;
		bot->hasWork = true;
		bot->evt.notify_one();

	}

}


class TimerEvent {
public:
	std::function<void()> functor;
	uint64_t timeout;
	bool cancellationToken;
	std::shared_ptr<TimerEvent> next;
	bool operator<(const TimerEvent& other) const {
		return other.timeout>timeout;
	}
	TimerEvent() {
		next = 0;
	}
};
template<typename T>
class shared_ref {
public:
	std::shared_ptr<T> val;
	shared_ref(const std::shared_ptr<T>& obj) {
		val = obj;
	}
	T& operator*() const {
		return *val;
	}
	T* operator->() const {
		return val.get();
	}
	operator std::shared_ptr<T>() const {
		return val;
	}
	bool operator<(const shared_ref<T>& other) const {
		return (*val)<(*other.val);
	}
};

class TimerPool {
public:
	std::thread thread;
	std::set<shared_ref<TimerEvent>> events;
	std::mutex mtx;
	std::condition_variable c;
	void Insert(std::shared_ptr<TimerEvent> evt) {
		if(events.find(evt) == events.end()) {
			events.insert(evt);
			}else {
				std::shared_ptr<TimerEvent> found = *events.find(evt);
				events.erase(found);
				evt->next = found;
				events.insert(evt);
				printf("LL\n");
			}
	}
	TimerPool() {
		thread = std::thread([=](){
			while(true) {
				{
					{
					std::unique_lock<std::mutex> l(mtx);
					while(!events.empty()) {
						std::vector<std::shared_ptr<TimerEvent>> currentEvents;
						std::shared_ptr<TimerEvent> cevt = *events.begin();
						uint64_t ctimeout = cevt->timeout;
						while(true) {
							currentEvents.push_back(cevt);
							if(cevt->next == 0) {
								break;
							}
							std::shared_ptr<TimerEvent> ptr = cevt->next;
							cevt->next = 0;
							cevt = ptr;
							printf("Append\n");
						}
						events.erase(events.begin());
						l.unlock();
						auto start = std::chrono::steady_clock::now();

						std::mutex mx;
						std::unique_lock<std::mutex> ml(mx);

						if(c.wait_for(ml,std::chrono::milliseconds(ctimeout)) == std::cv_status::timeout) {
							for(auto i = events.begin();i != events.end();i++) {
								if(ctimeout>i->val->timeout) {
									//Execute immediately
									i->val->timeout = 0;
								}else {
									//Defer execution
									i->val->timeout-=(ctimeout);
								}
							}
						for(auto i = currentEvents.begin(); i != currentEvents.end();i++) {
							if((*i)->cancellationToken) {
							SubmitWork((*i)->functor);
							}
						}
						}else {
							this->mtx.lock();
							for(auto i = currentEvents.begin();i != currentEvents.end(); i++) {
								Insert(*i);
							}
							auto end = std::chrono::steady_clock::now();
							auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count();
							//TODO: Subtract milliseconds from all timers
							for(auto i = events.begin();i!= events.end();i++) {
								if(milliseconds>i->val->timeout) {
									i->val->timeout = 0;
								}else {
									i->val->timeout-=milliseconds;
								}
							}
							this->mtx.unlock();


						}
						l.lock();
					}

				}
				}
				std::mutex mx;
				std::unique_lock<std::mutex> ml(mx);
				c.wait(ml);

			}
		});
	}
};
static TimerPool timerPool;
static std::shared_ptr<TimerEvent> CreateTimer(const std::function<void()>& callback, size_t timeout) {

	std::shared_ptr<TimerEvent> evt = std::make_shared<TimerEvent>();
	evt->functor = callback;
	evt->timeout = timeout;
	evt->cancellationToken = true;
	{
	std::lock_guard<std::mutex> mg(timerPool.mtx);
	timerPool.Insert(evt);
	timerPool.c.notify_one();
	}
	return evt;
{'fraction_non_alphanumeric': 0.1724686902992995, 'fraction_numerical': 0.002334960730205901, 'mean_word_length': 3.197327394209354, 'pattern_counts': {'":': 0, '<': 83, '<?xml version=': 0, '>': 140, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4349702', 'n_tokens_mistral': 4157, 'n_tokens_neox': 3338, 'n_words': 650}