File:  [DragonFly] / src / sys / sys / msgport.h
Revision 1.16: download - view: text, annotated - select for diffs
Thu Apr 15 00:50:05 2004 UTC (10 years, 3 months ago) by dillon
Branches: MAIN
CVS tags: HEAD
Implement lwkt_abortmsg() support.  This function chases down a message and
marks it MSGF_ABORTED, requeuing it to its target port for abort reprocessing.
The chasedown may run through multiple message forwardings and even chase the
message all the way back to the reply port (in which case the abort becomes a
NOP).  The queueing of a replied message is delayed if there is an abort
chasing it down until the abort chasedown has caught up to the message.

Support MSGF_PCATCH in the default waitport function.  If a signal is pending,
lwkt_default_waitport() (the default assigned to mp_waitport) will request
a message abort.  Note that we still have to wait for the message to be
returned after requesting a message abort.

Also do some minor performance tuning and adjust or move some of the inlines
from msgport2.h into lwkt_msgport.c.

    1: /*
    2:  * SYS/MSGPORT.H
    3:  *
    4:  *	Implements LWKT messages and ports.
    5:  * 
    6:  * $DragonFly: src/sys/sys/msgport.h,v 1.16 2004/04/15 00:50:05 dillon Exp $
    7:  */
    8: 
    9: #ifndef _SYS_MSGPORT_H_
   10: #define _SYS_MSGPORT_H_
   11: 
   12: #ifndef _SYS_QUEUE_H_
   13: #include <sys/queue.h>		/* TAILQ_* macros */
   14: #endif
   15: #ifndef _SYS_STDINT_H_
   16: #include <sys/stdint.h>
   17: #endif
   18: 
   19: struct lwkt_msg;
   20: struct lwkt_port;
   21: struct thread;
   22: 
   23: typedef struct lwkt_msg		*lwkt_msg_t;
   24: typedef struct lwkt_port	*lwkt_port_t;
   25: 
   26: typedef TAILQ_HEAD(lwkt_msg_queue, lwkt_msg) lwkt_msg_queue;
   27: 
   28: /*
   29:  * The standard message and port structure for communications between
   30:  * threads.  See kern/lwkt_msgport.c for documentation on how messages and
   31:  * ports work.
   32:  *
   33:  * For the most part a message may only be manipulated by whomever currently
   34:  * owns it, which generally means the originating port if the message has
   35:  * not been sent yet or has been replied, and the target port if the message
   36:  * has been sent and/or is undergoing processing.
   37:  *
   38:  * The one exception to this rule is an abort.  Aborts must be initiated
   39:  * by the originator and may 'chase' the target (especially if a message
   40:  * is being forwarded), potentially even 'chase' the message all the way
   41:  * back to the originator if it races against the target replying the
   42:  * message.  The ms_abort_port field is the only field that may be modified
   43:  * by the originator or intermediate target (when the abort is chasing
   44:  * a forwarding or reply op).  An abort may cause a reply to be delayed
   45:  * until the abort catches up to it.
   46:  *
   47:  * Finally, note that an abort can requeue a message to its current target
   48:  * port after the message has been pulled off of it, so you CANNOT use
   49:  * ms_node for your own purposes after you have pulled a message request
   50:  * off its port.
   51:  *
   52:  * NOTE! 64-bit-align this structure.
   53:  */
   54: typedef struct lwkt_msg {
   55:     TAILQ_ENTRY(lwkt_msg) ms_node;	/* link node (see note above) */
   56:     union {
   57: 	struct lwkt_msg *ms_next;	/* chaining / cache */
   58: 	union sysunion	*ms_sysunnext;	/* chaining / cache */
   59: 	struct lwkt_msg	*ms_umsg;	/* user message (UVA address) */
   60:     } opaque;
   61:     lwkt_port_t ms_target_port;		/* current target or relay port */
   62:     lwkt_port_t	ms_reply_port;		/* async replies returned here */
   63:     lwkt_port_t ms_abort_port;		/* abort chasing port */
   64:     int		ms_cmd;			/* message command */
   65:     int		ms_flags;		/* message flags */
   66: #define ms_copyout_start	ms_msgsize
   67:     int		ms_msgsize;		/* size of message */
   68:     int		ms_error;		/* positive error code or 0 */
   69:     union {
   70: 	void	*ms_resultp;		/* misc pointer data or result */
   71: 	int	ms_result;		/* standard 'int'eger result */
   72: 	long	ms_lresult;		/* long result */
   73: 	int	ms_fds[2];		/* two int bit results */
   74: 	__int32_t ms_result32;		/* 32 bit result */
   75: 	__int64_t ms_result64;		/* 64 bit result */
   76: 	__off_t	ms_offset;		/* off_t result */
   77:     } u;
   78: #define ms_copyout_end	ms_pad[0]
   79:     int		ms_pad[2];		/* future use */
   80: } lwkt_msg;
   81: 
   82: #define ms_copyout_size	(offsetof(struct lwkt_msg, ms_copyout_end) - offsetof(struct lwkt_msg, ms_copyout_start))
   83: 
   84: #define MSGF_DONE	0x0001		/* asynch message is complete */
   85: #define MSGF_REPLY1	0x0002		/* asynch message has been returned */
   86: #define MSGF_QUEUED	0x0004		/* message has been queued sanitychk */
   87: #define MSGF_ASYNC	0x0008		/* sync/async hint */
   88: #define MSGF_ABORTED	0x0010		/* message was aborted flag */
   89: #define MSGF_PCATCH	0x0020		/* catch proc signal while waiting */
   90: #define MSGF_REPLY2	0x0040		/* reply processed by rport cpu */
   91: 
   92: #define MSG_CMD_CDEV	0x00010000
   93: #define MSG_CMD_VFS	0x00020000
   94: #define MSG_CMD_SYSCALL	0x00030000
   95: #define MSG_CMD_NETMSG	0x00040000
   96: #define MSG_SUBCMD_MASK	0x0000FFFF
   97: 
   98: #ifdef _KERNEL
   99: #ifdef MALLOC_DECLARE
  100: MALLOC_DECLARE(M_LWKTMSG);
  101: #endif
  102: #endif
  103: 
  104: typedef struct lwkt_port {
  105:     lwkt_msg_queue	mp_msgq;
  106:     int			mp_flags;
  107:     int			mp_refs;	/* references to port structure */
  108:     struct thread	*mp_td;
  109:     int			(*mp_putport)(lwkt_port_t, lwkt_msg_t);
  110:     void *		(*mp_waitport)(lwkt_port_t, lwkt_msg_t);
  111:     void		(*mp_replyport)(lwkt_port_t, lwkt_msg_t);
  112:     void		(*mp_abortport)(lwkt_port_t, lwkt_msg_t);
  113: } lwkt_port;
  114: 
  115: #define MSGPORTF_WAITING	0x0001
  116: 
  117: /*
  118:  * These functions are good for userland as well as the kernel.  The 
  119:  * messaging function support for userland is provided by the kernel's
  120:  * kern/lwkt_msgport.c.  The port functions are provided by userland.
  121:  */
  122: void lwkt_initport(lwkt_port_t, struct thread *);
  123: void lwkt_sendmsg(lwkt_port_t, lwkt_msg_t);
  124: int lwkt_domsg(lwkt_port_t, lwkt_msg_t);
  125: int lwkt_forwardmsg(lwkt_port_t, lwkt_msg_t);
  126: void lwkt_abortmsg(lwkt_msg_t);
  127: void *lwkt_getport(lwkt_port_t);
  128: 
  129: int lwkt_default_putport(lwkt_port_t port, lwkt_msg_t msg);
  130: void *lwkt_default_waitport(lwkt_port_t port, lwkt_msg_t msg);
  131: void lwkt_default_replyport(lwkt_port_t port, lwkt_msg_t msg);
  132: void lwkt_default_abortport(lwkt_port_t port, lwkt_msg_t msg);
  133: 
  134: #endif