Main Page | Data Structures | File List | Data Fields | Globals

opale_event.c

Go to the documentation of this file.
00001 // C Source File 00002 // Created 21/02/05; 19:16:17 00003 00004 #include "opale_internal.h" 00005 00013 static void EventInit( register t_EVENT* event asm("%a0"), register unsigned long initValue asm("%d0") ) 00014 { 00015 short i; /* just a counter */ 00016 unsigned char* ptr = event->waitingTasks.tasksTable; /* gets a pointer to the taskTable */ 00017 00018 event->waitingTasks.rowIndex = 0; /* sets the t_EVENT.waitingTasks.rowIndex field to 0 (no task is waiting for the event */ 00019 event->value = initValue; /* sets the t_EVENT.value to the wanted value */ 00020 00021 for( i = 0; i<_Y_; i++ ) /* clear the waitingTasks table */ 00022 { 00023 *ptr++ = 0; 00024 } 00025 } 00026 00031 void op_SemaphoreInit( register t_SEMAPHORE* semaphore asm("%a0"), register unsigned long initValue asm("%d0") ) 00032 { 00033 EventInit( (t_EVENT*)semaphore, initValue ); /* simple call to EventInit with a cast */ 00034 } 00035 00040 void op_MailBoxInit( register t_MAILBOX* mailbox asm("%a0"), register void* initMessage asm("%d0") ) 00041 { 00042 EventInit( (t_EVENT*)mailbox, (unsigned long)initMessage ); /* simple call to EventInit with a cast */ 00043 } 00044 00049 void op_QueueInit( register t_QUEUE* queue asm("%a0"), register void* buffer asm("%d0"), register unsigned short size asm("%d1") ) 00050 { 00051 EventInit( (t_EVENT*)queue, (unsigned long)buffer ); /* simple call to EventInit with a cast */ 00052 00053 queue->bufferSize = size; /* set the t_QUEUE.bufferSize field to the wanted size (maximum number of messages the queue can handle) */ 00054 queue->front = 0; /* set the t_QUEUE.front index to 0 */ 00055 queue->back = 0; /* set the t_QUEUE.back index to 0 */ 00056 queue->bufferUsage = 0; /* set the t_QUEUE.bufferUsage field to 0 (current number of messages in the queue */ 00057 } 00058 00063 void addTaskToTable( register t_TASK_BLOCK* table asm("%a0"), register unsigned char ident asm("%d0") ) 00064 { 00065 unsigned char x = identToX( ident ); /* get the X part of the ident of the task */ 00066 unsigned char y = identToY( ident ); /* get the Y part of the ident of the task */ 00067 00068 poke_bset( &table->tasksTable[ y ], x ); /* set the task's bit in the correct line of the table */ 00069 poke_bset( &table->rowIndex, y ); /* set the line's bit in the table index */ 00070 } 00071 00076 void removeTaskFromTable( register t_TASK_BLOCK* table asm("%a0"), register unsigned char ident asm("%d0") ) 00077 { 00078 unsigned char x = identToX( ident ); /* get the X part of the ident of the task */ 00079 unsigned char y = identToY( ident ); /* get the Y part of the ident of the task */ 00080 00081 poke_bclr( &table->tasksTable[ y ], x ); /* clear the task's bit in the correct line of the table */ 00082 if( !table->tasksTable[ y ] ) /* check if there is anymore bit setted on this line */ 00083 poke_bclr( &table->rowIndex, y ); /* if there is none, clears the line's bit in the table's index */ 00084 } 00085 00091 static void moveFromTable( register t_TASK_BLOCK* tableFrom asm("%a0"), register t_TASK_BLOCK* tableTo asm("%a1"), register unsigned char ident asm("d0") ) 00092 { 00093 addTaskToTable( tableTo, ident ); /* add the task to tableTo */ 00094 removeTaskFromTable( tableFrom, ident ); /* remove it from tableFrom */ 00095 00096 op_Scheduler(); /* since ready tasks waiting could have changed, call scheduler */ 00097 } 00098 00102 static void MakeTaskReady( register t_EVENT* event asm("%a0") ) 00103 { 00104 if( event->waitingTasks.rowIndex ) /* check if at least one task is waiting */ 00105 { 00106 00107 unsigned char y = indexToLowestSettedBit[ event->waitingTasks.rowIndex ]; 00108 unsigned char x = indexToLowestSettedBit[ event->waitingTasks.tasksTable[ y ] ]; 00109 00110 register unsigned char highestPriorityWaiting asm("%d0") = ( y << MASK_Y ) + x; /* find the highest priority task waiting for the event */ 00111 00112 moveFromTable( &event->waitingTasks, readyTasks, highestPriorityWaiting ); /* removes the task from the waiting queue and adds the task to the ready list */ 00113 } 00114 } 00115 00119 static void WaitForEvent( register t_EVENT* event asm("%a0") ) 00120 { 00121 /* removes the task from the ready queue and adds the task to the waiting list */ 00122 moveFromTable( readyTasks, &event->waitingTasks, currentTask->ident ); 00123 } 00124 00129 void op_SemaphorePost( register t_SEMAPHORE* semaphore asm("%a0") ) 00130 { 00131 00132 op_EnterCriticalSection(); 00133 00134 semaphore->count++; 00135 00136 MakeTaskReady( (t_EVENT*)semaphore ); 00137 00138 op_ExitCriticalSection(); 00139 } 00140 00146 void op_SemaphorePend( register t_SEMAPHORE* semaphore asm("%a0") ) 00147 { 00148 op_EnterCriticalSection(); 00149 00150 if( semaphore->count == 0 ) 00151 { 00152 WaitForEvent( (t_EVENT*)semaphore ); 00153 } 00154 00155 semaphore->count--; 00156 op_ExitCriticalSection(); 00157 } 00158 00165 unsigned short op_MailBoxPost( register t_MAILBOX* mailBox asm("%a0"), register void* message asm("%d0") ) 00166 { 00167 00168 op_EnterCriticalSection(); 00169 00170 if( mailBox->message != NULL ) return FALSE; 00171 00172 mailBox->message = message; 00173 00174 MakeTaskReady( (t_EVENT*)mailBox ); 00175 00176 op_ExitCriticalSection(); 00177 return TRUE; 00178 } 00179 00187 void* op_MailBoxPend( register t_MAILBOX* mailBox asm("%a0") ) 00188 { 00189 void* message; 00190 00191 op_EnterCriticalSection(); 00192 00193 if( mailBox->message == NULL ) 00194 { 00195 WaitForEvent( (t_EVENT*)mailBox ); 00196 } 00197 00198 message = mailBox->message; 00199 mailBox->message = NULL; 00200 00201 op_ExitCriticalSection(); 00202 00203 return message; 00204 } 00205 00213 unsigned short op_QueuePost( register t_QUEUE* queue asm("%a0"), register void* message asm("%d0") ) 00214 { 00215 op_EnterCriticalSection(); 00216 00217 if( queue->bufferUsage >= queue->bufferSize ) return FALSE; 00218 00219 queue->messageBuffer[ queue->back ] = message; 00220 queue->back = (queue->back >= queue->bufferSize)? 0: queue->back+1; 00221 queue->bufferUsage++; 00222 00223 MakeTaskReady( (t_EVENT*)queue ); 00224 00225 op_ExitCriticalSection(); 00226 return TRUE; 00227 } 00228 00237 unsigned short op_QueuePostFront( register t_QUEUE* queue asm("%a0"), register void* message asm("%d0") ) 00238 { 00239 op_EnterCriticalSection(); 00240 00241 if( queue->bufferUsage >= queue->bufferSize ) return FALSE; 00242 00243 queue->front = ((queue->front == 0)? queue->bufferSize: queue->front) -1; 00244 00245 queue->messageBuffer[ queue->front ] = message; 00246 queue->bufferUsage++; 00247 00248 MakeTaskReady( (t_EVENT*)queue ); 00249 00250 op_ExitCriticalSection(); 00251 return TRUE; 00252 } 00253 00261 void* op_QueuePend( register t_QUEUE* queue asm("%a0") ) 00262 { 00263 void* message; 00264 op_EnterCriticalSection(); 00265 00266 if( queue->bufferUsage == 0 ) 00267 { 00268 WaitForEvent( (t_EVENT*)queue ); 00269 } 00270 00271 message = queue->messageBuffer[ queue->front ]; 00272 00273 if( ++(queue->front) >= queue->bufferSize ) 00274 queue->front = 0; 00275 00276 queue->bufferUsage--; 00277 00278 op_ExitCriticalSection(); 00279 00280 return message; 00281 } 00282 00283 /* end of file */ 00284

Generated on Sun May 14 22:31:06 2006 for Opale by doxygen 1.3.8