Division bug hidden, now only shows when 64-bit division is needed
[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         LOCK( &thread->IsLocked );
38         
39         // Check if thread is still alive
40         if(thread->Status == THREAD_STAT_DEAD)  return -1;
41         
42         // Create message
43         msg = malloc( sizeof(tMsg)+Length );
44         msg->Next = NULL;
45         msg->Source = Proc_GetCurThread()->TID;
46         msg->Length = Length;
47         memcpy(msg->Data, Data, Length);
48         
49         // If there are already messages
50         if(thread->LastMessage) {
51                 thread->LastMessage->Next = msg;
52                 thread->LastMessage = msg;
53         } else {
54                 thread->Messages = msg;
55                 thread->LastMessage = msg;
56         }
57         
58         RELEASE(&thread->IsLocked);
59         
60         Threads_Wake( thread );
61         
62         return 0;
63 }
64
65 /**
66  * \fn int Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer)
67  * \brief Gets a message
68  * \param Err   Pointer to \a errno
69  * \param Source        Where to put the source TID
70  * \param Buffer        Buffer to place the message data (set to NULL to just get message length)
71  */
72 int Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer)
73 {
74          int    ret;
75         void *tmp;
76         tThread *cur = Proc_GetCurThread();
77         
78         // Check if queue has any items
79         if(!cur->Messages) {
80                 return 0;
81         }
82
83         LOCK( &cur->IsLocked );
84         
85         if(Source)
86                 *Source = cur->Messages->Source;
87         
88         // Get message length
89         if( !Buffer ) {
90                 ret = cur->Messages->Length;
91                 RELEASE( &cur->IsLocked );
92                 return ret;
93         }
94         
95         // Get message
96         if(Buffer != GETMSG_IGNORE)
97         {
98                 if( !CheckMem( Buffer, cur->Messages->Length ) )
99                 {
100                         *Err = -EINVAL;
101                         RELEASE( &cur->IsLocked );
102                         return -1;
103                 }
104                 memcpy(Buffer, cur->Messages->Data, cur->Messages->Length);
105         }
106         ret = cur->Messages->Length;
107         
108         // Remove from list
109         tmp = cur->Messages->Next;
110         free( (void*)cur->Messages );
111         cur->Messages = tmp;
112         
113         RELEASE( &cur->IsLocked );
114         
115         return ret;
116 }

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