SpiderScript: Working on dumping the AST to disk
[tpg/acess2.git] / Kernel / messages.c
1 /*
2  * AcessOS Microkernel Version
3  * messages.c
4  */
5 #include <acess.h>
6 #include <threads.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  * \param Length        Length of the message
16  * \param Data  Message data
17  */
18 int Proc_SendMessage(Uint *Err, Uint Dest, int Length, void *Data)
19 {
20         tThread *thread;
21         tMsg    *msg;
22         
23         Log("Proc_SendMessage: (Err=%p, Dest=%i, Length=%i, Data=%p)", Err, Dest, Length, Data);
24         
25         if(Length <= 0 || !Data) {
26                 *Err = -EINVAL;
27                 return -1;
28         }
29         
30         // Get thread
31         thread = Threads_GetThread( Dest );
32         
33         // Error check
34         if(!thread) {   return -1;      }
35         
36         // Get Spinlock
37         SHORTLOCK( &thread->IsLocked );
38         
39         // Check if thread is still alive
40         if(thread->Status == THREAD_STAT_DEAD) {
41                 SHORTREL( &thread->IsLocked );
42                 return -1;
43         }
44         
45         // Create message
46         msg = malloc( sizeof(tMsg)+Length );
47         msg->Next = NULL;
48         msg->Source = Proc_GetCurThread()->TID;
49         msg->Length = Length;
50         memcpy(msg->Data, Data, Length);
51         
52         // If there are already messages
53         if(thread->LastMessage) {
54                 thread->LastMessage->Next = msg;
55                 thread->LastMessage = msg;
56         } else {
57                 thread->Messages = msg;
58                 thread->LastMessage = msg;
59         }
60         
61         SHORTREL(&thread->IsLocked);
62         
63         Threads_Wake( thread );
64         
65         return 0;
66 }
67
68 /**
69  * \fn int Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer)
70  * \brief Gets a message
71  * \param Err   Pointer to \a errno
72  * \param Source        Where to put the source TID
73  * \param Buffer        Buffer to place the message data (set to NULL to just get message length)
74  */
75 int Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer)
76 {
77          int    ret;
78         void    *tmp;
79         tThread *cur = Proc_GetCurThread();
80         
81         // Check if queue has any items
82         if(!cur->Messages) {
83                 return 0;
84         }
85
86         SHORTLOCK( &cur->IsLocked );
87         
88         if(Source)
89                 *Source = cur->Messages->Source;
90         
91         // Get message length
92         if( !Buffer ) {
93                 ret = cur->Messages->Length;
94                 SHORTREL( &cur->IsLocked );
95                 return ret;
96         }
97         
98         // Get message
99         if(Buffer != GETMSG_IGNORE)
100         {
101                 if( !CheckMem( Buffer, cur->Messages->Length ) )
102                 {
103                         *Err = -EINVAL;
104                         SHORTREL( &cur->IsLocked );
105                         return -1;
106                 }
107                 memcpy(Buffer, cur->Messages->Data, cur->Messages->Length);
108         }
109         ret = cur->Messages->Length;
110         
111         // Remove from list
112         tmp = cur->Messages;
113         cur->Messages = cur->Messages->Next;
114         
115         SHORTREL( &cur->IsLocked );
116         
117         free(tmp);      // Free outside of lock
118         
119         return ret;
120 }

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