int itc_async_read_1 (it_cursor_t * itc, dp_addr_t dp, dp_addr_t phys_dp, buffer_desc_t * buf, buffer_desc_t * decoy) { #if 0 #error Not supposed to be on with 5.0 /* if the iq for the dp to read is busy, put the read in the iq instead of doing it here. * Called outside map, returns 1 inside map if the read was scheduled, otherwise returns 0 outside map. */ int n; io_queue_t * iq = db_io_queue (ITC_STORAGE (itc), phys_dp); buffer_desc_t * queued; if (!iq || !iq_is_on ()) return 0; queued = iq->iq_first; for (n = 0; n < 10; n++) { if (!queued) return 0; queued = queued->bd_iq_next; } /* items in the queue. Add to the queue. */ buf->bd_being_read = 1; ITC_IN_MAP (itc); buf->bd_page = 0; isp_set_buffer (itc->itc_space, dp, phys_dp, buf); buf->bd_write_waiting = NULL; itc->itc_n_reads++; ITC_MARK_READ (itc); buf->bd_waiting_read = decoy->bd_waiting_read; buf->bd_readers = 0; ITC_LEAVE_MAP (itc); iq_schedule (&buf, 1); ITC_IN_MAP (itc); return 1; #else return 0; #endif }
void iq_schedule (buffer_desc_t ** bufs, int n) { int inx; int is_reads = 0; buf_sort (bufs, n, (sort_key_func_t) bd_phys_page_key); for (inx = 0; inx < n; inx++) { if (bufs[inx]->bd_iq) GPF_T1 ("buffer added to iq already has a bd_iq"); bufs[inx]->bd_iq = db_io_queue (bufs[inx]->bd_storage, bufs[inx]->bd_physical_page); } DO_SET (io_queue_t *, iq, &mti_io_queues) { int n_added = 0; buffer_desc_t * ipoint; int was_empty; IN_IOQ (iq); inx = 0; ipoint = iq->iq_first; was_empty = (iq->iq_first == NULL); while (inx < n) { buffer_desc_t * buf = bufs[inx]; if (!buf || buf->bd_iq != iq) { inx++; continue; } is_reads = buf->bd_being_read; if (buf->bd_iq_next || buf->bd_iq_prev) GPF_T1 ("can't schedule same buffer twice"); bufs[inx] = NULL; next_ipoint: if (!ipoint) { L2_PUSH_LAST (iq->iq_first, iq->iq_last, buf, bd_iq_); n_added++; inx++; } else if (BUF_SORT_DP (ipoint) < BUF_SORT_DP (buf)) { ipoint = ipoint->bd_iq_next; goto next_ipoint; } else if (BUF_SORT_DP (ipoint) == BUF_SORT_DP (buf)) GPF_T1 ("the same buffer can't be scheduled twice for io"); else { L2_INSERT (iq->iq_first, iq->iq_last, ipoint, buf, bd_iq_); n_added++; inx++; } if (!buf->bd_being_read) { page_leave_outside_map (buf); } } LEAVE_IOQ (iq); if (n_added && !is_reads) { dbg_printf (("IQ %s %d %s added, %s.\n", IQ_NAME (iq), n_added, is_reads ? "reads" : "writes", was_empty ? "starting" : "running")); } if (n_added && was_empty) semaphore_leave (iq->iq_sem); } END_DO_SET (); if (n) { if (is_reads) mti_reads_queued += n; else mti_writes_queued += n; } }