- Inserted some USB3 hub class request skeletons
[AROS.git] / rom / exec / putmsg.c
blobc37eb85f963e66f23e0e29a162163ca071be2e73
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Send a message to a port.
6 Lang: english
7 */
9 #define DEBUG 0
10 #include <aros/debug.h>
12 #include <aros/libcall.h>
13 #include <exec/ports.h>
14 #include <proto/exec.h>
16 #include "exec_intern.h"
17 #include "exec_util.h"
19 /*****************************************************************************
21 NAME */
23 AROS_LH2(void, PutMsg,
25 /* SYNOPSIS */
26 AROS_LHA(struct MsgPort *, port, A0),
27 AROS_LHA(struct Message *, message, A1),
29 /* LOCATION */
30 struct ExecBase *, SysBase, 61, Exec)
32 /* FUNCTION
33 Sends a message to a given message port. Messages are not copied
34 from one task to another but must lie in shared memory instead.
35 Therefore the owner of the message may generally not reuse it before
36 it is returned. But this depends on the two tasks sharing the message.
38 INPUTS
39 port - Pointer to messageport.
40 message - Pointer to message.
42 RESULT
44 NOTES
45 It is legal to send a message from within interrupts.
47 Messages may either trigger a signal at the owner of the messageport
48 or raise a software interrupt, depending on port->mp_Flags&PF_ACTION.
50 EXAMPLE
52 BUGS
54 SEE ALSO
55 WaitPort(), GetMsg()
57 INTERNALS
59 ******************************************************************************/
61 AROS_LIBFUNC_INIT
62 ASSERT_VALID_PTR(message);
63 ASSERT_VALID_PTR(port);
65 /* Set the node type to NT_MESSAGE == sent message. */
66 message->mn_Node.ln_Type = NT_MESSAGE;
68 InternalPutMsg(port, message, SysBase);
70 AROS_LIBFUNC_EXIT
71 } /* PutMsg() */
73 void InternalPutMsg(struct MsgPort *port, struct Message *message, struct ExecBase *SysBase)
76 * Add a message to the ports list.
77 * NB : Messages may be sent from interrupts, therefore
78 * the message list of the message port must be protected
79 * with Disable() for the local core, and also a spinlock
80 * on smp systems.
83 D(bug("[EXEC] PutMsg: Port @ 0x%p, Msg @ 0x%p\n", port, message);)
85 Disable();
86 #if defined(__AROSEXEC_SMP__)
87 EXEC_SPINLOCK_LOCK(&port->mp_SpinLock, NULL, SPINLOCK_MODE_WRITE);
88 #endif
89 AddTail(&port->mp_MsgList, &message->mn_Node);
90 D(bug("[EXEC] PutMsg: Port MsgList->lh_TailPred = 0x%p\n", port->mp_MsgList.lh_TailPred);)
91 #if defined(__AROSEXEC_SMP__)
92 EXEC_SPINLOCK_UNLOCK(&port->mp_SpinLock);
93 #endif
94 Enable();
96 if (port->mp_SigTask)
98 ASSERT_VALID_PTR(port->mp_SigTask);
100 /* And trigger the action. */
101 switch(port->mp_Flags & PF_ACTION)
103 case PA_SIGNAL:
104 D(bug("[EXEC] PutMsg: PA_SIGNAL -> Task 0x%p, Signal %08x\n", port->mp_SigTask, (1 << port->mp_SigBit));)
106 /* Send the signal */
107 Signal((struct Task *)port->mp_SigTask, (1 << port->mp_SigBit));
108 break;
110 case PA_SOFTINT:
111 D(bug("[EXEC] PutMsg: PA_SOFTINT -> Int %s\n", ((struct Interrupt *)port->mp_SoftInt)->is_Node.ln_Name);)
113 /* Raise a software interrupt */
114 Cause((struct Interrupt *)port->mp_SoftInt);
115 break;
117 case PA_IGNORE:
118 /* Do nothing. */
119 break;
121 case PA_CALL:
122 D(bug("[EXEC] PutMsg: PA_CALL -> Func @ 0x%p\n", port->mp_SigTask, port);)
124 #if defined(__AROSEXEC_SMP__)
125 //TODO! - the called function must be SMP safe.
126 #endif
127 /* Call the function in mp_SigTask. */
128 AROS_UFC2NR(void, port->mp_SigTask,
129 AROS_UFCA(struct MsgPort *, port, D0),
130 AROS_UFCA(struct ExecBase *, SysBase, A6));
131 break;