Example #1
0
Load::Load(QObject *parent) : QObject(parent), d_ptr(new LoadPrivate(this))
{
	Q_D(Load);
	ins = this;
	setObjectName("Load");

	auto avProcess = [this](QNetworkReply *reply){
		Q_D(Load);
		Task &task = d->queue.head();
		int sharp = task.code.indexOf(QRegularExpression("[#_]"));
		switch (task.state){
		case None:
		{
			QString i = task.code.mid(2, sharp - 2);
			QString p = sharp == -1 ? QString() : task.code.mid(sharp + 1);
			QString url("http://www.%1/video/av%2/");
			url = url.arg(Utils::customUrl(Utils::Bilibili)).arg(i);
			if (!p.isEmpty()){
				url += QString("index_%1.html").arg(p);
			}
			forward(QNetworkRequest(url), Page);
			break;
		}
		case Page:
		{
			d->model->clear();
			QString api, id, video(reply->readAll());
			int part = video.indexOf("<select");
			if (part != -1 && sharp == -1){
				QRegularExpression r("(?<=>).*?(?=</option>)");
				QStringRef list(&video, part, video.indexOf("</select>", part) - part);
				QRegularExpressionMatchIterator i = r.globalMatch(list);
				api = "http://www.%1/video/%2/index_%3.html";
				api = api.arg(Utils::customUrl(Utils::Bilibili));
				while (i.hasNext()){
					int index = d->model->rowCount() + 1;
					QStandardItem *item = new QStandardItem;
					item->setData(QUrl(api.arg(task.code).arg(index)), UrlRole);
					item->setData((task.code + "#%1").arg(index), StrRole);
					item->setData(Page, NxtRole);
					item->setData(Utils::decodeXml(i.next().captured()), Qt::EditRole);
					d->model->appendRow(item);
				}
			}
			if (d->model->rowCount() > 0){
				emit stateChanged(task.state = Part);
			}
			else{
				QRegularExpression r = QRegularExpression("cid[=\":]*\\d+", QRegularExpression::CaseInsensitiveOption);
				QRegularExpressionMatchIterator i = r.globalMatch(video);
				while (i.hasNext()){
					QString m = i.next().captured();
					m = QRegularExpression("\\d+").match(m).captured();
					if (id.isEmpty()){
						id = m;
					}
					else if (id != m){
						id.clear();
						break;
					}
				}
				if (!id.isEmpty()){
					api = "http://comment.%1/%2.xml";
					api = api.arg(Utils::customUrl(Utils::Bilibili));
					forward(QNetworkRequest(api.arg(id)), File);
				}
                else{
                    emit stateChanged(203);
                    qDebug() << "Fail to load danmaku, try biliApi";
                    dequeue();
                }
            }
			break;
		}
		case File:
		{
			dumpDanmaku(reply->readAll(), Utils::Bilibili, false);
			emit stateChanged(task.state = None);
			dequeue();
			break;
		}
		}
	};
	auto avRegular = [](QString &code){
		code.remove(QRegularExpression("/index(?=_\\d+\\.html)"));
		QRegularExpression r("a(v(\\d+([#_])?(\\d+)?)?)?");
		r.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
		return getRegular(r)(code);
	};
	d->pool.append({ avRegular, 0, avProcess });

	auto bbProcess = [this, avProcess](QNetworkReply *reply) {
		Q_D(Load);
		Task &task = d->queue.head();
		switch (task.state) {
		case None:
		{
			QString i = task.code.mid(2);
			QString u = "http://www.%1/bangumi/i/%2/";
			u = u.arg(Utils::customUrl(Utils::Bilibili)).arg(i);
			forward(QNetworkRequest(u), Page);
			break;
		}
		case Page:
		{
			d->model->clear();
			QString page(reply->readAll());
			QStringList list = page.split("<li data-index");

			if (list.size() < 2) {
				emit stateChanged(task.state = None);
				dequeue();
				break;
			}

			list.removeFirst();
			QListIterator<QString> iter(list);
			iter.toBack();
			while (iter.hasPrevious()) {
				QRegularExpression r;
				const QString &i = iter.previous();
				r.setPattern("(?<=href=\")[^\"]+");
				QString c = r.match(i).captured();
				fixCode(c);
				r.setPattern("(?<=<span>).+(?=</span>)");
				QString t = Utils::decodeXml(r.match(i).captured());

				QStandardItem *item = new QStandardItem;
				item->setData(c, StrRole);
				item->setData(None, NxtRole);
				item->setData(t, Qt::EditRole);
				d->model->appendRow(item);
			}
			emit stateChanged(task.state = Part);
		}
		}
	};

	auto bbRegular = [](QString &code) {
		code.replace(QRegularExpression("bangumi/i/(?=\\d+)"), "bb");
		QRegularExpression r("b(b(\\d+)?)?");
		r.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
		return getRegular(r)(code);
	};
	d->pool.append({ bbRegular, 0, bbProcess });

	auto acProcess = [this](QNetworkReply *reply){
		Q_D(Load);
		Task &task = d->queue.head();
		int sharp = task.code.indexOf(QRegularExpression("[#_]"));
		switch (task.state){
		case None:
		{
			QString i = task.code.mid(2, sharp - 2);
			QString p = sharp == -1 ? QString() : task.code.mid(sharp + 1);
			QString url("http://www.%1/v/ac%2");
			url = url.arg(Utils::customUrl(Utils::AcFun)).arg(i);
			if (!p.isEmpty()){
				url += QString("_%1").arg(p);
			}
			forward(QNetworkRequest(url), Page);
			break;;
		}
		case Page:
		{
			d->model->clear();
			QRegularExpressionMatchIterator match = QRegularExpression("data-vid.*?</a>").globalMatch(reply->readAll());
			while (match.hasNext()){
				QStandardItem *item = new QStandardItem;
				QString part = match.next().captured();
				QRegularExpression r;
				r.setPattern("(?<=>)[^>]+?(?=</a>)");
				item->setData(Utils::decodeXml(r.match(part).captured()), Qt::EditRole);
				r.setPattern("(?<=data-vid=\").+?(?=\")");
				QString next("http://static.comment.%1/V2/%2?pageSize=1000&pageNo=1");
				next = next.arg(Utils::customUrl(Utils::AcFun)).arg(r.match(part).captured());
				item->setData(next, UrlRole);
				item->setData((task.code + "#%1").arg(d->model->rowCount() + 1), StrRole);
				item->setData(File, NxtRole);
				d->model->appendRow(item);
			}
			if (sharp == -1 && d->model->rowCount() >= 2){
				emit stateChanged(task.state = Part);
			}
			else{
				int i = sharp == -1 ? 0 : task.code.mid(sharp + 1).toInt() - 1;
				if (i >= 0 && i < d->model->rowCount()){
					forward(QNetworkRequest(d->model->item(i)->data(UrlRole).toUrl()), File);
				}
				else{
					emit stateChanged(203);
					dequeue();
				}
			}
			break;
		}
		case File:
		{
			QByteArray data = reply->readAll();
			if (data != "[[],[],[]]"){
				QNetworkRequest &request = task.request;
				QUrl url = request.url();
				int page = QUrlQuery(url).queryItemValue("pageNo").toInt();
				url.setQuery(QString());
				request.setUrl(url);
				dumpDanmaku(data, Utils::AcFun, false);
				QUrlQuery query;
				query.addQueryItem("pageSize", "1000");
				query.addQueryItem("pageNo", QString::number(page + 1));
				url.setQuery(query);
				request.setUrl(url);
				forward(request, File);
			}
			else{
				emit stateChanged(task.state = None);
				dequeue();
			}
			break;
		}
		}
	};
	auto acRegular = getRegular(QRegularExpression("a(c(\\d+([#_])?(\\d+)?)?)?", QRegularExpression::CaseInsensitiveOption));
	d->pool.append({ acRegular, 0, acProcess });

	auto abProcess = [this, acProcess](QNetworkReply *reply){
		Q_D(Load);
		Task &task = d->queue.head();
		int sharp = task.code.indexOf(QRegularExpression("[#_]"));
		switch (task.state){
		case None:
		{
			QString url("http://www.%1/bangumi/video/page?bangumiId=%2&pageSize=30&pageNo=%3&order=2");
			url = url.arg(Utils::customUrl(Utils::AcFun)).arg(task.code.mid(2, sharp - 2));
			url = url.arg(sharp == -1 ? 1 : (task.code.mid(sharp + 1).toInt() - 1) / 30 + 1);
			forward(QNetworkRequest(url), Page);
			break;
		}
		case Page:
		{
			if (sharp != -1){
				QJsonObject data = QJsonDocument::fromJson(reply->readAll()).object()["data"].toObject();
				int i = task.code.mid(sharp + 1).toInt();
				if (i > 0){
					i = (i - 1) % 30;
				}
				else{
					i = data["totalCount"].toInt();
					if (i > 30){
						task.code = task.code.left(sharp) + QString("#%1").arg(i);
						task.state = None;
						task.processer->process(nullptr);
						break;
					}
				}
				QJsonArray list = data["list"].toArray();
				if (i < 0 || i >= list.size()){
					emit stateChanged(203);
					dequeue();
					break;
				}
				QString head("http://static.comment.%1/V2/%2?pageSize=1000&pageNo=1");
				head = head.arg(Utils::customUrl(Utils::AcFun));
				head = head.arg(list[i].toObject()["danmakuId"].toString());
				forward(QNetworkRequest(head), File);
				break;
			}
			else{
				d->model->clear();
			}
		}
		case Part:
		{
			QJsonObject info = QJsonDocument::fromJson(reply->readAll()).object();
			if (!info["success"].toBool() && d->model->rowCount() == 0){
				emit stateChanged(info["status"].toInt());
				dequeue();
			}
			QJsonObject data = info["data"].toObject();
			for (const QJsonValue &value : data["list"].toArray()){
				QStandardItem *item = new QStandardItem;
				QJsonObject data = value.toObject();
				item->setData(data["title"].toString(), Qt::EditRole);
				QString head("http://static.comment.%1/V2/%2?pageSize=1000&pageNo=1");
				head = head.arg(Utils::customUrl(Utils::AcFun)).arg(data["danmakuId"].toString());
				item->setData(head, UrlRole);
				item->setData((task.code + "#%1").arg(d->model->rowCount() + 1), StrRole);
				item->setData(File, NxtRole);
				d->model->appendRow(item);
			}
			if (task.state != Part){
				emit stateChanged(task.state = Part);
			}
			if (data["pageNo"].toInt() < data["totalPage"].toInt()){
				QUrl url = reply->request().url();
				auto arg = QUrlQuery(url).queryItems();
				for (auto &p : arg){
					if (p.first == "pageNo"){
						p.second = QString::number(p.second.toInt() + 1);
						break;
					}
				}
				QUrlQuery query;
				query.setQueryItems(arg);
				url.setQuery(query);
				d->remain.insert(d->manager.get(QNetworkRequest(url)));
			}
			break;
		}
		case File:
		{
			acProcess(reply);
			break;
		}
		}
	};
	auto abRegular = getRegular(QRegularExpression("a(b(\\d+([#_])?(\\d+)?)?)?", QRegularExpression::CaseInsensitiveOption));
	d->pool.append({ abRegular, 0, abProcess });

	auto ccProcess = [this](QNetworkReply *reply){
		Q_D(Load);
		Task &task = d->queue.head();
		int sharp = task.code.indexOf(QRegularExpression("[#_]"));
		switch (task.state){
		case None:
		{
			QString i = task.code.mid(2, sharp - 2);
			QString p = sharp == -1 ? QString() : task.code.mid(sharp + 1);
			QString url("http://www.%1/play/h%2/");
			url = url.arg(Utils::customUrl(Utils::TuCao)).arg(i);
			if (!p.isEmpty()){
				url += QString("#%1").arg(p);
			}
			forward(QNetworkRequest(url), Page);
			break;
		}
		case Page:
		{
			QString page = reply->readAll();
			d->model->clear();
			QRegularExpressionMatch m;
			QRegularExpression r("(?<=<li>)[^<]*(?=</li>)");
			m = r.match(page, page.indexOf("<ul id=\"player_code\""));
			QStringList list = m.captured().split("**");
			m = r.match(page, m.capturedEnd());
			QString code = m.captured();
			for (const QString &iter : list){
				QStandardItem *item = new QStandardItem;
				item->setData(iter.mid(iter.indexOf('|') + 1), Qt::EditRole);
				QString api("http://www.%1/index.php?m=mukio&c=index&a=init&playerID=%2");
				api = api.arg(Utils::customUrl(Utils::TuCao)).arg((code + "-%1").arg(d->model->rowCount()));
				item->setData(api, UrlRole);
				item->setData((task.code + "#%1").arg(d->model->rowCount() + 1), StrRole);
				item->setData(File, NxtRole);
				d->model->appendRow(item);
			}
			if (sharp == -1 && d->model->rowCount() >= 2){
				emit stateChanged(task.state = Part);
			}
			else{
				int i = sharp == -1 ? 0 : task.code.mid(sharp + 1).toInt() - 1;
				if (i >= 0 && i < d->model->rowCount()){
					forward(QNetworkRequest(d->model->item(i)->data(UrlRole).toUrl()), File);
				}
				else{
					emit stateChanged(203);
					dequeue();
				}
			}
			break;
		}
		case File:
		{
			dumpDanmaku(reply->readAll(), Utils::TuCao, false);
			emit stateChanged(task.state = None);
			dequeue();
			break;
		}
		}
	};
	auto ccRegular = [](QString &code){
		code.replace(QRegularExpression("[Hh](?=\\d)"), "cc");
		QRegularExpression r("c(c(\\d+([#_])?(\\d+)?)?)?");
		r.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
		return getRegular(r)(code);
	};
	d->pool.append({ ccRegular, 0, ccProcess });

	d->pool.append(Proc());
	Proc *directProc = &d->pool.last();
	directProc->process = [this](QNetworkReply *reply){
		Q_D(Load);
		Task &task = d->queue.head();
		switch (task.state){
		case None:
		{
			QUrl url = QUrl::fromUserInput(task.code);
			task.request.setUrl(url);
			task.state = File;
			forward();
			break;
		}
		case File:
		{
			Record load;
			QUrl url = reply->url();
			QByteArray data(reply->readAll());
			load.source = url.url();
			load.access = url.isLocalFile() ? url.toLocalFile() : load.source;
			load.string = QFileInfo(task.code).fileName();
			load.delay = task.delay;
			QString head = Utils::decodeTxt(data.left(512));
			if (head.startsWith("[Script Info]")){
				load.danmaku = Parse::parseComment(data, Utils::ASS);
			}
			else if (!head.startsWith("<?xml")){
				load.danmaku = Parse::parseComment(data, Utils::AcFun);
			}
			else if (head.indexOf("<packet>") != -1){
				load.danmaku = Parse::parseComment(data, Utils::Niconico);
			}
			else if (head.indexOf("<i>") != -1){
				load.danmaku = Parse::parseComment(data, Utils::Bilibili);
				QString i = QRegularExpression("(?<=<chatid>)\\d+(?=</chatid>)").match(head).captured();
				if (!i.isEmpty()){
					load.source = "http://comment.%1/%2.xml";
					load.source = load.source.arg(Utils::customUrl(Utils::Bilibili)).arg(i);
				}
			}
			else if (head.indexOf("<c>") != -1){
				load.danmaku = Parse::parseComment(data, Utils::AcfunLocalizer);
			}
			if (load.delay != 0){
				for (Comment &c : load.danmaku){
					c.time += load.delay;
				}
			}
			Danmaku::instance()->appendToPool(&load);
			emit stateChanged(task.state = None);
			dequeue();
			break;
		}
		}
	};
	directProc->priority = -100;
	directProc->regular = [this, directProc](QString &code){
		if (code.startsWith("full?") || code.startsWith("hist?")){
			code.clear();
			return false;
		}
		QUrl u = QUrl::fromUserInput(code);
		if (!u.host().isEmpty() && !u.path().isEmpty()){
			return true;
		}
		if (QFileInfo(code).exists()){
			return true;
		}
		code.clear();
		return false;
	};

	auto fullBiProcess = [this](QNetworkReply *reply){
		Q_D(Load);
		Task &task = d->queue.head();
		switch (task.state) {
		case None:
		{
			emit progressChanged(0);
			QString api("http://comment.%1/rolldate,%2");
			api = api.arg(Utils::customUrl(Utils::Bilibili));
			task.code = QUrlQuery(task.code.mid(5)).queryItemValue("source");
			forward(QNetworkRequest(api.arg(QFileInfo(task.code).baseName())), Page);
			break;
		}
		case Page:
		{
			QByteArray data = reply->readAll();
			QJsonArray date = QJsonDocument::fromJson(data).array();
			if (date.isEmpty()) {
				emit stateChanged(203);
				dequeue();
				break;
			}
			QJsonObject head = date.first().toObject();
			QString url("http://comment.%1/dmroll,%2,%3");
			url = url.arg(Utils::customUrl(Utils::Bilibili));
			url = url.arg(head["timestamp"].toVariant().toInt());
			url = url.arg(QFileInfo(task.code).baseName());
			QNetworkRequest request(url);
			request.setAttribute(QNetworkRequest::User, data);
			forward(request, Code);
			break;
		}
		case Code:
		{
			QByteArray data = task.request.attribute(QNetworkRequest::User).toByteArray();
			QJsonArray date = QJsonDocument::fromJson(data).array();
			QMap<int, int> count;
			for (auto iter : date) {
				QJsonObject item = iter.toObject();
				count[item["timestamp"].toVariant().toInt()] += item["new"].toVariant().toInt();
			}

			data = reply->readAll();
			if (count.size() >= 2) {
				int max = QRegularExpression("(?<=\\<max_count\\>).+(?=\\</max_count\\>)").match(data).captured().toInt();
				int now = 0;

				auto getHistory = [d, &count, &task](int date) {
					QString url("http://comment.%1/dmroll,%2,%3");
					url = url.arg(Utils::customUrl(Utils::Bilibili));
					url = url.arg(date);
					url = url.arg(QFileInfo(task.code).baseName());
					return d->manager.get(QNetworkRequest(url));
				};

				for (auto iter = count.begin() + 1;; ++iter) {
					now += iter.value();
					if (iter + 1 == count.end()) {
						d->remain += getHistory(iter.key());
						break;
					}
					else if (now + (iter + 1).value() > max) {
						d->remain += getHistory(iter.key());
						now = 0;
					}
				}

				auto pool = QSharedPointer<QVector<Parse::ResultDelegate>>::create();
				pool->append(Parse::parseComment(data, Utils::Bilibili));

				double total = d->remain.size() + 2;
				for (QNetworkReply *iter : d->remain) {
					connect(iter, &QNetworkReply::finished, [=, &task]() {
						QByteArray data = iter->readAll();
						pool->append(Parse::parseComment(data, Utils::Bilibili));
						switch (iter->error()) {
						case QNetworkReply::NoError:
							emit progressChanged((total - d->remain.size()) / total);
						case QNetworkReply::OperationCanceledError:
							if (d->remain.isEmpty() && !pool->empty()) {
								Record load;
								load.full = true;
								for (auto &iter : *pool) {
									load.danmaku.append(iter);
								}
								load.source = task.code;
								Danmaku::instance()->appendToPool(&load);
								emit stateChanged(task.state = None);
								dequeue();
							}
						default:
							break;
						}
					});
				}

				emit progressChanged(2 / total);
				emit stateChanged(task.state = File);
				break;
			}
			else {
				emit progressChanged(1);
				dumpDanmaku(data, Utils::Bilibili, true);
				emit stateChanged(task.state = None);
				dequeue();
				break;
			}
		}
		}
	};

	auto fullBiRegular = QRegularExpression("^full\\?source=http://comment\\.bilibili\\.com/\\d+\\.xml$");
	fullBiRegular.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
	d->pool.append({ getRegular(fullBiRegular), 100, fullBiProcess });

	auto histBiProcess = [this](QNetworkReply *reply){
		Q_D(Load);
		Task &task = d->queue.head();
		switch (task.state){
		case None:
		{
			QUrlQuery query(task.code.mid(5));
			task.code = query.queryItemValue("source");
			QString cid = QFileInfo(task.code).baseName();
			QString dat = query.queryItemValue("date");
			QString url;
			QNetworkRequest request;
			if (dat != "0" && dat.toUInt() != QDateTime(QDate::currentDate()).toTime_t()){
				url = QString("http://comment.%1/dmroll,%2,%3");
				url = url.arg(Utils::customUrl(Utils::Bilibili));
				url = url.arg(dat).arg(cid);
				int limit = QDateTime(QDateTime::fromTime_t(dat.toInt()).date().addDays(1)).toTime_t();
				request.setAttribute(QNetworkRequest::User, limit);
			}
			else{
				url = QString("http://comment.%1/%2.xml").arg(Utils::customUrl(Utils::Bilibili));
				url = url.arg(cid);
			}
			request.setUrl(url);
			forward(request, File);
			break;
		}
		case File:
		{
			Record load;
			load.danmaku = Parse::parseComment(reply->readAll(), Utils::Bilibili);
			load.source = task.code;
			for (Record &iter : Danmaku::instance()->getPool()){
				if (iter.source == load.source){
					iter.full = false;
					iter.danmaku.clear();
					iter.limit = 1;
					break;
				}
			}
			load.limit = task.request.attribute(QNetworkRequest::User).toInt();
			Danmaku::instance()->appendToPool(&load);
			emit stateChanged(task.state = None);
			dequeue();
			break;
		}
		}
	};
	auto histBiRegular = QRegularExpression("^hist\\?source=http://comment\\.bilibili\\.com/\\d+\\.xml&date=\\d+$");
	histBiRegular.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
	d->pool.append({ getRegular(histBiRegular), 100, histBiProcess });

	connect(this, &Load::stateChanged, [this](int code){
		switch (code){
		case None:
		case Page:
		case Part:
		case Code:
		case File:
			break;
		default:
		{
			Q_D(Load);
			if (!d->tryNext()){
				emit errorOccured(code);
			}
			break;
		}
		}
	});
}
void mm_one_queue_simulator_for_batch_means(long nr_customer, double average_interarrival_time, double average_service_time, long *next_seed_interarrival, long *next_seed_service, long nr_batch, long batch_size, long initial_bias, double correlation_bound, double half_alpha, double eps_relative, struct batch_means_output *result) {
  struct event *event_list = NULL;
  struct queue system_queue;
  enum server_state server_state = IDLE;
  double system_clock = 0.0;
  struct event *event;

  enum event_type event_type;
  int customer_number = 0;
  double clock_time;
  double arrival_time;
  double interarrival_time;
  double departure_time;
  double service_time;

  struct customer *customer;

  double lamda_interarrival_rate = 1.0 / average_interarrival_time; /* interarrival rate: lamda = 1 / average_time */
  double mu_service_rate = 1.0 / average_service_time; /* service_rate: mu = 1 / arverage_service_time */

  double total_customer_in_system_time = 0.0; 

  /* for batch means */
  double *batch_mean;
  batch_mean = malloc(nr_batch * sizeof(double));
  memset(batch_mean, 0, nr_batch * sizeof(double));
  double *batch_sum;
  batch_sum = malloc(nr_batch * sizeof(double));
  memset(batch_sum, 0, nr_batch * sizeof(double));

  double lag_1_corr;
  double t; /* student t distribution */
  double dev;
  double avg;
  double ci_hw;
  double ci_hb;
  long batch_index;
  int i;

  /* initial system */
  init_queue(&system_queue);

  /* step 0: initial first event and add into event list */
#ifdef DEBUG
  printf("Info: simulation starts.\n");
#endif
  if (customer_number < nr_customer) {
    event_type = ARRIVAL;
    clock_time = 1.0;
    customer = init_customer(customer_number);
    customer->arrival_time = clock_time;
    customer_number++;
    add_event(&event_list, event_type, clock_time, (void *) customer);
  }
  /* step 1: pop event from event list */
  event = get_event(event_list);
  while (event) {
    /* step 2: addvance clock */
    system_clock = event->clock_time;
    pop_event(&event_list);
    /* get customer */
    customer = (struct customer *) event->content;
    event->content = NULL;
    switch (event->event_type) {
      case ARRIVAL:
#ifdef DEBUG
        /* print info */
        printf("Info: [time: %12f] [customer: %8d] event: ARRIVAL\n", system_clock, customer->no);
#endif
        /* generate service time */
        service_time = exponential_random_generator(mu_service_rate, next_seed_service);
        add_service_time_to_customer(customer, service_time);
        /* step 3: update state */
        if (server_state == IDLE) {
          server_state = BUSY;
          /* set service time and departure time */
          service_time = customer->service_time;
          departure_time = system_clock + service_time;
          event_type = DEPARTURE;
          customer->departure_time = departure_time;
          add_event(&event_list, event_type, departure_time, (void *) customer);
        } else if (server_state == BUSY) {
          /* add customer into queue */
          enqueue(&system_queue, (void *) customer);
        }
        /* step 4: generate future event into event list */
        /* if customer_number < nr_customer, generate next arrival event */
        if (customer_number < nr_customer) {
          interarrival_time = exponential_random_generator(lamda_interarrival_rate, next_seed_interarrival);
          arrival_time = system_clock + interarrival_time;
          event_type = ARRIVAL;
          customer = init_customer(customer_number);
          customer->arrival_time = arrival_time;
          customer_number++;
          add_event(&event_list, event_type, arrival_time, (void *) customer);
        }
     
        break;
      case DEPARTURE:
#ifdef DEBUG
        /* print info */
        printf("Info: [time: %12f] --------------------------------------- [customer: %8d] event: DEPARTURE\n", system_clock, customer->no);
#endif
        if (customer->no >= (initial_bias + nr_batch * batch_size)) {
          for (i = 0; i < nr_batch; i++) {
            batch_mean[i] = batch_sum[i] / batch_size;
          }
          /* check correlation */
          lag_1_corr = sample_lag1_corr_sequence(batch_mean, nr_batch);
          if (fabs(lag_1_corr) < correlation_bound) {
            /* check confidence interval */
            t = gsl_cdf_tdist_Pinv(1.0-half_alpha, nr_batch - 1); 
            avg = avg_sequence(batch_mean, nr_batch);
            dev = dev_sequence(batch_mean, nr_batch);
            ci_hw = t * dev / sqrt((double) nr_batch);
            ci_hb = avg * eps_relative;
            if (ci_hw < ci_hb) {
              if (result) {
                result->avg = avg;
                result->ci_hw = ci_hw;
                result->lag_1 = lag_1_corr;
              }
              return;
            }
          }
          /* not satisfy constraint, double batch_size */
          batch_size *= 2;
          for (i = 0; i < nr_batch / 2; i++) {
            batch_sum[i] = batch_sum[i*2] + batch_sum[i*2+1];
          }
          for (i = nr_batch / 2; i < nr_batch; i++) {
            batch_sum[i] = 0.0;
          }
        }
        if (customer->no >= initial_bias) {
          batch_index = (customer->no - initial_bias) / batch_size;
          batch_sum[batch_index] += customer->departure_time - customer->arrival_time;
          total_customer_in_system_time += customer->departure_time - customer->arrival_time;
        }
        free(customer);
        customer = NULL;
        /* step 3: update state */
        if (system_queue.count > 0) {
          customer = (struct customer *) dequeue(&system_queue);
          /* set service time and departure time */
          service_time = get_service_time_from_customer(customer);
          departure_time = system_clock + service_time;
          event_type = DEPARTURE;
          customer->departure_time = departure_time;
          add_event(&event_list, event_type, departure_time, (void *) customer);
        } else if (system_queue.count == 0) {
          server_state = IDLE;
        }

        /* step 4: generate future event into event list */
        break;
      default:
        fprintf(stderr, "Error: unkown event type.\n");
        exit(EXIT_FAILURE);
    }
    free(event);
    event = NULL;

    /* get next event */
    event = get_event(event_list);
  }
#ifdef DEBUG
  printf("Info: event list is empty.\n");
  printf("Info: simulation ends.\n");
#endif
}
Example #3
0
					//function handeles the  deperived case of writers and pops the process accordingly
int pop_3(int head,int tail,int ldesc1)
{
	struct lentry    *tptr;
        struct pentry  *pptr;
	tptr=&lockarr[ldesc1];
	int max=head,pid,next;
	int count=1;
        int rd[50],i=1;
	next =q[head].qnext;
	int cc=1;	

	if (isEmpty(head))		//if one in the ready queue change the 
	{
		tptr->lstate=LUSED;
		return OK; 
		//continue ;
	}
	

	while(next <tail )		//calculate the max writer
        {	
        	pptr = &proctab[next];
                if (pptr->wait_type==WRITE)
			max=next;
		next=q[next].qnext;
	}

	if (max !=head)
	if ( (&proctab[max])->dep==3 )    //has been deprieved 3 times
	{
		pptr = &proctab[max];
		pptr->dep=0;	
		pptr->wait_lock=-1;
		pptr->wait_type=-1;
		ready(dequeue(max),RESCHNO);
		//ready(dequeue(max),RESCHYES);
		return OK;	
		//continue;
	}
	

	if (q[max].qnext ==tail && max !=head)      //writer is the last element
	{
		pid=getlast(tail);
		pptr = &proctab[pid];
		pptr->dep=0;	
		pptr->wait_lock=-1;
		pptr->wait_type=-1;

		ready(pid,RESCHNO);
		return OK; 
		//continue;
	}		

	// do this only if the last writer priority = priority of last reader
	next=q[tail].qprev;	
	

	if (max ==head)
	{
		while (next !=head)
		{
			pptr= &proctab[next];
			pptr->wait_lock=-1;
			pptr->wait_type=-1;
			ready(dequeue(next),RESCHNO);
			next=q[tail].qprev;
		}
	}
	else
	{
		while(next!=max)
		{
			pptr= &proctab[next];
			pptr->wait_lock=-1;
			pptr->wait_type=-1;
			ready(dequeue(next),RESCHNO); 
			/*dfsdfsfsdfsdfsdfSD*/
			next=q[tail].qprev;
		}
		
		(&proctab[max])->dep++;
	}
	return OK;
}
Example #4
0
void DumbCall::notify() {
  callback();
  dequeue();
}
Example #5
0
PROC *getproc(PROC **list){  // allocate a FREE proc from freeList
    return dequeue(list);    //return a FREE PROC pointer;
}
Example #6
0
void clarityEventLoopStart(ClarityEventLoop *eventLoop)
{
	while (hasEvent(eventLoop))
		dequeue(eventLoop);
}
Example #7
0
double runSimulation(double arrivalRate, double serviceTime, double simTime)
{


	struct Simulation sim = initSimulation(arrivalRate, serviceTime, simTime);


	while(sim.currTime < sim.totalSimTime){

	if((sim.timeForNextArrival < sim.timeForNextDeparture) || (sim.buffer.currSize == 0)){
	sim.e = ARRIVAL;
	}
	else{
	sim.e = DEPARTURE;
	}

	//printf("Curr: %lf\n",sim.currTime);
	
	if(sim.e == ARRIVAL){


		sim.currTime = sim.timeForNextArrival;
		
		struct Data d;
		d.arrivalTime = sim.currTime;

		enqueue(&(sim.buffer), d); 

		sim.timeForNextArrival = sim.currTime + getRandTime(sim.arrivalRate);

		if(sim.buffer.currSize == 1){

		sim.timeForNextDeparture = sim.currTime + serviceTime;
		//printf("ok");
		}

	}

	else if(sim.e == DEPARTURE){

		sim.currTime = sim.timeForNextDeparture;
		
		struct Data packet = dequeue(&(sim.buffer));

		//printf("Depart: %lf\n", packet.arrivalTime);
		
		packet.departureTime = sim.currTime;
		//printf("Arrival: %lf\n", packet.arrivalTime);
		//printf("Depart: %lf\n", packet.departureTime);

		sim.timeForNextDeparture = sim.currTime + serviceTime;

		enqueue(&(sim.eventQueue), packet);
	}


	}
	
	return calcAverageWaitingTime(&sim);


}
Example #8
0
/*------------------------------------------------------------------------
 * kill  --  kill a process and remove it from the system
 *------------------------------------------------------------------------
 */
SYSCALL kill(int pid)
{
	STATWORD ps;    
	struct	pentry	*pptr;		/* points to proc. table for pid*/
	int	dev;

	disable(ps);
	if (isbadpid(pid) || (pptr= &proctab[pid])->pstate==PRFREE) {
		restore(ps);
		return(SYSERR);
	}
	if (--numproc == 0)
		xdone();

	dev = pptr->pdevs[0];
	if (! isbaddev(dev) )
		close(dev);
	dev = pptr->pdevs[1];
	if (! isbaddev(dev) )
		close(dev);
	dev = pptr->ppagedev;
	if (! isbaddev(dev) )
		close(dev);
	
	send(pptr->pnxtkin, pid);

	freestk(pptr->pbase, pptr->pstklen);
	switch (pptr->pstate) {

	case PRCURR:	pptr->pstate = PRFREE;	/* suicide */
			resched();

	case PRWAIT:	semaph[pptr->psem].semcnt++;

	case PRREADY:	dequeue(pid);
			pptr->pstate = PRFREE;
			break;

	case PRSLEEP:
	case PRTRECV:	unsleep(pid);
						/* fall through	*/
	default:	pptr->pstate = PRFREE;
			bs_map_t *temp;
			int i;
                        for (i=0;i<16;i++)
			{
				temp = &bsm_tab[i];
				 while(temp !=NULL)
			        {
			                if(temp->bs_pid == currpid)
			                {
			                        xmunmap(temp->bs_vpno);
						if(temp->bs_private_heap == 1)
							release_bs(i);
			                        return OK;
				         }
			                temp=temp->next;
				}

	}			}
	restore(ps);
	return(OK);
}
Example #9
0
/**  
  * \param e a Service descriptor
  *
  * The calling task publishes a new value "v" to service "s". All waiting tasks on
  * service "s" will be resumed and receive a copy of this value "v". 
  * Values generated by services without subscribers will be lost.
  */
void Service_Publish( SERVICE *s, int16_t v ) {
	s->data = v;
	while (s->list_of_tasks_who_are_subscribed.head != NULL) {
		enqueue(&service_queue, dequeue(&s->list_of_tasks_who_are_subscribed));
	}
}
Example #10
0
/*
 * A consumer thread.
 * This will wait until the queue has a job and run it
 */
void *JobConsumer (void *device) {
  JobToPUM *job;
  int devID = *((int *) device);

  jobNResult jnr;

  struct timeval start, end, result,
                 overheadstart, overheadend, overheadresult; //for capturing job execution times
  finishedJobNotification fjn;

  //  cl_device_type dev = *((cl_device_type *)device);

  //TODO: Does doing this only once have any consequences? (Can we reuse a command queue *safely*? What if the device is left on an "inconsistent state"?)
  //prepare OpenCL
/*  if (!initializeCLExec(dev)) {
    fprintf(stderr,"PUM (%i):  FAILED INITIALIZING %s DEVICE\n", myid, dev == CL_DEVICE_TYPE_CPU ? "CPU" : "GPU");
    return NULL;
  }*/

  printf("PUM (%i): Job consumer started\n", myid);

  while (true) {
    //wait until the queue has a job
    job = dequeue(devID);

    jnr.job = job;
    fjn.category = job->category;
    fjn.ranAtPU = job->runOn;
    fjn.executionTime = 0.0;
    fjn.succeeded = false;
    if (gettimeofday(&overheadstart, NULL)) {
      perror("gettimeofday");
      exit (EXIT_FAILURE);
    }

    if (!initializeCLBuffers(job)) {
      fprintf(stderr,"PUM (%i):  FAILED INITIALIZING BUFFERS\n", myid);

      fjn.executionTime = DBL_MAX ;
      sendFinishedJobNotification(&fjn);


      jnr.res = JOB_RETURN_STATUS_FAILURE;
      resultPrepareAndSend(&jnr);
      continue;
    }

    if (debug_PUM) {
      printf("PUM (%i):  Arguments BEFORE execution:\n", myid);
      for (cl_uint i = 0; i < job->nTotalArgs; i++) {
        printf("arg %i: ", i);
        if (job->argTypes[i] == EMPTY_BUFFER)
          printf("EMPTY BUFFER.\n");
        else
          print1DArray(job->arguments[i], job->argSizes[i] / sizeof(unsigned int));
      }
    }
    if (gettimeofday(&overheadend, NULL)) {
      perror("gettimeofday");
      return false;
    }

    start = overheadend;
    if (!execJob(job)) {
      fprintf(stderr,"PUM (%i):  FAILED RUNNING JOB\n", myid);

      fjn.executionTime = DBL_MAX ;
      sendFinishedJobNotification(&fjn);

      jnr.res = JOB_RETURN_STATUS_FAILURE;
      fprintf(stderr,"JOB FAIL NOTIFICATION SENT TO JS. Sending to RC as well.\n");
      resultPrepareAndSend(&jnr);
      continue;
    }
    if (gettimeofday(&end, NULL)) {
      perror("gettimeofday");
      return false;
    }

    if (debug_PUM) {
      printf("PUM (%i):  Arguments AFTER execution:\n", myid);
      for (cl_uint i = 0; i < job->nTotalArgs; i++) {
        printf("arg %i: ", i);
        if (job->argTypes[i] == EMPTY_BUFFER)
          printf("EMPTY BUFFER.\n");
        else
          print1DArray(job->arguments[i], job->argSizes[i] / sizeof(unsigned int));
      }
    }

    if (!SILENT)
      printf("PUM (%i):  Finished running job (%s).\n", myid, job->startingKernel);
//    if (debug_PUM)
//      printJobToPUM(job);


    jnr.res = JOB_RETURN_STATUS_SUCCESS;

//    sendResults(&jnr);//TODO: include this on a file-transfer metric for the scheduler?

    timeval_subtract(&result, &end, &start);
    fjn.executionTime = result.tv_sec + (result.tv_usec / 1000000.0);
    timeval_subtract(&overheadresult, &overheadend, &overheadstart);
    fjn.overheads = overheadresult.tv_sec + (overheadresult.tv_usec / 1000000.0);
    fjn.succeeded = jnr.res;
    sendFinishedJobNotification(&fjn);


    resultPrepareAndSend(&jnr);
  }
}
Example #11
0
void* worker(void* x)
{
	int id = *((int *) x), i, current=-1;
	element* me = &workers[id-1];
	queueReceived terminated;
	received *term;
	
	#ifdef DEBUG
		printf("[DEBUG] THREAD%d is now working\n", id);
	#endif
	
	queueReceived_init(&terminated);
	
	while(1)
	{
		pthread_mutex_lock(&me->mutex);
		if (me->q.head == NULL)
		{
			pthread_cond_wait(&me->work, &me->mutex);
		}
		pthread_mutex_unlock(&me->mutex);
		
		pthread_mutex_lock(&pikachu);
		if (toShutdown)
		{
			pthread_mutex_unlock(&pikachu);
			#ifdef DEBUG
				pthread_mutex_lock(&display);
					printf("[DEBUG] worker thread%d killed\n", id);
				pthread_mutex_unlock(&display);
			#endif
			
			for (i=0 ; i<N_WORKERS ; i++)
				pthread_cond_signal(&workers[i].work);
			
			pthread_exit(0);
		}
		pthread_mutex_unlock(&pikachu);
		
		pthread_mutex_lock(&me->mutex);
		while (me->q.head)
		{
			term = getJob(me->q.head->id, &terminated);
			
			if (term == NULL)
			{
				term = received_init();
				enqueueReceived(&terminated, term);
			}
			
			segment* s = dequeue(&me->q);
			if (s->last)
				term->ended = true;
			enqueue(&term->q, s);
		}
		pthread_mutex_unlock(&me->mutex);
		
		for (term=terminated.head ; term ; term=term->next)
		{
			if(term->ended && term->q.head)
			{
				pthread_mutex_lock(&display);
				printf("\n\n[THREAD%d] JOB %d\n", id, term->q.head->id);
				while (term->q.head)
				{
					segment* s = dequeue(&term->q);
					if (s->page != current)
					{
						current = s->page;
						printf("PAGE %d\n", current);
					}
					printf("%s\n", s->text);
				}
				pthread_mutex_unlock(&display);
			}
		}
	}
	pthread_exit(0);
}
Example #12
0
void play_client(config cfg) {
    //time of the last step that occured. in ticks.
    int ok;               //signal we're waiting for before begining
    char c;               //key that is pressed
    int ret;              //value returned by 'read(0)', 0 if no new key was pressed
    int ret_serv;
    queue p1_queue = new_queue(MAX_INPUT_STACK);    //queue used to stack player input
    direction cur_dir;
    direction* players_dir = malloc(cfg.nb_players*sizeof(direction));

    //let's wait for server's signal
    ret_serv = read(sockfd, &ok, 1*sizeof(int));
    if(ret_serv < 0){
        perror("handle_server read waiting for signal");
    }
    else if(ret_serv == 0){
        printf("Server on socket %i closed connection.\n", sockfd); clear(); safe_quit(1);
    }

    if(ok != 1){
        printf("Wrong signal recieved from server. Received %i.\n", ok); safe_quit(1);
    }
    printf("Signal received. Starting now\n");
    //sleep(3);

    //GO
    clear();
    mode_raw(1);

    //creating field
    field* map = new_field(WIDTH, HEIGHT);

    //creating snakes
    int i;
    snake** snakes = malloc(cfg.nb_players*sizeof(snake*));
    for(i = 0; i < cfg.nb_players; i++){
        snakes[i] = new_snake(T_SNAKE, cfg.size, i, map);
    }

    fflush(stdout);

    struct timeval last_step_time;
    gettimeofday(&last_step_time, NULL);
    struct timeval now;
    int elapsed_time;       //elapsed time
    while(1){
        //SUMMARY
        //1 - let's check if it's time to retrieve input
        //2 - let's retrieve and sort every input
        //3 - let's send the server our direction
        //4 - let's wait for server's directions
        //5 - let's make snakes move
        //6 - let's update last_step_time
        //--------------------------------------

        //1 - let's check if it's time to retrieve input
        gettimeofday(&now, NULL);
        elapsed_time = diff_time(now, last_step_time); //time elapsed since last round. in ms.
        if(elapsed_time > TIME_STEP - PING){
            //2 - let's retrieve and sort every input
            while((ret = read(0, &c, sizeof(char))) != 0){
                if(ret == -1){
                    perror("read in 'play()'"); safe_quit(1);
                }

                if(c == C_QUIT){
                    mode_raw(0);
                    clear();
                    free_queue(&p1_queue);
                    free_all_client(map, snakes, cfg.nb_players);
                    return;
                }
                else if(key_is_p1_dir(c)){
                    //if the key is a move key for player 1:
                    if(! queue_full(&p1_queue)){
                        enqueue(&p1_queue, key_to_dir(c));
                    }
                }
                else{
                    //key pressed was a useless key. Do nothing.
                }
            }

            //3 - let's send the server our direction
            cur_dir = (! queue_empty(&p1_queue)) ? dequeue(&p1_queue) : snakes[cfg.id]->dir;
            cur_dir = (cur_dir == opposite(snakes[cfg.id]->dir)) ? snakes[cfg.id]->dir : cur_dir;
            if(write(sockfd, &cur_dir, 1*sizeof(direction)) < 0){
                perror("handle_server write"); safe_quit(1);
            }
            switch(cur_dir){
                case 0:
                    write(2, "sent 0\n", 7*sizeof(char));
                    break;
                case 1:
                    write(2, "sent 1\n", 7*sizeof(char));
                    break;
                case 2:
                    write(2, "sent 2\n", 7*sizeof(char));
                    break;
                case 3:
                    write(2, "sent 3\n", 7*sizeof(char));
                    break;
            }

            //4 - let's wait for server's directions
            ret_serv = read(sockfd, players_dir, cfg.nb_players*sizeof(direction));
            if(ret_serv == -1){
                perror("handle_server read"); safe_quit(1);
            }
            else if(ret_serv == 0){
                clear(); printf("Server closed connection.\n"); safe_quit(1);
            }

            //5 - let's make snakes move
            for(i = 0; i<cfg.nb_players; i++){
                if(players_dir[i] != 4){       //if the player is not dead (dir = 4 => dead player)
                    move(snakes[i], players_dir[i], map);
                }
            }
            fflush(stdout);

            //6 - let's update last_step_time
            gettimeofday(&last_step_time, NULL);
        }
        else{
            //sleep 90% of the remaining time
            usleep( (((TIME_STEP - PING) - elapsed_time) * 0.9) * 1000);
        }
    }
}
Example #13
0
int main() {
  const int max_entries = 5; /* size of the queue */

  /* define some variables to hold Foo structs*/
  Foo* new_foo1;
  Foo* new_foo2; 
  Foo* new_foo3;
  Foo* new_foo4;
  Foo* new_foo5;
  Foo* new_foo6;
  Foo* returned_foo;

  /* create a Queue struct with max_entries size */
  Queue *new_queue = create_queue(max_entries);

  /* show pointer addresses to demonstrate wrap around */
  printf("\nWrap around demonstration before Queue is modified:");
  printf("\nBuffer: %p\n", new_queue);
  printf("Head: %p\n", new_queue->queue_head);
  printf("Tail: %p\n\n", new_queue->queue_tail);


  /* allocate a Foo and add it onto the queue */
  new_foo1 = (Foo *) malloc(sizeof(Foo));
  new_foo1->x = 6;
  new_foo1->y = 14.79;
  printf("Adding: x = %5d, y = %10.3f\n", new_foo1->x, new_foo1->y);
  enqueue(new_queue, (void *) new_foo1);

  /* allocate a Foo and add it onto the queue */
  new_foo2 = (Foo *) malloc(sizeof(Foo));
  new_foo2->x = 217;
  new_foo2->y = 3.14159;
  printf("Adding: x = %5d, y = %10.3f\n", new_foo2->x, new_foo2->y);
  enqueue(new_queue, (void *) new_foo2);;

  /* allocate a Foo and add it onto the queue */
  new_foo3 = (Foo *) malloc(sizeof(Foo));
  new_foo3->x = 500;
  new_foo3->y = 4.50483;
  printf("Adding: x = %5d, y = %10.3f\n", new_foo3->x, new_foo3->y);
  enqueue(new_queue, (void *) new_foo3);

  /* allocate a Foo and add it onto the queue */
  new_foo4 = (Foo *) malloc(sizeof(Foo));
  new_foo4->x = 4059;
  new_foo4->y = 22.48300;
  printf("Adding: x = %5d, y = %10.3f\n", new_foo4->x, new_foo4->y);
  enqueue(new_queue, (void *) new_foo4);

  /* allocate a Foo and add it onto the queue */
  new_foo5 = (Foo *) malloc(sizeof(Foo));
  new_foo5->x = 1010;
  new_foo5->y = 1056.3827;
  printf("Adding: x = %5d, y = %10.3f\n", new_foo5->x, new_foo5->y);
  enqueue(new_queue, (void *) new_foo5);

  /* show pointer addresses to demonstrate wrap around */
  printf("\nWrap around demonstration after max entries are added:");
  printf("\nBuffer: %p\n", new_queue);
  printf("Head: %p\n", new_queue->queue_head);
  printf("Tail: %p\n\n", new_queue->queue_tail);
  
  /* attempt to add more than max number of entries onto the queue */
  new_foo6 = (Foo *) malloc(sizeof(Foo));
  new_foo6->x = 666;
  new_foo6->y = 66.666666;
  printf("Attempting to add more than max # of entries to the queue.\n");
  printf("Last entry is not added to queue!\n");
  printf("Adding: x = %5d, y = %10.3f\n", new_foo6->x, new_foo6->y);
  enqueue(new_queue, (void *) new_foo6);

  /* remove entries from the queue and print them */
  returned_foo = (Foo *) dequeue(new_queue);
  printf("Removed:  x = %5d, y = %10.3f\n", returned_foo->x, returned_foo->y);
  returned_foo = (Foo *) dequeue(new_queue);
  printf("Removed:  x = %5d, y = %10.3f\n", returned_foo->x, returned_foo->y);
  returned_foo = (Foo *) dequeue(new_queue);
  printf("Removed:  x = %5d, y = %10.3f\n", returned_foo->x, returned_foo->y);
  returned_foo = (Foo *) dequeue(new_queue);
  printf("Removed:  x = %5d, y = %10.3f\n", returned_foo->x, returned_foo->y);
  returned_foo = (Foo *) dequeue(new_queue);
  printf("Removed:  x = %5d, y = %10.3f\n", returned_foo->x, returned_foo->y);

  /* show pointer addresses to demonstrate wrap around */
  printf("\nWrap around demonstration after entries are removed:");
  printf("\nBuffer: %p\n", new_queue);
  printf("Head: %p\n", new_queue->queue_head);
  printf("Tail: %p\n\n", new_queue->queue_tail);

  /* attempt to remove non-existant element from queue */
  returned_foo = (Foo *) dequeue(new_queue);
  /* check for removing  more elements than exist in the queue */
  if(returned_foo != NULL) {
    printf("Removed:  x = %5d, y = %10.3f\n", returned_foo->x, returned_foo->y);
  } else {
    printf("\nError. Trying to remove nonexistant entry from queue!\n");
  } /* end else */
  

  /* free any allocated memory and clean up */
  delete_queue(new_queue);
  free(new_foo1);
  free(new_foo2);
  free(new_foo3);
  free(new_foo4);
  free(new_foo5);
  free(new_foo6);

  return 0; /* success */
} /* end function main */
Example #14
0
//This function was not implemented in class so I just took everything out of the queue one at a time until nothing was left
void Heap::clear(){
	while(count != 0)
		dequeue();
}
Example #15
0
void *cgroupService(void *arg)
{
	int res	= FUNC_RETURN_OK;

	gp_set_thread_sigmasks();

	res = CleanUpCGroupAtStartup("cpu");
	if (res != FUNC_RETURN_OK)
	{
		write_log("%s Function CleanUpCGroupAtStartup failed, "
				  "cgroupService thread will quit",
				  ENFORCER_MESSAGE_HEAD);
		return NULL;
	}

	g_ghash_cgroup = createGHash(GHASH_SLOT_VOLUME_DEFAULT,
								 GHASH_SLOT_VOLUME_DEFAULT_MAX,
								 GHASH_KEYTYPE_SIMPSTR,
								 NULL);
	if (g_ghash_cgroup == NULL)
	{
		write_log("%s Function createGHash failed with out of memory, "
				  "cgroupService thread will quit",
				  ENFORCER_MESSAGE_HEAD);
		return NULL;
	}

    while (true)
    {
    	/* Timeout in 1 second (1000 ms) */
    	ResourceEnforcementRequest *task = NULL;
		task = (ResourceEnforcementRequest *)dequeue(g_queue_cgroup, 1*1000);

    	if (!task)
    	{
			CleanUpCGroupAtRuntime();
			continue;
    	}

    	if (task->type == MOVETO)
    	{
    		res = MoveToCGroup(task->pid, task->cgroup_name);

    		if (res != FUNC_RETURN_OK)
    		{
    			write_log("%s Move PID %d to CGroup %s failed with error %d",
    					  ENFORCER_MESSAGE_HEAD,
    					  task->pid,
    					  task->cgroup_name,
    					  res);
    			free(task);
    			break;
    		}
    	}
    	else if (task->type == MOVEOUT)
    	{
    		res = MoveOutCGroup(task->pid, task->cgroup_name);

    		if (res != FUNC_RETURN_OK)
			{
				write_log("%s Move PID %d out from CGroup %s failed with error %d",
						  ENFORCER_MESSAGE_HEAD,
						  task->pid,
						  task->cgroup_name,
						  res);
				free(task);
				break;
			}
    	}
    	else if (task->type == SETWEIGHT)
    	{
    		res = SetupWeightCGroup(task->pid, task->cgroup_name, &(task->query_resource));

    		if (res != FUNC_RETURN_OK)
			{
				write_log("%s Set weight %lf for CGroup %s failed with error %d",
						  ENFORCER_MESSAGE_HEAD,
						  task->query_resource.vcore,
						  task->cgroup_name,
						  res);
				free(task);
				break;
			}
    	}
    	else
    	{
    		write_log("%s WARNING :: invalid CGroup task type",
					  ENFORCER_MESSAGE_HEAD);
    		free(task);
    		break;
    	}

    	free(task);

    	CleanUpCGroupAtRuntime();
    }

	write_log("%s Worker thread will quit", ENFORCER_MESSAGE_HEAD);

	g_enforcement_thread_quited = true;

    return NULL;
}
Example #16
0
int
pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
{
  pthread_descr torestart;
  pthread_descr th;

  __pthread_lock (&rwlock->__rw_lock, NULL);
  if (rwlock->__rw_writer != NULL)
    {
      /* Unlocking a write lock.  */
      if (rwlock->__rw_writer != thread_self ())
	{
	  __pthread_unlock (&rwlock->__rw_lock);
	  return EPERM;
	}
      rwlock->__rw_writer = NULL;

      if (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP
	  || (th = dequeue (&rwlock->__rw_write_waiting)) == NULL)
	{
	  /* Restart all waiting readers.  */
	  torestart = rwlock->__rw_read_waiting;
	  rwlock->__rw_read_waiting = NULL;
	  __pthread_unlock (&rwlock->__rw_lock);
	  while ((th = dequeue (&torestart)) != NULL)
	    restart (th);
	}
      else
	{
	  /* Restart one waiting writer.  */
	  __pthread_unlock (&rwlock->__rw_lock);
	  restart (th);
	}
    }
  else
    {
      /* Unlocking a read lock.  */
      if (rwlock->__rw_readers == 0)
	{
	  __pthread_unlock (&rwlock->__rw_lock);
	  return EPERM;
	}

      --rwlock->__rw_readers;
      if (rwlock->__rw_readers == 0)
	/* Restart one waiting writer, if any.  */
	th = dequeue (&rwlock->__rw_write_waiting);
      else
	th = NULL;

      __pthread_unlock (&rwlock->__rw_lock);
      if (th != NULL)
	restart (th);

      /* Recursive lock fixup */

      if (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_WRITER_NP)
	{
	  pthread_descr self = thread_self();
	  pthread_readlock_info *victim = rwlock_remove_from_list(self, rwlock);

	  if (victim != NULL)
	    {
	      if (victim->pr_lock_count == 0)
		{
		  victim->pr_next = self->p_readlock_free;
		  self->p_readlock_free = victim;
		}
	    }
	  else
	    {
	      if (self->p_untracked_readlock_count > 0)
		self->p_untracked_readlock_count--;
	    }
	}
    }

  return 0;
}
Example #17
0
uint32_t ir_sensor_get_raw_data()
{
    return dequeue(IR_QUEUE, uint32_t);
}
/** @brief Releases buffers under processing.
 * This function must be implemented in the derived classes, for the
 * specific processing
 */
OMX_ERRORTYPE camera_video_port_FlushProcessingBuffers(omx_base_PortType *openmaxStandPort)
{
    omx_base_component_PrivateType *omx_base_component_Private;
    OMX_BUFFERHEADERTYPE *pBuffer;
    int errQue;
    omx_base_camera_video_PortType *omx_base_video_Port;
    int nPrePare_Num = 0;

    OMXDBUG(OMXDBUG_VERB, "In %s for port %p\n", __func__, openmaxStandPort);
    omx_base_component_Private = (omx_base_component_PrivateType *)openmaxStandPort->standCompContainer->pComponentPrivate;
    omx_base_video_Port = (omx_base_camera_video_PortType *)openmaxStandPort;

    if(openmaxStandPort->sPortParam.eDomain != OMX_PortDomainOther) /* clock buffers not used in the clients buffer managment function */
    {
        pthread_mutex_lock(&omx_base_component_Private->flush_mutex);
        openmaxStandPort->bIsPortFlushed = OMX_TRUE;

        /*Signal the buffer management thread of port flush,if it is waiting for buffers*/
        if(omx_base_component_Private->bMgmtSem->semval == 0)
        {
            tsem_up(omx_base_component_Private->bMgmtSem);
        }

        if(omx_base_component_Private->state != OMX_StateExecuting)
        {
            /*Waiting at paused state*/
            tsem_signal(omx_base_component_Private->bStateSem);
        }

        OMXDBUG(OMXDBUG_VERB, "In %s waiting for flush all condition port index =%d\n", __func__, (int)openmaxStandPort->sPortParam.nPortIndex);
        /* Wait until flush is completed */
        pthread_mutex_unlock(&omx_base_component_Private->flush_mutex);
        tsem_down(omx_base_component_Private->flush_all_condition);
    }

    OMXDBUG(OMXDBUG_VERB, "In %s flushed all the buffers under processing\n", __func__);

    tsem_reset(omx_base_component_Private->bMgmtSem);

    /* Flush all the buffers not under processing */
    while(openmaxStandPort->pBufferSem->semval > 0)
    {
        OMXDBUG(OMXDBUG_VERB, "In %s TFlag=%x Flusing Port=%d,Semval=%d Qelem=%d\n",
              __func__, (int)openmaxStandPort->nTunnelFlags, (int)openmaxStandPort->sPortParam.nPortIndex,
              (int)openmaxStandPort->pBufferSem->semval, (int)openmaxStandPort->pBufferQueue->nelem);

        tsem_down(openmaxStandPort->pBufferSem);
        pBuffer = dequeue(openmaxStandPort->pBufferQueue);

        if(PORT_IS_TUNNELED(openmaxStandPort) && !PORT_IS_BUFFER_SUPPLIER(openmaxStandPort))
        {
            OMXDBUG(OMXDBUG_VERB, "In %s: Comp %s is returning io:%d buffer\n",
                  __func__, omx_base_component_Private->name, (int)openmaxStandPort->sPortParam.nPortIndex);

            if(openmaxStandPort->sPortParam.eDir == OMX_DirInput)
            {
                ((OMX_COMPONENTTYPE *)(openmaxStandPort->hTunneledComponent))->FillThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
            }
            else
            {
                ((OMX_COMPONENTTYPE *)(openmaxStandPort->hTunneledComponent))->EmptyThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
            }
        }
        else if(PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort))
        {
            errQue = queue(openmaxStandPort->pBufferQueue, pBuffer);

            if(errQue)
            {
                /* /TODO the queue is full. This can be handled in a fine way with
                 * some retrials, or other checking. For the moment this is a critical error
                 * and simply causes the failure of this call
                 */
                return OMX_ErrorInsufficientResources;
            }
        }
        else
        {
            (*(openmaxStandPort->BufferProcessedCallback))(
                openmaxStandPort->standCompContainer,
                omx_base_component_Private->callbackData,
                pBuffer);
        }
    }

    /*Port is tunneled and supplier and didn't received all it's buffer then wait for the buffers*/
    if(PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort))
    {
        while(openmaxStandPort->pBufferQueue->nelem != openmaxStandPort->nNumAssignedBuffers)
        {
            tsem_down(openmaxStandPort->pBufferSem);
            OMXDBUG(OMXDBUG_VERB, "In %s Got a buffer qelem=%d\n", __func__, openmaxStandPort->pBufferQueue->nelem);
        }

        tsem_reset(openmaxStandPort->pBufferSem);
    }

    nPrePare_Num = getquenelem(omx_base_video_Port->queue_dq);

    while(nPrePare_Num > 0)
    {
        pBuffer = dequeue(omx_base_video_Port->queue_dq);
        pBuffer = NULL;
        nPrePare_Num = getquenelem(omx_base_video_Port->queue_dq);
    }

    pthread_mutex_lock(&omx_base_component_Private->flush_mutex);
    openmaxStandPort->bIsPortFlushed = OMX_FALSE;
    pthread_mutex_unlock(&omx_base_component_Private->flush_mutex);

    tsem_up(omx_base_component_Private->flush_condition);

    OMXDBUG(OMXDBUG_VERB, "Out %s Port Index=%d bIsPortFlushed=%d Component %s\n", __func__,
          (int)openmaxStandPort->sPortParam.nPortIndex, (int)openmaxStandPort->bIsPortFlushed, omx_base_component_Private->name);

    OMXDBUG(OMXDBUG_VERB, "In %s TFlag=%x Qelem=%d BSem=%d bMgmtsem=%d component=%s\n", __func__,
          (int)openmaxStandPort->nTunnelFlags,
          (int)openmaxStandPort->pBufferQueue->nelem,
          (int)openmaxStandPort->pBufferSem->semval,
          (int)omx_base_component_Private->bMgmtSem->semval,
          omx_base_component_Private->name);

    OMXDBUG(OMXDBUG_VERB, "Out %s Port %p Index=%d\n", __func__, openmaxStandPort, (int)openmaxStandPort->sPortParam.nPortIndex);
    return OMX_ErrorNone;
}
Example #19
0
int main(int argc, char *argv[])
{
	char *filename;
	int task_index, speed, delay, filesize;
	int i, fd, timeout, res, COUNT;
	int bdp, window, FRAME_SIZE;
	char read_buffer[MSGSIZE];
	struct stat f_status;

	task_index = atoi(argv[1]);
	filename = argv[2];
	speed = atoi(argv[3]);
	delay = atoi(argv[4]);
	
	printf("[SENDER] Sender starts.\n");
	printf("[SENDER] Filename=%s, task_index=%d, speed=%d, delay=%d\n", filename, task_index, speed, delay);

	/* miliseconds for delay & megabits for speed */
	bdp = speed * delay * 1000;
	printf("[SENDER] BDP = %d b(bits).\n", bdp);

	fd = open(filename, O_RDONLY);
	fstat(fd, &f_status);

	filesize = (int) f_status.st_size;
	printf("[SENDER] File size: %d\n", filesize);

	/* miliseconds for timeout */
	if(2*delay > 1000)
		timeout = 2*delay;
	else
		timeout = 1000;
	printf("[SENDER] timeout = %d\n", timeout);	

	init(HOST, PORT1);

	if(task_index == 0 || task_index == 1) {

		msg t;
		my_pkt p;
		int SCAN, bsize;
		queue *buffer;
		buffer = (queue *) malloc(sizeof(queue));
		create_queue(buffer, sizeof(msg));
		FRAME_SIZE = MSGSIZE + 4;

		printf("[SENDER] Each frame has %d B(bytes).\n", FRAME_SIZE);
		COUNT = filesize / FRAME_SIZE;
		printf("[SENDER] Gonna send %d frames.\n", COUNT);
		/* window = number of frames in the 'network', unacked */
		window = bdp / (FRAME_SIZE * BITS_NO);
		printf("[SENDER] window = %d frames\n", window);

		/* Len in message 
			= size(msg payload)
			= amount of data in the my_pkt structure
			= size(type) + data in (pkt payload)
			= sizeof(int) + number of used bytes in (pkt payload)
		*/

		/* Gonna send filename - SEQ = -2 message */
		memset(t.payload, 0, sizeof(t.payload));
		memset(p.payload, 0, sizeof(p.payload));
	
		p.SEQ = -2;	
		memcpy(p.payload, filename, strlen(filename));
		t.len = sizeof(int) + strlen(filename) + 1;
		memcpy(t.payload, &p, t.len); 
		while(1) {
			/* send msg */
			while(1) {
				res = send_message(&t);
				if (res < 0) {
					perror("[SENDER] Send error. Resending");
					continue;
				}
				break;
			}
			printf("[SENDER] Filename sent.\n");

			/* Wait for filename ACK */	
			if (recv_message_timeout(&t, timeout) < 0) {
				perror("[SENDER] Receive error: TIMEOUT. Resending");
				continue;
			}
			p = *((my_pkt *) t.payload);
			if (p.SEQ != -2) {
				perror("[SENDER] Receive error: WRONG ACK. Resending");
				continue;
			}
			printf("[SENDER] Got reply with ACK: %d (Filename)\n", p.SEQ);
			break;
		}

		/* Gonna send filesize - SEQ = -1 message */
		memset(t.payload, 0, sizeof(t.payload));
		memset(p.payload, 0, sizeof(p.payload));
	
		p.SEQ = -1;
		memcpy(p.payload, &filesize, sizeof(int));
		t.len = sizeof(int) * 2;
		memcpy(t.payload, &p, t.len);
		while(1) {
			/* send msg */
			while(1) {
				res = send_message(&t);
				if (res < 0) {
					perror("[SENDER] Send error. Resending");
					continue;
				}
				break;
			}
			printf("[SENDER] Filesize sent.\n");
	
			/* Wait for filesize ACK */	
			if (recv_message_timeout(&t, timeout) < 0) {
				perror("[SENDER] Receive error: TIMEOUT. Resending");
				continue;
			}
	
			p = *((my_pkt *) t.payload);
			if (p.SEQ != -1) {
				perror("[SENDER] Receive error: WRONG ACK. Resending");
				continue;
			}
			printf("[SENDER] Got reply with ACK: %d (Filesize)\n", p.SEQ);
			break;
		}

		/* Send file contents - (SEQ = 0 -> COUNT) messages */
		int seq = 0;
		/* Fill the link = send window messages */
		for (i = 0; i < window; i++) {
			if((SCAN = read(fd, read_buffer, MSGSIZE - sizeof(int))) > 0) {
				memset(t.payload, 0, sizeof(t.payload));
				memset(p.payload, 0, sizeof(p.payload));
	
				p.SEQ = seq;
				memcpy(p.payload, read_buffer, SCAN);
				t.len = sizeof(int) + SCAN;
				memcpy(t.payload, &p, t.len);
				printf("[SENDER] Sending message with SEQ: %d\n", seq);

				/* put msg in buffer */
				enqueue(buffer, &t);

				/* send msg */
				while(1) {
					res = send_message(&t);
					if (res < 0) {
						perror("[SENDER] Send error. Resending");
						continue;
					}
					break;
				}
				seq++;
			}
			else
				break;
		}

		/* From now on, ack clocking, i.e., a new ack will inform 
		   us about the space released in the link */
		while(1) {
			/* wait for ACK */
			if (recv_message_timeout(&t, timeout) < 0) {
				perror("[SENDER] Receive error: TIMEOUT. Resending buffer");
				bsize = buffer->size;
				while(bsize) {
					/* clear msg from buffer */
					dequeue(buffer, &t);

					/* send msg */
					while(1) {
						res = send_message(&t);
						if (res < 0) {
							perror("[SENDER] Send error. Resending");
							continue;
						}
						break;
					}

					/* reput msg in buffer, in case it will be lost again */
					enqueue(buffer, &t);
					bsize--;				
				}
				continue;
			}
			else {
				p = *((my_pkt *) t.payload);
				printf("[SENDER] Got reply with ACK: %d\n", p.SEQ);

				/* clear succesfully sent msg from buffer */
				dequeue(buffer, &t);

				if((SCAN = read(fd, read_buffer, MSGSIZE - sizeof(int))) > 0) {
					memset(t.payload, 0, sizeof(t.payload));
					memset(p.payload, 0, sizeof(p.payload));
		
					p.SEQ = seq;
					memcpy(p.payload, read_buffer, SCAN);
					t.len = sizeof(int) + SCAN;
					memcpy(t.payload, &p, t.len);
					printf("[SENDER] Sending message with SEQ: %d\n", seq);

					/* put msg in buffer */
					enqueue(buffer, &t);

					/* send msg */
					while(1) {
						res = send_message(&t);
						if (res < 0) {
							perror("[SENDER] Send error. Resending");
							continue;
						}
						break;
					}
					seq++;
				}
				else
					if(buffer->size == 0)
						break;
			}
		}

		destroy_queue(buffer);
		free(buffer);
	}
	
	printf("[SERVER] File transfer has ended.\n");

	close(fd);
	
	return 0;
}
Example #20
0
void mt_task_queue::spawn_worker() {
    lean_always_assert(!m_shutting_down);
    auto this_worker = std::make_shared<worker_info>();
    m_workers.push_back(this_worker);
    m_required_workers--;
    this_worker->m_thread.reset(new lthread([this, this_worker]() {
        save_stack_info(false);

        unique_lock<mutex> lock(m_mutex);
        while (true) {
            if (m_shutting_down) {
                break;
            }
            if (m_required_workers < 0) {
                scoped_add<int> inc_required(m_required_workers, +1);
                scoped_add<unsigned> inc_sleeping(m_sleeping_workers, +1);
                if (m_wake_up_worker.wait_for(lock, g_worker_max_idle_time,
                                              [&] { return m_required_workers >= 1 || m_shutting_down; })) {
                    continue;
                } else {
                    break;
                }
            }
            if (m_queue.empty()) {
                if (m_queue_added.wait_for(lock, g_worker_max_idle_time,
                                           [&] { return !m_queue.empty() || m_shutting_down; })) {
                    continue;
                } else {
                    break;
                }
            }

            auto t = dequeue();
            if (get_state(t).load() != task_state::Queued) continue;

            get_state(t) = task_state::Running;
            reset_heartbeat();
            {
                flet<gtask> _(this_worker->m_current_task, t);
                scoped_current_task scope_cur_task(&t);
                notify_queue_changed();
                lock.unlock();
                execute(t);
                lock.lock();
            }
            reset_heartbeat();

            handle_finished(t);

            notify_queue_changed();
        }

        // We need to run the finalizers while the lock is held,
        // otherwise we risk a race condition at the end of the program.
        // We would finalize in the thread, while we call the finalize() function.
        run_thread_finalizers();
        run_post_thread_finalizers();

        m_workers.erase(std::find(m_workers.begin(), m_workers.end(), this_worker));
        m_required_workers++;
        m_shut_down_cv.notify_all();
    }));
}
Example #21
0
	/**
	 * pops the next item from the top of the queue
	 *
	 * @param t assigned to the item at the top of the queue, if it is not empty
	 *
	 * @return true if an item was retrieved, false if the queue is empty
	 */
	inline bool pop(T& t) { boost::uint32_t version; return dequeue(t, version); }
Example #22
0
/*
 * generic single channel send/recv
 * if the bool pointer is nil,
 * then the full exchange will
 * occur. if pres is not nil,
 * then the protocol will not
 * sleep but return if it could
 * not complete.
 *
 * sleep can wake up with g->param == nil
 * when a channel involved in the sleep has
 * been closed.  it is easiest to loop and re-run
 * the operation; we'll see that it's now closed.
 */
void
runtime·chansend(ChanType *t, Hchan *c, byte *ep, bool *pres, void *pc)
{
	SudoG *sg;
	SudoG mysg;
	G* gp;
	int64 t0;

	if(c == nil) {
		USED(t);
		if(pres != nil) {
			*pres = false;
			return;
		}
		runtime·park(nil, nil, "chan send (nil chan)");
		return;  // not reached
	}

	if(runtime·gcwaiting)
		runtime·gosched();

	if(debug) {
		runtime·printf("chansend: chan=%p; elem=", c);
		c->elemalg->print(c->elemsize, ep);
		runtime·prints("\n");
	}

	t0 = 0;
	mysg.releasetime = 0;
	if(runtime·blockprofilerate > 0) {
		t0 = runtime·cputicks();
		mysg.releasetime = -1;
	}

	runtime·lock(c);
	// TODO(dvyukov): add similar instrumentation to select.
	if(raceenabled)
		runtime·racereadpc(c, pc, runtime·chansend);
	if(c->closed)
		goto closed;

	if(c->dataqsiz > 0)
		goto asynch;

	sg = dequeue(&c->recvq);
	if(sg != nil) {
		if(raceenabled)
			racesync(c, sg);
		runtime·unlock(c);

		gp = sg->g;
		gp->param = sg;
		if(sg->elem != nil)
			c->elemalg->copy(c->elemsize, sg->elem, ep);
		if(sg->releasetime)
			sg->releasetime = runtime·cputicks();
		runtime·ready(gp);

		if(pres != nil)
			*pres = true;
		return;
	}

	if(pres != nil) {
		runtime·unlock(c);
		*pres = false;
		return;
	}

	mysg.elem = ep;
	mysg.g = g;
	mysg.selgen = NOSELGEN;
	g->param = nil;
	enqueue(&c->sendq, &mysg);
	runtime·park(runtime·unlock, c, "chan send");

	if(g->param == nil) {
		runtime·lock(c);
		if(!c->closed)
			runtime·throw("chansend: spurious wakeup");
		goto closed;
	}

	if(mysg.releasetime > 0)
		runtime·blockevent(mysg.releasetime - t0, 2);

	return;

asynch:
	if(c->closed)
		goto closed;

	if(c->qcount >= c->dataqsiz) {
		if(pres != nil) {
			runtime·unlock(c);
			*pres = false;
			return;
		}
		mysg.g = g;
		mysg.elem = nil;
		mysg.selgen = NOSELGEN;
		enqueue(&c->sendq, &mysg);
		runtime·park(runtime·unlock, c, "chan send");

		runtime·lock(c);
		goto asynch;
	}

	if(raceenabled)
		runtime·racerelease(chanbuf(c, c->sendx));

	c->elemalg->copy(c->elemsize, chanbuf(c, c->sendx), ep);
	if(++c->sendx == c->dataqsiz)
		c->sendx = 0;
	c->qcount++;

	sg = dequeue(&c->recvq);
	if(sg != nil) {
		gp = sg->g;
		runtime·unlock(c);
		if(sg->releasetime)
			sg->releasetime = runtime·cputicks();
		runtime·ready(gp);
	} else
		runtime·unlock(c);
	if(pres != nil)
		*pres = true;
	if(mysg.releasetime > 0)
		runtime·blockevent(mysg.releasetime - t0, 2);
	return;

closed:
	runtime·unlock(c);
	runtime·panicstring("send on closed channel");
}
Example #23
0
int scheduler()
{
    if (running->status == READY)     // if running is still READY
        enqueue(&readyQueue, running); // enter it into readyQueue
    running = dequeue(&readyQueue);   // new running
}
Example #24
0
void
runtime·chanrecv(ChanType *t, Hchan* c, byte *ep, bool *selected, bool *received)
{
	SudoG *sg;
	SudoG mysg;
	G *gp;
	int64 t0;

	if(runtime·gcwaiting)
		runtime·gosched();

	if(debug)
		runtime·printf("chanrecv: chan=%p\n", c);

	if(c == nil) {
		USED(t);
		if(selected != nil) {
			*selected = false;
			return;
		}
		runtime·park(nil, nil, "chan receive (nil chan)");
		return;  // not reached
	}

	t0 = 0;
	mysg.releasetime = 0;
	if(runtime·blockprofilerate > 0) {
		t0 = runtime·cputicks();
		mysg.releasetime = -1;
	}

	runtime·lock(c);
	if(c->dataqsiz > 0)
		goto asynch;

	if(c->closed)
		goto closed;

	sg = dequeue(&c->sendq);
	if(sg != nil) {
		if(raceenabled)
			racesync(c, sg);
		runtime·unlock(c);

		if(ep != nil)
			c->elemalg->copy(c->elemsize, ep, sg->elem);
		gp = sg->g;
		gp->param = sg;
		if(sg->releasetime)
			sg->releasetime = runtime·cputicks();
		runtime·ready(gp);

		if(selected != nil)
			*selected = true;
		if(received != nil)
			*received = true;
		return;
	}

	if(selected != nil) {
		runtime·unlock(c);
		*selected = false;
		return;
	}

	mysg.elem = ep;
	mysg.g = g;
	mysg.selgen = NOSELGEN;
	g->param = nil;
	enqueue(&c->recvq, &mysg);
	runtime·park(runtime·unlock, c, "chan receive");

	if(g->param == nil) {
		runtime·lock(c);
		if(!c->closed)
			runtime·throw("chanrecv: spurious wakeup");
		goto closed;
	}

	if(received != nil)
		*received = true;
	if(mysg.releasetime > 0)
		runtime·blockevent(mysg.releasetime - t0, 2);
	return;

asynch:
	if(c->qcount <= 0) {
		if(c->closed)
			goto closed;

		if(selected != nil) {
			runtime·unlock(c);
			*selected = false;
			if(received != nil)
				*received = false;
			return;
		}
		mysg.g = g;
		mysg.elem = nil;
		mysg.selgen = NOSELGEN;
		enqueue(&c->recvq, &mysg);
		runtime·park(runtime·unlock, c, "chan receive");

		runtime·lock(c);
		goto asynch;
	}

	if(raceenabled)
		runtime·raceacquire(chanbuf(c, c->recvx));

	if(ep != nil)
		c->elemalg->copy(c->elemsize, ep, chanbuf(c, c->recvx));
	c->elemalg->copy(c->elemsize, chanbuf(c, c->recvx), nil);
	if(++c->recvx == c->dataqsiz)
		c->recvx = 0;
	c->qcount--;

	sg = dequeue(&c->sendq);
	if(sg != nil) {
		gp = sg->g;
		runtime·unlock(c);
		if(sg->releasetime)
			sg->releasetime = runtime·cputicks();
		runtime·ready(gp);
	} else
		runtime·unlock(c);

	if(selected != nil)
		*selected = true;
	if(received != nil)
		*received = true;
	if(mysg.releasetime > 0)
		runtime·blockevent(mysg.releasetime - t0, 2);
	return;

closed:
	if(ep != nil)
		c->elemalg->copy(c->elemsize, ep, nil);
	if(selected != nil)
		*selected = true;
	if(received != nil)
		*received = false;
	if(raceenabled)
		runtime·raceacquire(c);
	runtime·unlock(c);
	if(mysg.releasetime > 0)
		runtime·blockevent(mysg.releasetime - t0, 2);
}
void mm_one_queue_simulator_with_initail_bias(long nr_customer, double average_interarrival_time, double average_service_time, long *next_seed_interarrival, long *next_seed_service, struct mm_one_simulation_result *result, long initial_bias) {
  struct event *event_list = NULL;
  struct queue system_queue;
  enum server_state server_state = IDLE;
  double system_clock = 0.0;
  struct event *event;

  enum event_type event_type;
  int customer_number = 0;
  double clock_time;
  double arrival_time;
  double interarrival_time;
  double departure_time;
  double service_time;

  struct customer *customer;

  double lamda_interarrival_rate = 1.0 / average_interarrival_time; /* interarrival rate: lamda = 1 / average_time */
  double mu_service_rate = 1.0 / average_service_time; /* service_rate: mu = 1 / arverage_service_time */

  double total_customer_in_system_time = 0.0; 
  /* initial system */
  init_queue(&system_queue);

  /* step 0: initial first event and add into event list */
#ifdef DEBUG
  printf("Info: simulation starts.\n");
#endif
  if (customer_number < nr_customer) {
    event_type = ARRIVAL;
    clock_time = 1.0;
    customer = init_customer(customer_number);
    customer->arrival_time = clock_time;
    customer_number++;
    add_event(&event_list, event_type, clock_time, (void *) customer);
  }
  /* step 1: pop event from event list */
  event = get_event(event_list);
  while (event) {
    /* step 2: addvance clock */
    system_clock = event->clock_time;
    pop_event(&event_list);
    /* get customer */
    customer = (struct customer *) event->content;
    event->content = NULL;
    switch (event->event_type) {
      case ARRIVAL:
#ifdef DEBUG
        /* print info */
        printf("Info: [time: %12f] [customer: %8d] event: ARRIVAL\n", system_clock, customer->no);
#endif
        /* generate service time */
        service_time = exponential_random_generator(mu_service_rate, next_seed_service);
        add_service_time_to_customer(customer, service_time);
        /* step 3: update state */
        if (server_state == IDLE) {
          server_state = BUSY;
          /* set service time and departure time */
          service_time = customer->service_time;
          departure_time = system_clock + service_time;
          event_type = DEPARTURE;
          customer->departure_time = departure_time;
          add_event(&event_list, event_type, departure_time, (void *) customer);
        } else if (server_state == BUSY) {
          /* add customer into queue */
          enqueue(&system_queue, (void *) customer);
        }
        /* step 4: generate future event into event list */
        /* if customer_number < nr_customer, generate next arrival event */
        if (customer_number < nr_customer) {
          interarrival_time = exponential_random_generator(lamda_interarrival_rate, next_seed_interarrival);
          arrival_time = system_clock + interarrival_time;
          event_type = ARRIVAL;
          customer = init_customer(customer_number);
          customer->arrival_time = arrival_time;
          customer_number++;
          add_event(&event_list, event_type, arrival_time, (void *) customer);
        }
     
        break;
      case DEPARTURE:
#ifdef DEBUG
        /* print info */
        printf("Info: [time: %12f] --------------------------------------- [customer: %8d] event: DEPARTURE\n", system_clock, customer->no);
#endif
        /* store each customer's system time in result */
        if (result && result->customer_in_system_time) {
          result->customer_in_system_time[customer->no] = customer->departure_time - customer->arrival_time;
        }

        /* initial bias */
        if (customer->no >= initial_bias) {
          total_customer_in_system_time += customer->departure_time - customer->arrival_time;
        }

        free(customer);
        customer = NULL;
        /* step 3: update state */
        if (system_queue.count > 0) {
          customer = (struct customer *) dequeue(&system_queue);
          /* set service time and departure time */
          service_time = get_service_time_from_customer(customer);
          departure_time = system_clock + service_time;
          event_type = DEPARTURE;
          customer->departure_time = departure_time;
          add_event(&event_list, event_type, departure_time, (void *) customer);
        } else if (system_queue.count == 0) {
          server_state = IDLE;
        }

        /* step 4: generate future event into event list */
        break;
      default:
        fprintf(stderr, "Error: unkown event type.\n");
        exit(EXIT_FAILURE);
    }
    free(event);
    event = NULL;

    /* get next event */
    event = get_event(event_list);
  }
  if (result) {
    result->average_customer_in_system_time = total_customer_in_system_time / (nr_customer - initial_bias);
#ifdef DEBUG
    printf("Info: average time of a customer in system: %12f\n", result->average_customer_in_system_time);
#endif
  }
#ifdef DEBUG
  printf("Info: event list is empty.\n");
  printf("Info: simulation ends.\n");
#endif
}
Example #26
0
static void*
selectgo(Select **selp)
{
	Select *sel;
	uint32 o, i, j, k;
	Scase *cas, *dfl;
	Hchan *c;
	SudoG *sg;
	G *gp;
	byte *as;
	void *pc;

	sel = *selp;
	if(runtime·gcwaiting)
		runtime·gosched();

	if(debug)
		runtime·printf("select: sel=%p\n", sel);

	// The compiler rewrites selects that statically have
	// only 0 or 1 cases plus default into simpler constructs.
	// The only way we can end up with such small sel->ncase
	// values here is for a larger select in which most channels
	// have been nilled out.  The general code handles those
	// cases correctly, and they are rare enough not to bother
	// optimizing (and needing to test).

	// generate permuted order
	for(i=0; i<sel->ncase; i++)
		sel->pollorder[i] = i;
	for(i=1; i<sel->ncase; i++) {
		o = sel->pollorder[i];
		j = runtime·fastrand1()%(i+1);
		sel->pollorder[i] = sel->pollorder[j];
		sel->pollorder[j] = o;
	}

	// sort the cases by Hchan address to get the locking order.
	// simple heap sort, to guarantee n log n time and constant stack footprint.
	for(i=0; i<sel->ncase; i++) {
		j = i;
		c = sel->scase[j].chan;
		while(j > 0 && sel->lockorder[k=(j-1)/2] < c) {
			sel->lockorder[j] = sel->lockorder[k];
			j = k;
		}
		sel->lockorder[j] = c;
	}
	for(i=sel->ncase; i-->0; ) {
		c = sel->lockorder[i];
		sel->lockorder[i] = sel->lockorder[0];
		j = 0;
		for(;;) {
			k = j*2+1;
			if(k >= i)
				break;
			if(k+1 < i && sel->lockorder[k] < sel->lockorder[k+1])
				k++;
			if(c < sel->lockorder[k]) {
				sel->lockorder[j] = sel->lockorder[k];
				j = k;
				continue;
			}
			break;
		}
		sel->lockorder[j] = c;
	}
	/*
	for(i=0; i+1<sel->ncase; i++)
		if(sel->lockorder[i] > sel->lockorder[i+1]) {
			runtime·printf("i=%d %p %p\n", i, sel->lockorder[i], sel->lockorder[i+1]);
			runtime·throw("select: broken sort");
		}
	*/
	sellock(sel);

loop:
	// pass 1 - look for something already waiting
	dfl = nil;
	for(i=0; i<sel->ncase; i++) {
		o = sel->pollorder[i];
		cas = &sel->scase[o];
		c = cas->chan;

		switch(cas->kind) {
		case CaseRecv:
			if(c->dataqsiz > 0) {
				if(c->qcount > 0)
					goto asyncrecv;
			} else {
				sg = dequeue(&c->sendq);
				if(sg != nil)
					goto syncrecv;
			}
			if(c->closed)
				goto rclose;
			break;

		case CaseSend:
			if(c->closed)
				goto sclose;
			if(c->dataqsiz > 0) {
				if(c->qcount < c->dataqsiz)
					goto asyncsend;
			} else {
				sg = dequeue(&c->recvq);
				if(sg != nil)
					goto syncsend;
			}
			break;

		case CaseDefault:
			dfl = cas;
			break;
		}
	}

	if(dfl != nil) {
		selunlock(sel);
		cas = dfl;
		goto retc;
	}


	// pass 2 - enqueue on all chans
	for(i=0; i<sel->ncase; i++) {
		o = sel->pollorder[i];
		cas = &sel->scase[o];
		c = cas->chan;
		sg = &cas->sg;
		sg->g = g;
		sg->selgen = g->selgen;

		switch(cas->kind) {
		case CaseRecv:
			enqueue(&c->recvq, sg);
			break;

		case CaseSend:
			enqueue(&c->sendq, sg);
			break;
		}
	}

	g->param = nil;
	runtime·park((void(*)(Lock*))selunlock, (Lock*)sel, "select");

	sellock(sel);
	sg = g->param;

	// pass 3 - dequeue from unsuccessful chans
	// otherwise they stack up on quiet channels
	for(i=0; i<sel->ncase; i++) {
		cas = &sel->scase[i];
		if(cas != (Scase*)sg) {
			c = cas->chan;
			if(cas->kind == CaseSend)
				dequeueg(&c->sendq);
			else
				dequeueg(&c->recvq);
		}
	}

	if(sg == nil)
		goto loop;

	cas = (Scase*)sg;
	c = cas->chan;

	if(c->dataqsiz > 0)
		runtime·throw("selectgo: shouldn't happen");

	if(debug)
		runtime·printf("wait-return: sel=%p c=%p cas=%p kind=%d\n",
			sel, c, cas, cas->kind);

	if(cas->kind == CaseRecv) {
		if(cas->receivedp != nil)
			*cas->receivedp = true;
	}

	selunlock(sel);
	goto retc;

asyncrecv:
	// can receive from buffer
	if(raceenabled)
		runtime·raceacquire(chanbuf(c, c->recvx));
	if(cas->receivedp != nil)
		*cas->receivedp = true;
	if(cas->sg.elem != nil)
		c->elemalg->copy(c->elemsize, cas->sg.elem, chanbuf(c, c->recvx));
	c->elemalg->copy(c->elemsize, chanbuf(c, c->recvx), nil);
	if(++c->recvx == c->dataqsiz)
		c->recvx = 0;
	c->qcount--;
	sg = dequeue(&c->sendq);
	if(sg != nil) {
		gp = sg->g;
		selunlock(sel);
		runtime·ready(gp);
	} else {
		selunlock(sel);
	}
	goto retc;

asyncsend:
	// can send to buffer
	if(raceenabled)
		runtime·racerelease(chanbuf(c, c->sendx));
	c->elemalg->copy(c->elemsize, chanbuf(c, c->sendx), cas->sg.elem);
	if(++c->sendx == c->dataqsiz)
		c->sendx = 0;
	c->qcount++;
	sg = dequeue(&c->recvq);
	if(sg != nil) {
		gp = sg->g;
		selunlock(sel);
		runtime·ready(gp);
	} else {
		selunlock(sel);
	}
	goto retc;

syncrecv:
	// can receive from sleeping sender (sg)
	if(raceenabled)
		racesync(c, sg);
	selunlock(sel);
	if(debug)
		runtime·printf("syncrecv: sel=%p c=%p o=%d\n", sel, c, o);
	if(cas->receivedp != nil)
		*cas->receivedp = true;
	if(cas->sg.elem != nil)
		c->elemalg->copy(c->elemsize, cas->sg.elem, sg->elem);
	gp = sg->g;
	gp->param = sg;
	runtime·ready(gp);
	goto retc;

rclose:
	// read at end of closed channel
	selunlock(sel);
	if(cas->receivedp != nil)
		*cas->receivedp = false;
	if(cas->sg.elem != nil)
		c->elemalg->copy(c->elemsize, cas->sg.elem, nil);
	if(raceenabled)
		runtime·raceacquire(c);
	goto retc;

syncsend:
	// can send to sleeping receiver (sg)
	if(raceenabled)
		racesync(c, sg);
	selunlock(sel);
	if(debug)
		runtime·printf("syncsend: sel=%p c=%p o=%d\n", sel, c, o);
	if(sg->elem != nil)
		c->elemalg->copy(c->elemsize, sg->elem, cas->sg.elem);
	gp = sg->g;
	gp->param = sg;
	runtime·ready(gp);

retc:
	// return pc corresponding to chosen case.
	// Set boolean passed during select creation
	// (at offset selp + cas->so) to true.
	// If cas->so == 0, this is a reflect-driven select and we
	// don't need to update the boolean.
	pc = cas->pc;
	if(cas->so > 0) {
		as = (byte*)selp + cas->so;
		*as = true;
	}
	runtime·free(sel);
	return pc;

sclose:
	// send on closed channel
	selunlock(sel);
	runtime·panicstring("send on closed channel");
	return nil;  // not reached
}
Example #27
0
int main(void)
{	
    Queue *queueOne = NULL, *queueTwo = NULL;
    node *persOne = NULL, *persTwo = NULL, *persThree, *firstPersOut = NULL;
    int i;
    int stationOne = 0, stationTwo = 0, stationThree = 0;
    int totTime = 0;
  
    printf("\nAirport Security Checkpoint Simulator\n");
    printf("=====================================\n\n");

    queueOne = createQueue();
    queueTwo = createQueue();
    
    srand( (unsigned)time(NULL) );
    
    /*  Assign random values to each person in the queue, between 60 and 180 seconds  */
    for (i = 0 ; i < 1000 ; i++)
    {
        int num = 0;
        
        num = rand()%(180-60) + 60;
        enqueue(queueOne, num);
    }
    
    printf("Number of people in line: %d\n", getLength(queueOne));
    
    persOne = dequeue(queueOne); 
    stationOne = persOne->nodeValue;
    enqueue(queueTwo, persOne->nodeValue);

    persTwo = dequeue(queueOne);
    stationTwo = persTwo->nodeValue;
    enqueue(queueTwo, persTwo->nodeValue);
    
    while (getLength(queueOne) != 0)
    {
        stationOne--;
        stationTwo--;
        
        if (stationOne == 0)
        {
            firstPersOut = persOne;
            persOne = dequeue(queueOne);
            stationOne = persOne->nodeValue;
            
            enqueue(queueTwo, firstPersOut->nodeValue);
        }
        else if (stationTwo == 0)
        {
            firstPersOut = persTwo;
            persTwo = dequeue(queueOne);
            stationTwo = persTwo->nodeValue;
            
            enqueue(queueTwo, firstPersOut->nodeValue);
        }      
        
        totTime++;
    }
    
    destroyQueue(queueOne);
    
    printf("Total Time for Two Stations: %.2f virtual minutes\n", (totTime/60.0));
    
    
    /* Test with 3 stations */
    totTime = 0;
    persOne = dequeue(queueTwo); 
    stationOne = persOne->nodeValue;

    persTwo = dequeue(queueTwo);
    stationTwo = persTwo->nodeValue;
    
    persThree = dequeue(queueTwo);
    stationThree = persThree->nodeValue;
    
    while (getLength(queueTwo) != 0)
    {
        stationOne--;
        stationTwo--;
        stationThree--;
        
        if (stationOne == 0)
        {
            firstPersOut = persOne;
            persOne = dequeue(queueTwo);
            stationOne = persOne->nodeValue;
        }
        else if (stationTwo == 0)
        {
            firstPersOut = persTwo;
            persTwo = dequeue(queueTwo);
            stationTwo = persTwo->nodeValue;
        }    
        else if (stationThree == 0)
        {
            firstPersOut = persThree;
            persThree = dequeue(queueTwo);
            stationThree = persThree->nodeValue;
        }   
        
        totTime++;
    }
    
    printf("Total Time for three Stations: %.2f virtual minutes\n", (totTime/60.0));
    destroyQueue(queueTwo);
    
    return (EXIT_SUCCESS);
}
Example #28
0
void
debugLoop_run(void)
{
    jboolean shouldListen;
    jdwpPacket p;
    jvmtiStartFunction func;

    /* Initialize all statics */
    /* We may be starting a new connection after an error */
    cmdQueue = NULL;
    cmdQueueLock = debugMonitorCreate("JDWP Command Queue Lock");
    transportError = JNI_FALSE;

    shouldListen = JNI_TRUE;

    func = &reader;
    (void)spawnNewThread(func, NULL, "JDWP Command Reader");

    standardHandlers_onConnect();
    threadControl_onConnect();

    /* Okay, start reading cmds! */
    while (shouldListen) {
        if (!dequeue(&p)) {
            break;
        }

        if (p.type.cmd.flags & JDWPTRANSPORT_FLAGS_REPLY) {
            /*
             * Its a reply packet.
             */
           continue;
        } else {
            /*
             * Its a cmd packet.
             */
            jdwpCmdPacket *cmd = &p.type.cmd;
            PacketInputStream in;
            PacketOutputStream out;
            CommandHandler func;

            /* Should reply be sent to sender.
             * For error handling, assume yes, since
             * only VM/exit does not reply
             */
            jboolean replyToSender = JNI_TRUE;

            /*
             * For VirtualMachine.Resume commands we hold the resumeLock
             * while executing and replying to the command. This ensures
             * that a Resume after VM_DEATH will be allowed to complete
             * before the thread posting the VM_DEATH continues VM
             * termination.
             */
            if (resumeCommand(cmd)) {
                debugMonitorEnter(resumeLock);
            }

            /* Initialize the input and output streams */
            inStream_init(&in, p);
            outStream_initReply(&out, inStream_id(&in));

            LOG_MISC(("Command set %d, command %d", cmd->cmdSet, cmd->cmd));

            func = debugDispatch_getHandler(cmd->cmdSet,cmd->cmd);
            if (func == NULL) {
                /* we've never heard of this, so I guess we
                 * haven't implemented it.
                 * Handle gracefully for future expansion
                 * and platform / vendor expansion.
                 */
                outStream_setError(&out, JDWP_ERROR(NOT_IMPLEMENTED));
            } else if (gdata->vmDead &&
             ((cmd->cmdSet) != JDWP_COMMAND_SET(VirtualMachine))) {
                /* Protect the VM from calls while dead.
                 * VirtualMachine cmdSet quietly ignores some cmds
                 * after VM death, so, it sends it's own errors.
                 */
                outStream_setError(&out, JDWP_ERROR(VM_DEAD));
            } else {
                /* Call the command handler */
                replyToSender = func(&in, &out);
            }

            /* Reply to the sender */
            if (replyToSender) {
                if (inStream_error(&in)) {
                    outStream_setError(&out, inStream_error(&in));
                }
                outStream_sendReply(&out);
            }

            /*
             * Release the resumeLock as the reply has been posted.
             */
            if (resumeCommand(cmd)) {
                debugMonitorExit(resumeLock);
            }

            inStream_destroy(&in);
            outStream_destroy(&out);

            shouldListen = !lastCommand(cmd);
        }
    }
    threadControl_onDisconnect();
    standardHandlers_onDisconnect();

    /*
     * Cut off the transport immediately. This has the effect of
     * cutting off any events that the eventHelper thread might
     * be trying to send.
     */
    transport_close();
    debugMonitorDestroy(cmdQueueLock);

    /* Reset for a new connection to this VM if it's still alive */
    if ( ! gdata->vmDead ) {
        debugInit_reset(getEnv());
    }
}
// Main function
int main (int argc, char *argv[])
{
    char *input = "input.txt"; // File containing the commands

    // Initialize Process Table
    struct process process_table[25];

    // Initialize CPU 1
    struct hardware cpu1;
    cpu1.busy = 0;

    // Initialize CPU 2
    struct hardware cpu2;
    cpu2.busy = 0;

    // Initialize SSD
    struct hardware ssd;
    ssd.busy = 0;

    // Initialize IO priority queue
    struct queue io_q;
    io_q.nextEmpty = 0;
    io_q.busy = 0;

    // Setting NULL values
    int x;

    for(x = 0; x < 26; x++) {
        io_q.pid[x] = NULL_VALUE;
    }

    // Initialize Ready queue.
    struct queue ready_q;
    ready_q.nextEmpty = 0;
    ready_q.busy = 0;

    // Setting NULL values
    for(x = 0; x < 26; x++) {
        ready_q.pid[x] = NULL_VALUE;
    }

    // Initialize SSD queue.
    struct queue ssd_q;
    ssd_q.nextEmpty = 0;
    ssd_q.busy = 0;

    // Setting NULL values
    for(x = 0; x < 26; x++) {
        ssd_q.pid[x] = NULL_VALUE;
    }


    // Read the file with the commands.
    read_commands(input, process_table);

    // Testing code to check if the process were created correctly
    int i, j;

    for(i=0;i<process_ctr;i++) {

        printf("PID %d\n", process_table[i].pid);
        printf("STATE %d\n", process_table[i].state);
        printf("COMMAND_INDEX %d\n", process_table[i].command_index);
        printf("TOTAL_COMMANDS %d\n", process_table[i].total_commands);
        printf("SSD_ACCESS_COUNTER %d\n", process_table[i].ssd_access_counter);
        printf("SSD_USAGE_TIME %d\n", process_table[i].ssd_usage_time);
        printf("SSD_WAIT_TIME %d\n", process_table[i].ssd_wait_time);
        printf("SSD_ENTRY_TIME %d\n", process_table[i].ssd_entry_time);

        for(j=0;j<process_table[i].command_index;j++) {
            printf("\tNAME %d", process_table[i].commands[j].name);
            printf("\tTIME %d\n", process_table[i].commands[j].time);
        }

        printf("\n");
    }

    // Setting the total commands and reseting the command_index of each process to 0;
    for(i=0;i<process_ctr;i++) {
        process_table[i].total_commands = process_table[i].command_index;
        process_table[i].command_index = 0;
    }


    printf("Current Time: %d, Total Processes in Table: %d\n", global_time,process_ctr);
    for(i = 0; i < process_ctr; i++) {
        printf("PROCESS %d: ", process_table[i].pid);
        if (process_table[i].state == READY)
        {
           printf("Current State = READY");
        }
        else if (process_table[i].state == RUNNING)
        {
           printf("Current State = RUNNING");
        }
        else if (process_table[i].state == WAITING)
        {
           printf("Current State = WAITING");
        }
        else if (process_table[i].state == FINISHED)
        {
           printf("Current State = FINISHED");
        }
        printf(" Next Index = %d\n", process_table[i].command_index);
    }

    printf("\n\n\n");

    while(finished_processes < process_ctr){
        /////////////// Check minimum end time ///////////////
        int minFinishTime = 9999999;
        // Check cpu1
        if(cpu1.busy) {
            if(cpu1.finish_time < minFinishTime) {
                minFinishTime = cpu1.finish_time;
            }
        }

        // Check cpu2
        if(cpu2.busy) {
            if(cpu2.finish_time < minFinishTime) {
                minFinishTime = cpu2.finish_time;
            }
        }

        // Check ssd
        if(ssd.busy) {
            if(ssd.finish_time < minFinishTime) {
                minFinishTime = ssd.finish_time;
            }
        }

        // Check INP queue
        if(io_q.busy) {
            if(process_table[io_q.pid[0]].commands[process_table[io_q.pid[0]].command_index].time + process_table[io_q.pid[0]].io_entry_time < minFinishTime) {
                minFinishTime = process_table[io_q.pid[0]].commands[process_table[io_q.pid[0]].command_index].time + process_table[io_q.pid[0]].io_entry_time;
            }
        }

        // Check if create a new process
        if(next_new_process < process_ctr) {
            if(process_table[next_new_process].commands[0].time < minFinishTime) {
                minFinishTime = process_table[next_new_process].commands[0].time;
            }
        }

        // Updating global time
        global_time = minFinishTime;



        /////////////// Free up hardware, io queue, and new process ///////////////

        // Free cpu1
        if(cpu1.busy) {
            if(cpu1.finish_time == minFinishTime) {
                execute_next_command(get_process_from_hardware(&cpu1, process_table), process_table, &io_q, &ssd_q, &ready_q);
            }
        }

        // Free cpu2
        if(cpu2.busy) {
            if(cpu2.finish_time == minFinishTime) {
                execute_next_command(get_process_from_hardware(&cpu2, process_table), process_table, &io_q, &ssd_q, &ready_q);
            }
        }

        // Free ssd
        if(ssd.busy) {
            if(ssd.finish_time == minFinishTime) {
                execute_next_command(get_process_from_hardware(&ssd, process_table), process_table, &io_q, &ssd_q, &ready_q);
            }
        }

        // Dequeue from INP queue
        if(io_q.busy) {
            while(io_q.busy && (process_table[io_q.pid[0]].commands[process_table[io_q.pid[0]].command_index].time + process_table[io_q.pid[0]].io_entry_time == minFinishTime) ) {
                execute_next_command(dequeue(&io_q), process_table, &io_q, &ssd_q, &ready_q);
            }
        }

        // Creating a new process
        if(next_new_process < process_ctr) {
            while(process_table[next_new_process].commands[0].time == minFinishTime) {
                execute_next_command(next_new_process, process_table, &io_q, &ssd_q, &ready_q);
                next_new_process = next_new_process + 1;
            }
        }




        /////////////// Put process from queue to hardware ///////////////

        // Check if cpu1 is busy
        if(cpu1.busy == 0) {
            // Check if ready q has something
            if(ready_q.busy) {

                // Add to cpu1
                cpu1.pid = dequeue(&ready_q);
                cpu1.busy = 1;
                cpu1.finish_time = global_time + process_table[cpu1.pid].commands[process_table[cpu1.pid].command_index].time;
                process_table[cpu1.pid].state = RUNNING;
                process_table[cpu1.pid].cpu_usage_time = process_table[cpu1.pid].cpu_usage_time + process_table[cpu1.pid].commands[process_table[cpu1.pid].command_index].time;


                // Increment command index
            }

        }

        // Check if cpu2 is busy
        if(cpu2.busy == 0) {
            // Check if ready q has something
             if(ready_q.busy) {

                // Add to cpu2
                cpu2.pid = dequeue(&ready_q);
                cpu2.busy = 1;
                cpu2.finish_time = global_time + process_table[cpu2.pid].commands[process_table[cpu2.pid].command_index].time;
                process_table[cpu2.pid].state = RUNNING;
                process_table[cpu2.pid].cpu_usage_time = process_table[cpu2.pid].cpu_usage_time + process_table[cpu2.pid].commands[process_table[cpu2.pid].command_index].time;
                // Increment command index
            }

        }

        // Check if ssd is busy
        if(ssd.busy == 0) {
            // Check if ssd q has something
            if(ssd_q.busy) {

                // Add to cpu2
                ssd.pid = dequeue(&ssd_q);
                ssd.busy = 1;
                ssd.finish_time = global_time + process_table[ssd.pid].commands[process_table[ssd.pid].command_index].time;
                process_table[ssd.pid].state = WAITING;
                process_table[ssd.pid].ssd_wait_time = (process_table[ssd.pid].ssd_wait_time + global_time) - process_table[ssd.pid].ssd_entry_time;
                process_table[ssd.pid].ssd_access_counter++;
                process_table[ssd.pid].ssd_usage_time = process_table[ssd.pid].ssd_usage_time + process_table[ssd.pid].commands[process_table[ssd.pid].command_index].time;
                // Increment command index
            }

        }

        printf("Current Time: %d, Total Processes in Table: %d\n", global_time,process_ctr);
        for(i = 0; i < process_ctr; i++) {
                printf("PROCESS %d: ", process_table[i].pid);
        if (process_table[i].state == READY)
        {
           printf("Current State = READY");
        }
        else if (process_table[i].state == RUNNING)
        {
           printf("Current State = RUNNING");
        }
        else if (process_table[i].state == WAITING)
        {
           printf("Current State = WAITING");
        }
        else if (process_table[i].state == FINISHED)
        {
           printf("Current State = FINISHED");
        }

        if (process_table[i].state == FINISHED) {
            printf(" Next Index = %d\n", process_table[i].command_index);
        }
        else {
            printf(" Next Index = %d\n", process_table[i].command_index + 1);
        }
    }

        printf("\n\n\n");

    }
    printf("Summary: \n");
    printf("Total Processes Completed: %d \n", finished_processes);

    int ssdAccesses = 0;
    int ssdWaitTime = 0;
    int ssdUsageTime = 0;
    int cpuUsageTime = 0;

    for(i=0; i < finished_processes; i++)
    {
        ssdAccesses = ssdAccesses + process_table[i].ssd_access_counter;
        ssdWaitTime =  ssdWaitTime + process_table[i].ssd_usage_time + process_table[i].ssd_wait_time;
        ssdUsageTime =  ssdUsageTime + process_table[i].ssd_usage_time;
        cpuUsageTime =  cpuUsageTime + process_table[i].cpu_usage_time;

    }

    printf("Total Number of SSD Accesses: %d\n", ssdAccesses);

    if(ssdAccesses != 0) {
        printf("Average SSD Access Duration: %f ms\n", ((double)ssdWaitTime/(double)ssdAccesses));
    }
    else {
        printf("Average SSD Access Duration: 0 ms\n");
    }
    printf("Total Elapsed Time %d ms\n", global_time-process_table[0].commands[0].time);
    printf("CPU Utilization %f\n", ( (double) cpuUsageTime / ((double) global_time-process_table[0].commands[0].time)));
    printf("SSD Utilization %f\n", ((double)ssdUsageTime/((double)global_time-process_table[0].commands[0].time)));


    // Finish program
    return 0;
};
Example #30
0
// takes an initial start index and calculates a blob with it returning
// the calculated blob
// visitedArray is 1 if it has been visited and 0 otherwise
Blob CalculateBlob(struct Image* img, double tol, byte* visited, int start)
{
  if(start < 0)
  {
    fprintf(stderr, "Calculate Blob called with %d. Number not acceptable\n", start);
    return;
  }

  // instantiating the blob to return
  Blob b;
  b.size = 0;
  b.max = 10;
  b.radAvg = 0;
  b.indeces = malloc(sizeof(int) * b.max);
  if(b.indeces == NULL)
  {
    fprintf(stderr, "Malloc did not properly allocate memory for b.indeces");
    exit(1);
  }
  b.color = malloc(sizeof(double)*3);
  if(b.color != NULL)
  {
    b.color[0] = img->red[start];
    b.color[1] = img->green[start];
    b.color[2] = img->blue[start];
  }
  else
  {
    fprintf(stderr, "Malloc did not properly allocate memory for b.color");
    exit(1);
  }

  // setting up the queue
  Queue intQueue;
  intQueue.tail = NULL;
  intQueue.head = NULL;
  intQueue.size = 0;
  enqueue(&intQueue, start);
  // accidently had this setting visited[0] to 1 over
  // and over again, so initial pixels were always counted twice
  visited[start] = 1;

  while(intQueue.size != 0)
  {
    int next = dequeue(&intQueue);
    AddDataToArray(&b, next);
    AverageColors(&b, img->red[next], img->green[next], img->blue[next]);

    int up = GetPixelUp(next, img->NofR, img->NofC);
    int down = GetPixelDown(next, img->NofR, img->NofC);
    int left = GetPixelLeft(next, img->NofR, img->NofC);
    int right = GetPixelRight(next, img->NofR, img->NofC);

    if(up != null && !visited[up] &&
      tol > geometricDistanceWithNoArrays(b.color, img->red[up], img->green[up], img->blue[up]))
    {
      enqueue(&intQueue, up);
      visited[up] = 1;        // this index has now been visited
    }
    if(down != null && !visited[down] &&
      tol > geometricDistanceWithNoArrays(b.color, img->red[down], img->green[down], img->blue[down]))
    {
      enqueue(&intQueue, down);
      visited[down] = 1;        // this index has now been visited
    }
    if(left != null && !visited[left] &&
      tol > geometricDistanceWithNoArrays(b.color, img->red[left], img->green[left], img->blue[left]))
    {
      enqueue(&intQueue, left);
      visited[left] = 1;        // this index has now been visited
    }
    if(right != null && !visited[right] &&
      tol > geometricDistanceWithNoArrays(b.color, img->red[right], img->green[right], img->blue[right]))
    {
      enqueue(&intQueue, right);
      visited[right] = 1;        // this index has now been visited
    }
  }
  return b;
}