⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pipe.c

📁 xenomai 很好的linux实时补丁
💻 C
📖 第 1 页 / 共 3 页
字号:
 */int rt_pipe_delete (RT_PIPE *pipe){    int err;    spl_t s;    if (xnpod_asynch_p())	return -EPERM;    xnlock_get_irqsave(&nklock,s);    pipe = xeno_h2obj_validate(pipe,XENO_PIPE_MAGIC,RT_PIPE);    if (!pipe)	{	err = xeno_handle_error(pipe,XENO_PIPE_MAGIC,RT_PIPE);       xnlock_put_irqrestore(&nklock,s);       return err;	}    if (__test_and_clear_bit(0,&pipe->flushable))	{	/* Purge data waiting for flush. */	removeq(&__pipe_flush_q,&pipe->link);       rt_pipe_free(pipe,pipe->buffer);	}    err = xnpipe_disconnect(pipe->minor);#ifdef CONFIG_XENO_OPT_REGISTRY    if (pipe->handle)        xnregistry_remove(pipe->handle);#endif /* CONFIG_XENO_OPT_REGISTRY */    xeno_mark_deleted(pipe);    xnlock_put_irqrestore(&nklock,s);    if (pipe->bufpool == &pipe->privpool)       xnheap_destroy(&pipe->privpool,__pipe_flush_pool,NULL);    return err;}/** * @fn ssize_t rt_pipe_receive(RT_PIPE *pipe,RT_PIPE_MSG **msgp,RTIME timeout) * * @brief Receive a message from a pipe. * * This service retrieves the next message written to the associated * special device in user-space. rt_pipe_receive() always preserves * message boundaries, which means that all data sent through the same * write(2) operation to the special device will be gathered in a * single message by this service. This service differs from * rt_pipe_read() in that it returns a pointer to the internal buffer * holding the message, which improves performances by saving a data * copy to a user-provided buffer, especially when large messages are * involved. * * Unless otherwise specified, the caller is blocked for a given * amount of time if no data is immediately available on entry. * * @param pipe The descriptor address of the pipe to receive from. * * @param msgp A pointer to a memory location which will be written * upon success with the address of the received message. Once * consumed, the message space should be freed using rt_pipe_free(). * The application code can retrieve the actual data and size carried * by the message by respectively using the P_MSGPTR() and P_MSGSIZE() * macros. * * @param timeout The number of clock ticks to wait for some message * to arrive (see note). Passing TM_INFINITE causes the caller to * block indefinitely until some data is eventually available. Passing * TM_NONBLOCK causes the service to return immediately without * waiting if no data is available on entry. * * @return The number of read bytes available from the received * message is returned upon success; this value will be equal to * P_MSGSIZE(*msgp). Otherwise: * * - -EINVAL is returned if @a pipe is not a pipe descriptor. * * - -EIDRM is returned if @a pipe is a closed pipe descriptor. * * - -ENODEV or -EBADF are returned if @a pipe is scrambled. * * - -ETIMEDOUT is returned if @a timeout is different from * TM_NONBLOCK and no data is available within the specified amount of * time. * * - -EWOULDBLOCK is returned if @a timeout is equal to TM_NONBLOCK * and no data is immediately available on entry. * * - -EINTR is returned if rt_task_unblock() has been called for the * waiting task before any data was available. * * - -EPERM is returned if this service should block, but was called * from a context which cannot sleep (e.g. interrupt, non-realtime or * scheduler locked). * * Environments: * * This service can be called from: * * - Kernel module initialization/cleanup code * - Interrupt service routine *   only if @a timeout is equal to TM_NONBLOCK. * * - Kernel-based task * * Rescheduling: always unless the request is immediately satisfied or * @a timeout specifies a non-blocking operation. * * @note This service is sensitive to the current operation mode of * the system timer, as defined by the rt_timer_start() service. In * periodic mode, clock ticks are interpreted as periodic jiffies. In * oneshot mode, clock ticks are interpreted as nanoseconds. */ssize_t rt_pipe_receive (RT_PIPE *pipe,			 RT_PIPE_MSG **msgp,			 RTIME timeout){    ssize_t n;    spl_t s;    if (timeout != TM_NONBLOCK && xnpod_unblockable_p())	return -EPERM;    xnlock_get_irqsave(&nklock,s);    pipe = xeno_h2obj_validate(pipe,XENO_PIPE_MAGIC,RT_PIPE);    if (!pipe)	{	n = xeno_handle_error(pipe,XENO_PIPE_MAGIC,RT_PIPE);	goto unlock_and_exit;	}    n = xnpipe_recv(pipe->minor,msgp,timeout); unlock_and_exit:    xnlock_put_irqrestore(&nklock,s);    return n;}/** * @fn ssize_t rt_pipe_read(RT_PIPE *pipe,void *buf,size_t size,RTIME timeout) * * @brief Read a message from a pipe. * * This service retrieves the next message written to the associated * special device in user-space. rt_pipe_read() always preserves * message boundaries, which means that all data sent through the same * write(2) operation to the special device will be gathered in a * single message by this service. This services differs from * rt_pipe_receive() in that it copies back the payload data to a * user-defined memory area, instead of returning a pointer to the * internal message buffer holding such data. * * Unless otherwise specified, the caller is blocked for a given * amount of time if no data is immediately available on entry. * * @param pipe The descriptor address of the pipe to read from. * * @param buf A pointer to a memory location which will be written * upon success with the read message contents. * * @param size The count of bytes from the received message to read up * into @a buf. If @a size is lower than the actual message size, * -ENOBUFS is returned since the incompletely received message would * be lost. If @a size is zero, this call returns immediately with no * other action. * * @param timeout The number of clock ticks to wait for some message * to arrive (see note). Passing TM_INFINITE causes the caller to * block indefinitely until some data is eventually available. Passing * TM_NONBLOCK causes the service to return immediately without * waiting if no data is available on entry. * * @return The number of read bytes copied to the @a buf is returned * upon success. Otherwise: * * - -EINVAL is returned if @a pipe is not a pipe descriptor. * * - -EIDRM is returned if @a pipe is a closed pipe descriptor. * * - -ENODEV or -EBADF are returned if @a pipe is scrambled. * * - -ETIMEDOUT is returned if @a timeout is different from * TM_NONBLOCK and no data is available within the specified amount of * time. * * - -EWOULDBLOCK is returned if @a timeout is equal to TM_NONBLOCK * and no data is immediately available on entry. * * - -EINTR is returned if rt_task_unblock() has been called for the * waiting task before any data was available. * * - -EPERM is returned if this service should block, but was called * from a context which cannot sleep (e.g. interrupt, non-realtime or * scheduler locked). * * - -ENOBUFS is returned if @a size is not large enough to collect the * message data. * * Environments: * * This service can be called from: * * - Kernel module initialization/cleanup code * - Interrupt service routine *   only if @a timeout is equal to TM_NONBLOCK. * * - Kernel-based task * - User-space task (switches to primary mode) * * Rescheduling: always unless the request is immediately satisfied or * @a timeout specifies a non-blocking operation. * * @note This service is sensitive to the current operation mode of * the system timer, as defined by the rt_timer_start() service. In * periodic mode, clock ticks are interpreted as periodic jiffies. In * oneshot mode, clock ticks are interpreted as nanoseconds. */ssize_t rt_pipe_read (RT_PIPE *pipe,		      void *buf,		      size_t size,		      RTIME timeout){    RT_PIPE_MSG *msg;    ssize_t nbytes;    if (size == 0)	return 0;    nbytes = rt_pipe_receive(pipe,&msg,timeout);    if (nbytes < 0)	return nbytes;    if (size < P_MSGSIZE(msg))	nbytes = -ENOBUFS;    else if (P_MSGSIZE(msg) > 0)	memcpy(buf,P_MSGPTR(msg),P_MSGSIZE(msg));    /* Zero-sized messages are allowed, so we still need to free the       message buffer even if no data copy took place. */    rt_pipe_free(pipe,msg);    return nbytes;} /** * @fn ssize_t rt_pipe_send(RT_PIPE *pipe,RT_PIPE_MSG *msg,size_t size,int mode) * * @brief Send a message through a pipe. * * This service writes a complete message to be received from the * associated special device. rt_pipe_send() always preserves message * boundaries, which means that all data sent through a single call of * this service will be gathered in a single read(2) operation from * the special device. This service differs from rt_pipe_write() in * that it accepts a canned message buffer, instead of a pointer to * the raw data to be sent. This call is useful whenever the caller * wants to prepare the message contents separately from its sending, * which does not require to have all the data to be sent available at * once but allows for incremental updates of the message, and also * saves a message copy, since rt_pipe_send() deals internally with * message buffers. * * @param pipe The descriptor address of the pipe to send to. * * @param msg The address of the message to be sent.  The message * space must have been allocated using the rt_pipe_alloc() service. * Once passed to rt_pipe_send(), the memory pointed to by @a msg is * no more under the control of the application code and thus should * not be referenced by it anymore; deallocation of this memory will * be automatically handled as needed. As a special exception, @a msg * can be NULL and will not be dereferenced if @a size is zero. * * @param size The size in bytes of the message (payload data * only). Zero is a valid value, in which case the service returns * immediately without sending any message. This parameter allows * you to actually send less data than you reserved using the * rt_pipe_alloc() service, which may be the case if you did not * know how much space you needed at the time of allocation. In all * other cases it may be more convenient to just pass P_MSGSIZE(msg). * * Additionally, rt_pipe_send() causes any data buffered by * rt_pipe_stream() to be flushed prior to sending the message. For * this reason, rt_pipe_send() can return a non-zero byte count to the * caller if some pending data has been flushed, even if @a size was * zero on entry. * * @param mode A set of flags affecting the operation: * * - P_URGENT causes the message to be prepended to the output * queue, ensuring a LIFO ordering. * * - P_NORMAL causes the message to be appended to the output * queue, ensuring a FIFO ordering. * * @return Upon success, this service returns @a size if the latter is * non-zero, or the number of bytes flushed otherwise. Upon error, one * of the following error codes is returned: * * - -EINVAL is returned if @a pipe is not a pipe descriptor. * * - -EPIPE is returned if the associated special device is not yet * open. * * - -EIDRM is returned if @a pipe is a closed pipe descriptor. * * - -ENODEV or -EBADF are returned if @a pipe is scrambled. * * Environments: * * This service can be called from: * * - Kernel module initialization/cleanup code * - Interrupt service routine * - Kernel-based task * * Rescheduling: possible. */ssize_t rt_pipe_send (RT_PIPE *pipe,		      RT_PIPE_MSG *msg,		      size_t size,		      int mode){    ssize_t n = 0;    spl_t s;    xnlock_get_irqsave(&nklock,s);    pipe = xeno_h2obj_validate(pipe,XENO_PIPE_MAGIC,RT_PIPE);    if (!pipe)	{	n = xeno_handle_error(pipe,XENO_PIPE_MAGIC,RT_PIPE);	goto unlock_and_exit;	}    if (__test_and_clear_bit(0,&pipe->flushable))	{	removeq(&__pipe_flush_q,&pipe->link);	n = __pipe_flush(pipe);	if (n < 0)	    goto unlock_and_exit;	}    if (size > 0)	/* We need to add the size of the message header here. */	n = xnpipe_send(pipe->minor,msg,size + sizeof(RT_PIPE_MSG),mode); unlock_and_exit:    xnlock_put_irqrestore(&nklock,s);    return n <= 0 ? n : n - sizeof(RT_PIPE_MSG);} /** * @fn ssize_t rt_pipe_write(RT_PIPE *pipe,const void *buf,size_t size,int mode) * * @brief Write a message to a pipe. * * This service writes a complete message to be received from the

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -