00001
00002
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;
00016
unsigned char* ptr = event->waitingTasks.tasksTable;
00017
00018 event->waitingTasks.rowIndex = 0;
00019 event->value = initValue;
00020
00021
for( i = 0; i<
_Y_; i++ )
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 );
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 );
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 );
00052
00053 queue->bufferSize = size;
00054 queue->front = 0;
00055 queue->back = 0;
00056 queue->bufferUsage = 0;
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 );
00066
unsigned char y =
identToY( ident );
00067
00068 poke_bset( &table->tasksTable[ y ], x );
00069 poke_bset( &table->rowIndex, y );
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 );
00079
unsigned char y =
identToY( ident );
00080
00081 poke_bclr( &table->tasksTable[ y ], x );
00082
if( !table->tasksTable[ y ] )
00083 poke_bclr( &table->rowIndex, y );
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 );
00094
removeTaskFromTable( tableFrom, ident );
00095
00096
op_Scheduler();
00097 }
00098
00102 static void MakeTaskReady(
register t_EVENT* event
asm(
"%a0") )
00103 {
00104
if( event->waitingTasks.rowIndex )
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;
00111
00112
moveFromTable( &event->waitingTasks,
readyTasks, highestPriorityWaiting );
00113 }
00114 }
00115
00119 static void WaitForEvent(
register t_EVENT* event
asm(
"%a0") )
00120 {
00121
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
00284