示例#1
0
/***
 *  rt_packet_recvmsg
 */
ssize_t rt_packet_recvmsg(struct rtdm_dev_context *sockctx,
                          rtdm_user_info_t *user_info, struct msghdr *msg,
                          int msg_flags)
{
    struct rtsocket     *sock = (struct rtsocket *)&sockctx->dev_private;
    size_t              len   = rt_iovec_len(msg->msg_iov, msg->msg_iovlen);
    size_t              copy_len;
    size_t              real_len;
    struct rtskb        *skb;
    struct ethhdr       *eth;
    struct sockaddr_ll  *sll;
    int                 ret;
    nanosecs_t          timeout = sock->timeout;


    /* non-blocking receive? */
    if (testbits(msg_flags, MSG_DONTWAIT))
        timeout = -1;

    ret = rtdm_sem_timeddown(&sock->pending_sem, timeout, NULL);
    if (unlikely(ret < 0)) {
        if ((ret != -EWOULDBLOCK) && (ret != -ETIMEDOUT))
            ret = -EBADF;   /* socket has been closed */
        return ret;
    }

    skb = rtskb_dequeue_chain(&sock->incoming);
    RTNET_ASSERT(skb != NULL, return -EFAULT;);
示例#2
0
/***
 *  rt_packet_recvmsg
 */
static ssize_t
rt_packet_recvmsg(struct rtdm_fd *fd, struct msghdr *msg, int msg_flags)
{
    struct rtsocket     *sock = rtdm_fd_to_private(fd);
    size_t              len   = rt_iovec_len(msg->msg_iov, msg->msg_iovlen);
    size_t              copy_len;
    size_t              real_len;
    struct rtskb        *rtskb;
    struct sockaddr_ll  *sll;
    int                 ret;
    nanosecs_rel_t      timeout = sock->timeout;


    /* non-blocking receive? */
    if (msg_flags & MSG_DONTWAIT)
	timeout = -1;

    ret = rtdm_sem_timeddown(&sock->pending_sem, timeout, NULL);
    if (unlikely(ret < 0))
	switch (ret) {
	    case -EWOULDBLOCK:
	    case -ETIMEDOUT:
	    case -EINTR:
		return ret;

	    default:
		return -EBADF;   /* socket has been closed */
	}

    rtskb = rtskb_dequeue_chain(&sock->incoming);
    RTNET_ASSERT(rtskb != NULL, return -EFAULT;);
示例#3
0
文件: semtest.c 项目: ArcEye/RTAI
void task2(void *cookie)
{
	long i, max;
	nanosecs_abs_t t, dt;

	rt_printk("TESTING TIMING OUT TIMEDDOWN ...");
	for (max = i = 0; i < LOOPS; i++) {
		t = rtdm_clock_read();
		if (rtdm_sem_timeddown(&sem2, DELAY, NULL) == -ETIMEDOUT) {
			dt = rtdm_clock_read() - t - DELAY;
			if (dt > max) {
				max = dt;
			}
		} else {
			break;
		}
	}
	if (i == LOOPS) {
		rt_printk(" OK [%lu (ns)].\n", max);
	} else {
		rt_printk(" NOT OK [MAXLAT %lu (ns)].\n", max);
	}

	rt_printk("TESTING FAILING TRY DOWN ...");
	for (i = 0; i < LOOPS; i++) {
		if (rtdm_sem_timeddown(&sem2, RTDM_TIMEOUT_NONE, NULL) != -EWOULDBLOCK) {
			break;
		}
	}
	if (i == LOOPS) {
		rt_printk(" OK.\n");
	} else {
		rt_printk(" NOT OK.\n", max);
	}

	rt_printk("TESTING SUCCEEDING TRY DOWN ...");
	rtdm_sem_up(&sem2);
	for (i = 0; i < LOOPS; i++) {
		if (!rtdm_sem_timeddown(&sem2, RTDM_TIMEOUT_NONE, NULL)) {
			rtdm_sem_up(&sem2);
		} else {
			break;
		}
	}
	if (i == LOOPS) {
		rt_printk(" OK.\n");
	} else {
		rt_printk(" NOT OK.\n", max);
	}

	rt_printk("TESTING DOWN/UP ...");
	rtdm_sem_down(&sem2);
	for (i = 0; i < LOOPS; i++) {
		rtdm_sem_up(&sem1);
		if (rtdm_sem_down(&sem2)) {
			break;
		}
	}
	if (i == LOOPS) {
		rt_printk(" OK.\n");
	} else {
		rt_printk(" NOT OK.\n", max);
	}

	rt_printk("TESTING NOT TIMING OUT TIMEDDOWN ...");
	for (i = 0; i < LOOPS; i++) {
		rtdm_sem_up(&sem1);
		if (rtdm_sem_timeddown(&sem2, DELAY, NULL)) {
			break;
		}
	}
	if (i == LOOPS) {
		rt_printk(" OK.\n");
	} else {
		rt_printk(" NOT OK.\n", max);
	}
}
示例#4
0
static int rtdmtest_ioctl(struct rtdm_dev_context *context,
			  rtdm_user_info_t *user_info,
			  unsigned int request,
			  void *arg)
{
	struct rtdmtest_context *ctx;
	struct rttst_rtdmtest_config config_buf, *config;
	rtdm_toseq_t toseq_local, *toseq = NULL;
	int i, err = 0;

	ctx = (struct rtdmtest_context *)context->dev_private;

	switch (request) {
	case RTTST_RTIOC_RTDMTEST_SEM_TIMEDDOWN:
	case RTTST_RTIOC_RTDMTEST_EVENT_TIMEDWAIT:
        case RTTST_RTIOC_RTDMTEST_MUTEX_TIMEDTEST:
        case RTTST_RTIOC_RTDMTEST_MUTEX_TEST:
		config = arg;
		if (user_info) {
			if (rtdm_safe_copy_from_user
			    (user_info, &config_buf, arg,
			     sizeof(struct rttst_rtdmtest_config)) < 0)
				return -EFAULT;

			config = &config_buf;
		}
		if (!config->seqcount)
			config->seqcount = 1;
		if (config->timeout && config->seqcount > 1) {
			toseq = &toseq_local;
			rtdm_toseq_init(toseq, config->timeout);
		}
		switch(request) {
		case RTTST_RTIOC_RTDMTEST_SEM_TIMEDDOWN:
			for (i = 0; i < config->seqcount; i++) {
				err = rtdm_sem_timeddown(&ctx->sem,
							 config->timeout,
							 toseq);
				if (err)
					break;
			}
			break;
		case RTTST_RTIOC_RTDMTEST_EVENT_TIMEDWAIT:
			for (i = 0; i < config->seqcount; i++) {
				err = rtdm_event_timedwait(&ctx->event,
							   config->timeout,
							   toseq);
				if (err)
					break;
			}
			break;
		case RTTST_RTIOC_RTDMTEST_MUTEX_TIMEDTEST:
			for (i = 0; i < config->seqcount; i++) {
				err = rtdm_mutex_timedlock(&ctx->mutex,
							   config->timeout,
							   toseq);
				if (err)
					break;
				if (config->delay_jiffies) {
					__set_current_state(TASK_INTERRUPTIBLE);
					schedule_timeout(config->delay_jiffies);
				}
				rtdm_lock_count++;
				rtdm_mutex_unlock(&ctx->mutex);
			}
			break;
		case RTTST_RTIOC_RTDMTEST_MUTEX_TEST:
			for (i = 0; i < config->seqcount; i++) {
				if ((err = rtdm_mutex_lock(&ctx->mutex)))
					break;
				rtdm_lock_count++;
				rtdm_mutex_unlock(&ctx->mutex);
			}
			break;
		}
		break;

	case RTTST_RTIOC_RTDMTEST_SEM_DOWN:
		err = rtdm_sem_down(&ctx->sem);
		break;

	case RTTST_RTIOC_RTDMTEST_SEM_UP:
		rtdm_sem_up(&ctx->sem);
		break;

        case RTTST_RTIOC_RTDMTEST_SEM_DESTROY:
                rtdm_sem_destroy(&ctx->sem);
                break;

	case RTTST_RTIOC_RTDMTEST_EVENT_WAIT:
		err = rtdm_event_wait(&ctx->event);
		break;

	case RTTST_RTIOC_RTDMTEST_EVENT_SIGNAL:
		rtdm_event_signal(&ctx->event);
		break;

        case RTTST_RTIOC_RTDMTEST_EVENT_DESTROY:
                rtdm_event_destroy(&ctx->event);
                break;

        case RTTST_RTIOC_RTDMTEST_MUTEX_DESTROY:
                rtdm_mutex_destroy(&ctx->mutex);
                break;

        case RTTST_RTIOC_RTDMTEST_MUTEX_GETSTAT:
		printk("RTTST_RTIOC_RTDMTEST_MUTEX_GETSTAT\n");
		if (user_info)
			config = &config_buf;
		else
			config = arg;
		config->seqcount = rtdm_lock_count;
		if (user_info) {
			if (rtdm_safe_copy_to_user
			    (user_info, arg, &config_buf,
			     sizeof(struct rttst_rtdmtest_config)) < 0)
				return -EFAULT;
		}
                break;

        case RTTST_RTIOC_RTDMTEST_NRTSIG_PEND:
		rtdm_nrtsig_pend(&ctx->nrtsig);
                break;

        case RTTST_RTIOC_RTDMTEST_TASK_CREATE:
        case RTTST_RTIOC_RTDMTEST_TASK_SET_PRIO:
                config = arg;
                if (user_info) {
                        if (rtdm_safe_copy_from_user
                            (user_info, &config_buf, arg,
                             sizeof(struct rttst_rtdmtest_config)) < 0)
                                return -EFAULT;

                        config = &config_buf;
                }
		if (request == RTTST_RTIOC_RTDMTEST_TASK_CREATE) {
			task_period = config->timeout;
			rtdm_task_init(&task, "RTDMTEST",
				       rtdmtest_task, (void *)config,
				       config->priority, 0);
		} else {
			rtdm_task_set_priority(&task, config->priority);
		}
		break;

        case RTTST_RTIOC_RTDMTEST_TASK_DESTROY:
		rtdm_task_destroy(&task);
		rtdm_task_join_nrt(&task, 100);
                break;

	default:
		printk("request=%d\n", request);
		err = -ENOTTY;
	}

	return err;
}