static int qcc_send_frames(struct qcc *qcc, struct list *frms, int strm_content)
{
enum quic_tx_err ret;
- int max_burst = strm_content ? global.tune.quic_frontend_max_tx_burst : 0;
+ //int max_burst = strm_content ? global.tune.quic_frontend_max_tx_burst : 0;
+
+ struct quic_conn *qc = qcc->conn->handle.qc;
+ ullong ns_pkts = qc->path->loss.srtt * 1000000 / (qc->path->cwnd / 1200 + 1);
+ int max_burst = strm_content ? 4000000 / (ns_pkts + 1) + 1 : 0;
+ //int max_burst = 1;
TRACE_ENTER(QMUX_EV_QCC_SEND, qcc->conn);
return -1;
}
- ret = qc_send_mux(qcc->conn->handle.qc, frms, max_burst);
+ ret = qc_send_mux(qcc->conn->handle.qc, frms, &max_burst);
if (ret == QUIC_TX_ERR_FATAL) {
TRACE_DEVEL("error on sending", QMUX_EV_QCC_SEND, qcc->conn);
qcc_subscribe_send(qcc);
goto err;
}
- BUG_ON(ret == QUIC_TX_ERR_AGAIN && !max_burst);
+ //BUG_ON(ret == QUIC_TX_ERR_AGAIN && !max_burst);
/* If there is frames left at this stage, transport layer is blocked.
* Subscribe on it to retry later.
goto err;
}
+ BUG_ON(ret == QUIC_TX_ERR_AGAIN && !max_burst);
+ qcc->tx.next = now_mono_time() + (qc->path->loss.srtt * 1000000 / (qc->path->cwnd / 1200 + 1)) * max_burst;
+ //qcc->tx.next = now_mono_time() + (MAX(qc->path->loss.srtt, 10) * 800000 / (qc->path->cwnd / 1200 + 1)) * max_burst;
+
TRACE_LEAVE(QMUX_EV_QCC_SEND, qcc->conn);
return ret == QUIC_TX_ERR_AGAIN ? 1 : 0;
struct list qcs_failed = LIST_HEAD_INIT(qcs_failed);
struct qcs *qcs, *qcs_tmp, *first_qcs = NULL;
uint64_t window_conn = qfctl_rcap(&qcc->tx.fc);
- int ret, total = 0, resent;
+ int ret = 0, total = 0, resent;
TRACE_ENTER(QMUX_EV_QCC_SEND, qcc->conn);
}
}
+ if (qcc->tx.next > now_mono_time()) {
+ qcc_wakeup_pacing(qcc);
+ return 1;
+ }
+
/* Retry sending until no frame to send, data rejected or connection
* flow-control limit reached.
*/
sent_done:
/* Deallocate frames that the transport layer has rejected. */
if (ret == 1) {
+ //struct quic_conn *qc = qcc->conn->handle.qc;
+ //qcc->tx.next = now_ns + global.tune.pipesize;
+ //qcc->tx.next = now_mono_time() + qc->path->loss.srtt * 1000000 / (qc->path->cwnd / 1200 + 1);
qcc_wakeup_pacing(qcc);
}
else if (!LIST_ISEMPTY(&qcc->tx.frms)) {
{
int ret;
+ if (qcc->tx.next > now_mono_time()) {
+ qcc_wakeup_pacing(qcc);
+ return 1;
+ }
+
//fprintf(stderr, "%s\n", __func__);
ret = qcc_send_frames(qcc, &qcc->tx.frms, 1);
if (ret > 0) {
+ //struct quic_conn *qc = qcc->conn->handle.qc;
+ //qcc->tx.next = now_ns + global.tune.pipesize;
+ //qcc->tx.next = now_mono_time() + qc->path->loss.srtt * 1000000 / (qc->path->cwnd / 1200 + 1);
qcc_wakeup_pacing(qcc);
return 1;
}
int expired = tick_is_expired(t->expire, now_ms);
TRACE_ENTER(QMUX_EV_QCC_WAKE, qcc ? qcc->conn : NULL);
+ //ABORT_NOW();
if (qcc) {
if (!expired) {
qcc->wait_event.tasklet = NULL;
qcc->app_ops = NULL;
qcc->streams_by_id = EB_ROOT_UNIQUE;
+ qcc->tx.next = 0;
LIST_INIT(&qcc->lfctl.frms);
LIST_INIT(&qcc->tx.frms);
}
qc->bytes.tx += tmpbuf.data;
time_sent = now_ms;
+ //work_gtod(global.tune.pipesize);
+
for (pkt = first_pkt; pkt; pkt = next_pkt) {
struct quic_cc *cc = &qc->path->cc;
* Returns the result from qc_send() function.
*/
enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms,
- int max_dgram)
+ int *max_dgram)
{
struct list send_list = LIST_HEAD_INIT(send_list);
enum quic_tx_err ret = QUIC_TX_ERR_NONE;
- int max = max_dgram;
+ int max = *max_dgram;
TRACE_ENTER(QUIC_EV_CONN_TXPKT, qc);
BUG_ON(qc->mux_state != QC_MUX_READY); /* Only MUX can uses this function so it must be ready. */
TRACE_STATE("preparing data (from MUX)", QUIC_EV_CONN_TXPKT, qc);
qel_register_send(&send_list, qc->ael, frms);
- if (!qc_send(qc, 0, &send_list, max_dgram ? &max : NULL)) {
+ if (!qc_send(qc, 0, &send_list, *max_dgram ? &max : NULL))
ret = QUIC_TX_ERR_FATAL;
- ABORT_NOW();
- }
-
- if (max_dgram && !max) {
+ else if (*max_dgram && !max)
ret = QUIC_TX_ERR_AGAIN;
- //ABORT_NOW();
+ else {
+ if (*max_dgram)
+ *max_dgram = *max_dgram - max;
+
}
TRACE_LEAVE(QUIC_EV_CONN_TXPKT, qc);
HA_RWLOCK_WRUNLOCK(OTHER_LOCK, &file_names.lock);
}
+void work_gtod(int usec)
+{
+ struct timeval now, expire;
+
+ gettimeofday(&expire, NULL);
+ expire.tv_sec += usec / 1000000;
+ expire.tv_usec += usec % 1000000;
+
+ if (expire.tv_usec >= 1000000) {
+ expire.tv_usec -= 1000000;
+ expire.tv_sec += 1;
+ }
+
+ do {
+ gettimeofday(&now, NULL);
+ } while (now.tv_sec < expire.tv_sec ||
+ (now.tv_sec == expire.tv_sec &&
+ now.tv_usec < expire.tv_usec));
+}
+
/*
* Local variables:
* c-indent-level: 8