Separated Architecture independent thread controll into the root of the tree
[tpg/acess2.git] / Kernel / messages.c
1 /*
2  * AcessOS Microkernel Version
3  * messages.c
4  */
5 #include <common.h>
6 #include <proc.h>
7 #include <errno.h>
8
9 // === CODE ===
10 /**
11  * \fn int Proc_SendMessage(Uint *Err, Uint Dest, int Length, void *Data)
12  * \brief Send an IPC message
13  * \param Err   Pointer to the errno variable
14  * \param Dest  Destination Thread
15  */
16 int Proc_SendMessage(Uint *Err, Uint Dest, int Length, void *Data)
17 {
18         tThread *thread;
19         tMsg    *msg;
20         
21         Log("Proc_SendMessage: (Err=%p, Dest=%i, Length=%i, Data=%p)", Err, Dest, Length, Data);
22         
23         if(Length <= 0 || !Data) {
24                 *Err = -EINVAL;
25                 return -1;
26         }
27         
28         // Get thread
29         thread = Threads_GetThread( Dest );
30         
31         // Error check
32         if(!thread) {   return -1;      }
33         
34         // Get Spinlock
35         LOCK( &thread->IsLocked );
36         
37         // Check if thread is still alive
38         if(thread->Status == THREAD_STAT_DEAD)  return -1;
39         
40         // Create message
41         msg = malloc( sizeof(tMsg)+Length );
42         msg->Next = NULL;
43         msg->Source = Proc_GetCurThread()->TID;
44         msg->Length = Length;
45         memcpy(msg->Data, Data, Length);
46         
47         // If there are already messages
48         if(thread->LastMessage) {
49                 thread->LastMessage->Next = msg;
50                 thread->LastMessage = msg;
51         } else {
52                 thread->Messages = msg;
53                 thread->LastMessage = msg;
54         }
55         
56         RELEASE(&thread->IsLocked);
57         
58         Threads_Wake( thread );
59         
60         return 0;
61 }
62
63 /**
64  * \fn int Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer)
65  * \brief Gets a message
66  */
67 int Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer)
68 {
69          int    ret;
70         void *tmp;
71         tThread *cur = Proc_GetCurThread();
72         
73         // Check if queue has any items
74         if(!cur->Messages) {
75                 return 0;
76         }
77
78         LOCK( &cur->IsLocked );
79         
80         if(Source)
81                 *Source = cur->Messages->Source;
82         
83         // Get message length
84         if( !Buffer ) {
85                 ret = cur->Messages->Length;
86                 RELEASE( &cur->IsLocked );
87                 return ret;
88         }
89         
90         // Get message
91         if(Buffer != GETMSG_IGNORE)
92                 memcpy(Buffer, cur->Messages->Data, cur->Messages->Length);
93         ret = cur->Messages->Length;
94         
95         // Remove from list
96         tmp = cur->Messages->Next;
97         free(cur->Messages);
98         cur->Messages = tmp;
99         
100         RELEASE( &cur->IsLocked );
101         
102         return ret;
103 }

UCC git Repository :: git.ucc.asn.au