2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
5 Desc: Send a message to a port.
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 /*****************************************************************************
23 AROS_LH2(void, PutMsg
,
26 AROS_LHA(struct MsgPort
*, port
, A0
),
27 AROS_LHA(struct Message
*, message
, A1
),
30 struct ExecBase
*, SysBase
, 61, Exec
)
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.
39 port - Pointer to messageport.
40 message - Pointer to message.
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.
59 ******************************************************************************/
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
);
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
83 D(bug("[EXEC] PutMsg: Port @ 0x%p, Msg @ 0x%p\n", port
, message
);)
86 #if defined(__AROSEXEC_SMP__)
87 EXEC_SPINLOCK_LOCK(&port
->mp_SpinLock
, NULL
, SPINLOCK_MODE_WRITE
);
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
);
98 ASSERT_VALID_PTR(port
->mp_SigTask
);
100 /* And trigger the action. */
101 switch(port
->mp_Flags
& PF_ACTION
)
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
));
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
);
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.
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
));