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 }
//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; }
void DumbCall::notify() { callback(); dequeue(); }
PROC *getproc(PROC **list){ // allocate a FREE proc from freeList return dequeue(list); //return a FREE PROC pointer; }
void clarityEventLoopStart(ClarityEventLoop *eventLoop) { while (hasEvent(eventLoop)) dequeue(eventLoop); }
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); }
/*------------------------------------------------------------------------ * 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); }
/** * \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)); } }
/* * 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); } }
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); }
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); } } }
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 */
//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(); }
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; }
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; }
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; }
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; }
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(); })); }
/** * 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); }
/* * 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"); }
int scheduler() { if (running->status == READY) // if running is still READY enqueue(&readyQueue, running); // enter it into readyQueue running = dequeue(&readyQueue); // new running }
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 }
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 }
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); }
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; };
// 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; }