2 * AcessOS Microkernel Version
8 #include <threads_int.h>
12 extern tShortSpinlock glThreadListLock;
16 * \fn int Proc_SendMessage(Uint *Err, Uint Dest, int Length, void *Data)
17 * \brief Send an IPC message
18 * \param Err Pointer to the errno variable
19 * \param Dest Destination Thread
20 * \param Length Length of the message
21 * \param Data Message data
23 int Proc_SendMessage(Uint *Err, Uint Dest, int Length, void *Data)
28 ENTER("pErr iDest iLength pData", Err, Dest, Length, Data);
30 if(Length <= 0 || !Data) {
36 thread = Threads_GetThread( Dest );
39 if(!thread) LEAVE_RET('i', -1);
42 SHORTLOCK( &thread->IsLocked );
44 // Check if thread is still alive
45 if(thread->Status == THREAD_STAT_DEAD) {
46 SHORTREL( &thread->IsLocked );
51 msg = malloc( sizeof(tMsg)+Length );
53 msg->Source = Proc_GetCurThread()->TID;
55 memcpy(msg->Data, Data, Length);
57 // If there are already messages
58 if(thread->LastMessage) {
59 thread->LastMessage->Next = msg;
60 thread->LastMessage = msg;
62 thread->Messages = msg;
63 thread->LastMessage = msg;
66 SHORTREL(&thread->IsLocked);
68 SHORTLOCK(&glThreadListLock);
69 Threads_Wake( thread );
70 SHORTREL(&glThreadListLock);
76 * \fn int Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer)
77 * \brief Gets a message
78 * \param Err Pointer to \a errno
79 * \param Source Where to put the source TID
80 * \param Buffer Buffer to place the message data (set to NULL to just get message length)
82 int Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer)
86 tThread *cur = Proc_GetCurThread();
88 // Check if queue has any items
93 SHORTLOCK( &cur->IsLocked );
96 *Source = cur->Messages->Source;
100 ret = cur->Messages->Length;
101 SHORTREL( &cur->IsLocked );
106 if(Buffer != GETMSG_IGNORE)
108 if( !CheckMem( Buffer, cur->Messages->Length ) )
111 SHORTREL( &cur->IsLocked );
114 memcpy(Buffer, cur->Messages->Data, cur->Messages->Length);
116 ret = cur->Messages->Length;
120 cur->Messages = cur->Messages->Next;
122 SHORTREL( &cur->IsLocked );
124 free(tmp); // Free outside of lock