// Find and transmit any scheduled steps prior to the given 'move_clock' public int flush(ulong move_clock) { // Flush each stepcompress to the specified move_clock int i; for (i = 0; i < sc_list.Count; i++) { var sc = sc_list[i]; int ret = sc.flush(move_clock); if (ret != 0) { return(ret); } } // Order commands by the reqclock of each pending command List <SerialQueue.RawMessage> msgs = new List <SerialQueue.RawMessage>(); while (true) { // Find message with lowest reqclock ulong req_clock = SerialQueue.MAX_CLOCK; var qm = new SerialQueue.RawMessage(); var scFound = default(stepcompress); bool found = false; for (i = 0; i < sc_list.Count; i++) { stepcompress sc = sc_list[i]; if (sc.msg_queue.Count != 0) { var m = sc.msg_queue.Peek(); if (m.req_clock < req_clock) { found = true; scFound = sc; qm = m; req_clock = m.req_clock; } } } if (!found || (qm.min_clock != 0 && req_clock > move_clock)) { break; } ulong next_avail = move_clocks[0]; if (qm.min_clock != 0) { // The qm.min_clock field is overloaded to indicate that // the command uses the 'move queue' and to store the time // that move queue item becomes available. heap_replace(qm.min_clock); } // Reset the min_clock to its normal meaning (minimum transmit time) qm.min_clock = next_avail; qm = scFound.msg_queue.Dequeue(); // Batch this command msgs.Add(qm); } // Transmit commands if (msgs.Count != 0) { sq.send_batch(cq, msgs.ToArray()); } return(0); }