Exemple #1
0
static cs_error_t
reply_receive (
	struct ipc_instance *ipc_instance,
	void *res_msg,
	size_t res_len)
{
	coroipc_response_header_t *response_header;
	cs_error_t res;

retry_ipc_sem_wait:
	res = ipc_sem_wait (ipc_instance->control_buffer, SEMAPHORE_RESPONSE, ipc_instance->fd);
	if (res != CS_OK) {
		if (res == CS_ERR_TRY_AGAIN) {
			priv_change_send (ipc_instance);
			goto retry_ipc_sem_wait;
		} else {
			return (res);
		}
	}

	response_header = (coroipc_response_header_t *)ipc_instance->response_buffer;
	if (response_header->error == CS_ERR_TRY_AGAIN) {
		return (CS_ERR_TRY_AGAIN);
	}

	memcpy (res_msg, ipc_instance->response_buffer, res_len);
	return (CS_OK);
}
Exemple #2
0
int ipc_read(void* buff, size_t len) {

    int res;
    struct Queue* queue = me->queue;
    struct Entry* entry;

    ipc_sem_wait(queue->readWait);
    sem_wait(me->lock);
    assert_sems(me);

    entry = &(queue->slots[queue->index[0]]);
    if (len > entry->len) {
        res = entry->len;
    } else {
        res = len;
    }
    memcpy(buff, entry->content, res);

    entry->len = 0;
    for (size_t i = 1; i < ENTRIES_PER_QUEUE; i++) {
        queue->index[i - 1] = queue->index[i];
        queue->index[i] = -1;
    }

    sem_post(me->lock);
    ipc_sem_post(queue->writeSem);

    return res;
}
Exemple #3
0
u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
{
	int ret = ipc_sem_wait(sem, timeout);
#ifdef LWIP_ARCH_DEBUG
	cprintf("[%d] sem: %d ret: %d timeout: %d\n", current->pid, sem, ret, timeout);
#endif
	if (ret == 0)
		return 0;
	else
		return SYS_ARCH_TIMEOUT;
}
Exemple #4
0
cs_error_t
coroipcc_dispatch_put (hdb_handle_t handle)
{
	coroipc_response_header_t *header;
	struct ipc_instance *ipc_instance;
	cs_error_t res;
	char *addr;
	unsigned int read_idx;

	res = hdb_error_to_cs (hdb_handle_get_always (&ipc_hdb, handle, (void **)&ipc_instance));
	if (res != CS_OK) {
		return (res);
	}

retry_ipc_sem_wait:
	res = ipc_sem_wait (ipc_instance->control_buffer, SEMAPHORE_DISPATCH, ipc_instance->fd);
	if (res != CS_OK) {
		if (res == CS_ERR_TRY_AGAIN) {
			priv_change_send (ipc_instance);
			goto retry_ipc_sem_wait;
		} else {
			goto error_exit;
		}
	}

	addr = ipc_instance->dispatch_buffer;

	read_idx = ipc_instance->control_buffer->read;
	header = (coroipc_response_header_t *) &addr[read_idx];
	ipc_instance->control_buffer->read =
		((read_idx + header->size + 7) & 0xFFFFFFF8) %
			ipc_instance->dispatch_size;

	/*
	 * Put from dispatch get and also from this call's get
	 */
	res = CS_OK;
	
error_exit:
	hdb_handle_put (&ipc_hdb, handle);
	hdb_handle_put (&ipc_hdb, handle);

	return (res);
}
Exemple #5
0
int ipc_write(ipc_t conn, const void* buff, size_t len) {
    size_t slot, i;
    struct Queue* queue = conn->queue;
    struct Entry* entry;

    ipc_sem_wait(queue->writeSem);
    sem_wait(conn->lock);
    assert_sems(conn);

    // If we got this far, we know we have a place to write on!
    for (slot = 0; slot < ENTRIES_PER_QUEUE; slot++) {
        if (queue->slots[slot].len == 0) {
            break;
        }
    }

    for (i = 0; i < ENTRIES_PER_QUEUE; i++) {
        if (queue->index[i] == -1) {
            break;
        }
    }
    // I could sanity check those values, and I also could start working out.
    if (slot == ENTRIES_PER_QUEUE) {
        print_error("[%s] Trying to write to invalid slot\n", conn->name);
    }
    if (i == ENTRIES_PER_QUEUE) {
        print_error("[%s] Trying to write to invalid index entry\n", conn->name);
    }

    queue->index[i] = slot;
    entry = &queue->slots[slot];
    if (len > IPC_MAX_PACKET_LEN) {
        len = IPC_MAX_PACKET_LEN;
        print_error("[%s] Trying to write something bigger than max packet len\n", conn->name);
    }
    entry->len = len;
    memcpy(entry->content, buff, len);

    sem_post(conn->lock);
    ipc_sem_post(queue->readWait);

    return len;
}
Exemple #6
0
int
do_futex(uintptr_t uaddr, int op, int val) {
	int ret = 0;
	if(FUTEX_WAIT == op) {
		if(*((int*)uaddr) != val) {
			panic("FUTEX_WAIT: unexpected val, *uaddr = %d, val = %d\n", *((int*)uaddr), val);
		}
		sem_t sem_id = ipc_sem_find_or_init_with_address(uaddr, 0, 1);
		ret = ipc_sem_wait(sem_id, 100000);
	} else if(FUTEX_WAKE == op) {
		sem_t sem_id = ipc_sem_find_or_init_with_address(uaddr, val, 0);
		if(-E_NO_MEM == sem_id) {
		} else {
			ret = ipc_sem_post_max(sem_id, val);
		}
	} else {
		panic("unexpected futex op: %d\n", op);
	}
}
Exemple #7
0
static cs_error_t
reply_receive_in_buf (
	struct ipc_instance *ipc_instance,
	void **res_msg)
{
	cs_error_t res;

retry_ipc_sem_wait:
	res = ipc_sem_wait (ipc_instance->control_buffer, SEMAPHORE_RESPONSE, ipc_instance->fd);
	if (res != CS_OK) {
		if (res == CS_ERR_TRY_AGAIN) {
			priv_change_send (ipc_instance);
			goto retry_ipc_sem_wait;
		} else {
			return (res);
		}
	}

	*res_msg = (char *)ipc_instance->response_buffer;
	return (CS_OK);
}
Exemple #8
0
static uint32_t sys_sem_wait(uint32_t arg[])
{
	sem_t sem_id = (sem_t) arg[0];
	unsigned int timeout = (unsigned int)arg[1];
	return ipc_sem_wait(sem_id, timeout);
}
Exemple #9
0
static uint64_t
sys_sem_wait(uint64_t arg[]) {
    sem_t sem_id = (sem_t)arg[0];
    return ipc_sem_wait(sem_id);
}
Exemple #10
0
static void *pthread_ipc_consumer (void *conn)
{
	struct conn_info *conn_info = (struct conn_info *)conn;
	int res;
	coroipc_request_header_t *header;
	coroipc_response_header_t coroipc_response_header;
	int send_ok;
	unsigned int new_message;
	int sem_value = 0;

#if defined(HAVE_PTHREAD_SETSCHEDPARAM) && defined(HAVE_SCHED_GET_PRIORITY_MAX)
	if (api->sched_policy != 0) {
		res = pthread_setschedparam (conn_info->thread,
			api->sched_policy, api->sched_param);
	}
#endif

	for (;;) {
		ipc_sem_wait (conn_info->control_buffer, SEMAPHORE_REQUEST_OR_FLUSH_OR_EXIT, IPC_SEMWAIT_NOFILE);
		if (ipc_thread_active (conn_info) == 0) {
			coroipcs_refcount_dec (conn_info);
			pthread_exit (0);
		}

		outq_flush (conn_info);

		ipc_sem_getvalue (conn_info->control_buffer, SEMAPHORE_REQUEST, &sem_value);
		if (sem_value > 0) {
		
			res = ipc_sem_wait (conn_info->control_buffer, SEMAPHORE_REQUEST, IPC_SEMWAIT_NOFILE);
		} else {
			continue;
		}
	
		zerocopy_operations_process (conn_info, &header, &new_message);
		/*
		 * There is no new message to process, continue for loop
		 */
		if (new_message == 0) {
			continue;
		}

		coroipcs_refcount_inc (conn);

		send_ok = api->sending_allowed (conn_info->service,
			header->id,
			header,
			conn_info->sending_allowed_private_data);

		/*
		 * This happens when the message contains some kind of invalid
		 * parameter, such as an invalid size
		 */
		if (send_ok == -1) {
			api->stats_increment_value (conn_info->stats_handle, "invalid_request");
			coroipc_response_header.size = sizeof (coroipc_response_header_t);
			coroipc_response_header.id = 0;
			coroipc_response_header.error = CS_ERR_INVALID_PARAM;
			coroipcs_response_send (conn_info,
				&coroipc_response_header,
				sizeof (coroipc_response_header_t));
		} else 
		if (send_ok) {
			api->stats_increment_value (conn_info->stats_handle, "requests");
			api->serialize_lock();
			api->handler_fn_get (conn_info->service, header->id) (conn_info, header);
			api->serialize_unlock();
		} else {
			/*
			 * Overload, tell library to retry
			 */
			api->stats_increment_value (conn_info->stats_handle, "overload");
			coroipc_response_header.size = sizeof (coroipc_response_header_t);
			coroipc_response_header.id = 0;
			coroipc_response_header.error = CS_ERR_TRY_AGAIN;
			coroipcs_response_send (conn_info,
				&coroipc_response_header,
				sizeof (coroipc_response_header_t));
		}

		api->sending_allowed_release (conn_info->sending_allowed_private_data);
		coroipcs_refcount_dec (conn);
	}
	pthread_exit (0);
}