void global_cached_io::process_all_requests() { // We first process the completed requests from the disk. // It will add completed user requests and pending requests to queues // for further processing. while (!completed_disk_queue.is_empty()) { int num = completed_disk_queue.get_num_entries(); stack_array<io_request> reqs(num); int ret = completed_disk_queue.fetch(reqs.data(), num); process_disk_completed_requests(reqs.data(), ret); } // Process the requests that are pending on the pages. // It may add completed user requests to queues for further processing. if (!pending_requests.is_empty()) handle_pending_requests(); // Process buffered user requests. // It may add completed user requests to queues for further processing. process_user_reqs(); std::vector<io_request> requests; // Process the completed requests served in the cache directly. process_cached_reqs(requests); // Process completed user requests. process_completed_requests(requests); // Process requests issued in the user compute. // We try to gather all requests so we can merge them. However, we only // have the local collection of the requests. We still need to rely on // the OS's elevator algorithm to merge the requests from different // global_cached_io. access(requests.data(), requests.size(), NULL); // Processing the pending requests on the pages might issue // more I/O requests. flush_requests(); }
dword_t cpu_mailbox_t::send_command(dword_t cpu, dword_t command, dword_t value) { int count = MAILBOX_TIMEOUT; m_status = value; m_command = command; /* signal the request */ cpu_mailbox[cpu].set_request(get_cpu_id()); /* send command IPI to the cpu */ send_command_ipi(cpu); spin1(71); /* and now wait for the cpu to handle the reuqest */ while (m_status == value) { spin1(70); if (count-- == 0) { IPI_PRINTF("mailbox::send_command timeout - resend IPI to %d\n", cpu); enter_kdebug("timeout"); send_command_ipi(cpu); count = MAILBOX_TIMEOUT; } /* allow incoming requests from other cpus */ if (pending_requests) { IPI_PRINTF("mailbox::send_command incoming request\n"); handle_pending_requests(); continue; } __asm__ __volatile__ (".byte 0xf3; .byte 0x90\n"); } return m_status; }
void partition_resolver_simple::query_config_reply(error_code err, dsn_message_t request, dsn_message_t response, int partition_index) { auto client_err = ERR_OK; if (err == ERR_OK) { configuration_query_by_index_response resp; unmarshall(response, resp); if (resp.err == ERR_OK) { zauto_write_lock l(_config_lock); if (_app_id != -1 && _app_id != resp.app_id) { dassert(false, "app id is changed (mostly the app was removed and created with the same name), local Vs remote: %u vs %u ", _app_id, resp.app_id); } if (_app_partition_count != -1 && _app_partition_count != resp.partition_count) { dassert(false, "partition count is changed (mostly the app was removed and created with the same name), local Vs remote: %u vs %u ", _app_partition_count, resp.partition_count); } _app_id = resp.app_id; _app_partition_count = resp.partition_count; _app_is_stateful = resp.is_stateful; for (auto it = resp.partitions.begin(); it != resp.partitions.end(); ++it) { auto& new_config = *it; dinfo("%s.client: query config reply, gpid = %d.%d, ballot = %" PRId64 ", primary = %s", _app_path.c_str(), new_config.pid.get_app_id(), new_config.pid.get_partition_index(), new_config.ballot, new_config.primary.to_string() ); auto it2 = _config_cache.find(new_config.pid.get_partition_index()); if (it2 == _config_cache.end()) { std::unique_ptr<partition_info> pi(new partition_info); pi->timeout_count = 0; pi->config = new_config; _config_cache.emplace(new_config.pid.get_partition_index(), std::move(pi)); } else if (_app_is_stateful && it2->second->config.ballot < new_config.ballot) { it2->second->timeout_count = 0; it2->second->config = new_config; } else if (!_app_is_stateful) { it2->second->timeout_count = 0; it2->second->config = new_config; } else { // nothing to do } } } else if (resp.err == ERR_OBJECT_NOT_FOUND) { derror("%s.client: query config reply, gpid = %d.%d, err = %s", _app_path.c_str(), _app_id, partition_index, resp.err.to_string() ); client_err = ERR_APP_NOT_EXIST; } else { derror("%s.client: query config reply, gpid = %d.%d, err = %s", _app_path.c_str(), _app_id, partition_index, resp.err.to_string() ); client_err = resp.err; } } else { derror("%s.client: query config reply, gpid = %d.%d, err = %s", _app_path.c_str(), _app_id, partition_index, err.to_string() ); } // get specific or all partition update if (partition_index != -1) { partition_context* pc = nullptr; { zauto_lock l(_requests_lock); auto it = _pending_requests.find(partition_index); if (it != _pending_requests.end()) { pc = it->second; _pending_requests.erase(partition_index); } } if (pc) { handle_pending_requests(pc->requests, client_err); delete pc; } } // get all partition update else { pending_replica_requests reqs; std::deque<request_context_ptr> reqs2; { zauto_lock l(_requests_lock); reqs.swap(_pending_requests); reqs2.swap(_pending_requests_before_partition_count_unknown); } if (!reqs2.empty()) { if (_app_partition_count != -1) { for (auto& req : reqs2) { dassert(req->partition_index == -1, ""); req->partition_index = get_partition_index(_app_partition_count, req->partition_hash); } } handle_pending_requests(reqs2, client_err); } for (auto& r : reqs) { if (r.second) { handle_pending_requests(r.second->requests, client_err); delete r.second; } } } }