00001
00002
00003
00004
#include "opale_internal.h"
00005
00006 static void EventInit(
register t_EVENT* event
asm(
"%a0"),
register unsigned long initValue
asm(
"%d0") )
00007 {
00008
short i;
00009
unsigned char* ptr = event->waitingTasks.tasksTable;
00010
00011 event->waitingTasks.rowIndex = 0;
00012 event->value = initValue;
00013
00014
for( i = 0; i<_Y_; i++ )
00015 {
00016 *ptr++ = 0;
00017 }
00018 }
00019
00024 void op_SemaphoreInit(
register t_SEMAPHORE* semaphore
asm(
"%a0"),
register unsigned long initValue
asm(
"%d0") )
00025 {
00026
EventInit( (t_EVENT*)semaphore, initValue );
00027 }
00028
00033 void op_MailBoxInit(
register t_MAILBOX* mailbox
asm(
"%a0"),
register void* initMessage
asm(
"%d0") )
00034 {
00035
EventInit( (t_EVENT*)mailbox, (
unsigned long)initMessage );
00036 }
00037
00042 void op_QueueInit(
register t_QUEUE* queue
asm(
"%a0"),
register void* buffer
asm(
"%d0"),
register unsigned short size
asm(
"%d1") )
00043 {
00044
EventInit( (t_EVENT*)queue, (
unsigned long)buffer );
00045
00046 queue->bufferSize = size;
00047 queue->front = 0;
00048 queue->back = 0;
00049 queue->bufferUsage = 0;
00050
00051 }
00052
00053 void addTaskToTable(
register t_TASK_BLOCK* table
asm(
"%a0"),
register unsigned char ident
asm(
"%d0") )
00054 {
00055
unsigned char x = identToX( ident );
00056
unsigned char y = identToY( ident );
00057
00058 poke_bset( &table->tasksTable[ y ], x );
00059 poke_bset( &table->rowIndex, y );
00060 }
00061
00062 void removeTaskFromTable(
register t_TASK_BLOCK* table
asm(
"%a0"),
register unsigned char ident
asm(
"%d0") )
00063 {
00064
unsigned char x = identToX( ident );
00065
unsigned char y = identToY( ident );
00066
00067 poke_bclr( &table->tasksTable[ y ], x );
00068
if( !table->tasksTable[ y ] )
00069 poke_bclr( &table->rowIndex, y );
00070 }
00071
00072 static void moveFromTable(
register t_TASK_BLOCK* tableFrom
asm(
"%a0"),
register t_TASK_BLOCK* tableTo
asm(
"%a1"),
register unsigned char ident
asm(
"d0") )
00073 {
00074
00075
00076
addTaskToTable( tableTo, ident );
00077
00078
00079
removeTaskFromTable( tableFrom, ident );
00080
00081
00082 op_Scheduler();
00083 }
00084
00085 static void MakeTaskReady(
register t_EVENT* event
asm(
"%a0") )
00086 {
00087
if( event->waitingTasks.rowIndex )
00088 {
00089
00090
unsigned char y =
indexToLowestSettedBit[ event->waitingTasks.rowIndex ];
00091
unsigned char x =
indexToLowestSettedBit[ event->waitingTasks.tasksTable[ y ] ];
00092
00093
register unsigned char highestPriorityWaiting
asm(
"%d0") = ( y << MASK_Y ) + x;
00094
00095
00096
moveFromTable( &event->waitingTasks,
readyTasks, highestPriorityWaiting );
00097 }
00098 }
00099
00100 static void WaitForEvent(
register t_EVENT* event
asm(
"%a0") )
00101 {
00102
00103
moveFromTable(
readyTasks, &event->waitingTasks, currentTask->ident );
00104 }
00105
00110 void op_SemaphorePost(
register t_SEMAPHORE* semaphore
asm(
"%a0") )
00111 {
00112
00113 op_EnterCriticalSection();
00114
00115 semaphore->count++;
00116
00117
MakeTaskReady( (t_EVENT*)semaphore );
00118
00119 op_ExitCriticalSection();
00120 }
00121
00127 void op_SemaphorePend(
register t_SEMAPHORE* semaphore
asm(
"%a0") )
00128 {
00129 op_EnterCriticalSection();
00130
00131
if( semaphore->count == 0 )
00132 {
00133
WaitForEvent( (t_EVENT*)semaphore );
00134 }
00135
00136 semaphore->count--;
00137 op_ExitCriticalSection();
00138 }
00139
00146 unsigned short op_MailBoxPost(
register t_MAILBOX* mailBox
asm(
"%a0"),
register void* message
asm(
"%d0") )
00147 {
00148
00149 op_EnterCriticalSection();
00150
00151
if( mailBox->message != NULL )
return FALSE;
00152
00153 mailBox->message = message;
00154
00155
MakeTaskReady( (t_EVENT*)mailBox );
00156
00157 op_ExitCriticalSection();
00158
return TRUE;
00159 }
00160
00168 void*
op_MailBoxPend(
register t_MAILBOX* mailBox
asm(
"%a0") )
00169 {
00170
void* message;
00171
00172 op_EnterCriticalSection();
00173
00174
if( mailBox->message == NULL )
00175 {
00176
WaitForEvent( (t_EVENT*)mailBox );
00177 }
00178
00179 message = mailBox->message;
00180 mailBox->message = NULL;
00181
00182 op_ExitCriticalSection();
00183
00184
return message;
00185 }
00186
00194 unsigned short op_QueuePost(
register t_QUEUE* queue
asm(
"%a0"),
register void* message
asm(
"%d0") )
00195 {
00196 op_EnterCriticalSection();
00197
00198
if( queue->bufferUsage >= queue->bufferSize )
return FALSE;
00199
00200 queue->messageBuffer[ queue->back ] = message;
00201 queue->back = (queue->back >= queue->bufferSize)? 0: queue->back+1;
00202 queue->bufferUsage++;
00203
00204
MakeTaskReady( (t_EVENT*)queue );
00205
00206 op_ExitCriticalSection();
00207
return TRUE;
00208 }
00209
00218 unsigned short op_QueuePostFront(
register t_QUEUE* queue
asm(
"%a0"),
register void* message
asm(
"%d0") )
00219 {
00220 op_EnterCriticalSection();
00221
00222
if( queue->bufferUsage >= queue->bufferSize )
return FALSE;
00223
00224 queue->front = ((queue->front == 0)? queue->bufferSize: queue->front) -1;
00225
00226 queue->messageBuffer[ queue->front ] = message;
00227 queue->bufferUsage++;
00228
00229
MakeTaskReady( (t_EVENT*)queue );
00230
00231 op_ExitCriticalSection();
00232
return TRUE;
00233 }
00234
00242 void*
op_QueuePend(
register t_QUEUE* queue
asm(
"%a0") )
00243 {
00244
void* message;
00245 op_EnterCriticalSection();
00246
00247
if( queue->bufferUsage == 0 )
00248 {
00249
WaitForEvent( (t_EVENT*)queue );
00250 }
00251
00252 message = queue->messageBuffer[ queue->front ];
00253
00254
if( ++(queue->front) >= queue->bufferSize )
00255 queue->front = 0;
00256
00257 queue->bufferUsage--;
00258
00259 op_ExitCriticalSection();
00260
00261
return message;
00262 }
00263
00264
00265