Ejemplo n.º 1
0
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();
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
        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;
                    }
                }
            }
        }