On 03/20/2017 03:55 PM, Sergiy Kibrik wrote:
 void XEN_Console::write(const char *str, size_t len) {
-       HYPERVISOR_console_write(str, len);
+    assert(len > 0);
+    if (!_interface) {
+        HYPERVISOR_console_write(str, len);
+        return;
+    }
+
+    /* str might be larger then ring, so write it by chunks in this case */
+    XENCONS_RING_IDX prod = _interface->out_prod;
+    constexpr auto ringsize = sizeof(_interface->out) - 1;
+    while (true) {
+        XENCONS_RING_IDX cons = _interface->out_cons;
+        auto delta = prod - cons;
+
+        if (unlikely(delta > ringsize)) {
+            prod = cons; /* ring is corrupted, reset is the best we can do */
+            delta = 0;
+        }
+
+        size_t c = 0;
+        for (; c < std::min(ringsize - delta, len); c++)
+            _interface->out[MASK_XENCONS_IDX(prod++, _interface->out)] = 
*str++;
+
+        _interface->out_prod = prod;
+        wmb();
+
+        if (likely(c == len))
+            break; /* flush() will do evtchn notification */
+
+        len -= ringsize - delta;
+        notify_remote_via_evtchn(_evtchn);
+
+        while (_interface->out_cons != _interface->out_prod)
+            cpu_relax(); /* can't sleep here */
+    }
 }


hi Nadav,
I've implemented flow control like this, but I can't properly verify and test 
it, as LineDiscipline and debug_early() write to console by single character at 
a time, while flow control presumes writing by quite large blocks of 2KB size.
In this v2 variant console works fine right now, but can you suggest how flow 
control can be verified?

--
regards,
Sergiy

--
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to