blob: eaf53496d0514adc03f6973bb9e9b4c3b941e51e [file] [log] [blame]
#ifndef __TASKQ_TASKQ_LIST_H__
#define __TASKQ_TASKQ_LIST_H__
typedef struct
{
void *args[NUM_FIELDS];
} Entry;
typedef struct
{
int head, tail, size, count;
Entry *array;
} TaskQList;
#define INDEX_INC(i,max) { if ( ++(i) == max) (i) = 0; }
#define INDEX_DEC(i,max) { if ( --(i) < 0) (i) = max-1; }
static inline void copyArgs (void *dest[NUM_FIELDS], void *src[NUM_FIELDS])
{
TQ_ASSERT (NUM_FIELDS == 4);
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
dest[3] = src[3];
}
static void initTaskQList (TaskQList *t, long maxNumOfTasks)
{
t->head = t->tail = t->count = 0;
t->size = maxNumOfTasks;
t->array = (Entry *) malloc (t->size * sizeof (Entry));
}
static inline void getEntryHead (TaskQList *t, void *task[NUM_FIELDS])
{
t->count--;
INDEX_DEC (t->head, t->size);
void **args = t->array[t->head].args;
copyArgs (task, args);
}
static inline void getEntryTail (TaskQList *t, void *task[NUM_FIELDS])
{
t->count--;
void **args = t->array[t->tail].args;
copyArgs (task, args);
INDEX_INC (t->tail, t->size);
}
static inline void putEntryHead (TaskQList *t, void *task[NUM_FIELDS])
{
t->count++;
DEBUG_ASSERT (t->count <= t->size);
void **args = t->array[t->head].args;
copyArgs (args, task);
INDEX_INC (t->head, t->size);
}
static inline void putEntryTail (TaskQList *t, void *task[NUM_FIELDS])
{
t->count++;
DEBUG_ASSERT (t->count <= t->size);
INDEX_DEC (t->tail, t->size);
void **args = t->array[t->tail].args;
copyArgs (args, task);
}
static inline int moveEntriesFromHeadToTail (TaskQList *src, TaskQList *dest, long maxTasks)
{
int toMove = (src->count < maxTasks) ? src->count : maxTasks;
int srcHead = src->head;
int destTail = dest->tail;
int srcSize = src->size;
int destSize = dest->size;
int moved = toMove;
while (toMove-- != 0)
{
INDEX_DEC (destTail, destSize);
INDEX_DEC (srcHead, srcSize);
void **destArgs = dest->array[destTail].args;
void **srcArgs = src->array[srcHead].args;
copyArgs (destArgs, srcArgs);
}
dest->tail = destTail;
dest->count += moved;
src->head = srcHead;
src->count -= moved;
DEBUG_ASSERT (dest->count <= dest->size);
DEBUG_ASSERT (src->count >= 0);
return moved;
}
static inline int moveEntriesFromTailToTail (TaskQList *src, TaskQList *dest, long maxTasks)
{
int toMove = (src->count < maxTasks) ? src->count : maxTasks;
int srcTail = src->tail;
int destTail = dest->tail;
int srcSize = src->size;
int destSize = dest->size;
int moved = toMove;
while (toMove-- != 0)
{
INDEX_DEC (destTail, destSize);
void **destArgs = dest->array[destTail].args;
void **srcArgs = src->array[srcTail].args;
copyArgs (destArgs, srcArgs);
INDEX_INC (srcTail, srcSize);
}
dest->tail = destTail;
dest->count += moved;
src->tail = srcTail;
src->count -= moved;
DEBUG_ASSERT (dest->count <= dest->size);
DEBUG_ASSERT (src->count >= 0);
return moved;
}
static inline int moveEntriesFromTailToHead (TaskQList *src, TaskQList *dest, long maxTasks)
{
int toMove = (src->count < maxTasks) ? src->count : maxTasks;
int srcTail = src->tail;
int destHead = dest->head;
int srcSize = src->size;
int destSize = dest->size;
int moved = toMove;
while (toMove-- != 0)
{
void **destArgs = dest->array[destHead].args;
void **srcArgs = src->array[srcTail].args;
copyArgs (destArgs, srcArgs);
INDEX_INC (destHead, destSize);
INDEX_INC (srcTail, srcSize);
}
dest->head = destHead;
dest->count += moved;
src->tail = srcTail;
src->count -= moved;
DEBUG_ASSERT (dest->count <= dest->size);
DEBUG_ASSERT (src->count >= 0);
return moved;
}
//------------------------------------------------------ CLEAN THIS UP. MAX_TASKS_TO_STEAL => MAX_MOVE_TASKS
#define MAX_TASKS_TO_STEAL 8
#ifdef USE_INFORMATION
static __inline void INFORMATION (int arg1, int arg2, int arg3)
{
__asm__ volatile ("information %[r1], %[r2], %[r3]"
:
: [r1] "r" (arg1), [r2] "r" (arg2), [r3] "r" (arg3));
}
#endif
static inline int getEntriesTail (TaskQList *t, void *tasks[MAX_TASKS_TO_STEAL][NUM_FIELDS])
{
int num_to_get = t->count / 2 <= MAX_TASKS_TO_STEAL ? t->count / 2 : MAX_TASKS_TO_STEAL;
int i;
void **args;
t->count -= num_to_get;
for (i = 0; i < num_to_get; i++)
{
args = t->array[t->tail].args;
copyArgs (tasks[i], args);
INDEX_INC (t->tail, t->size);
}
return num_to_get;
}
static inline void putEntriesHead (TaskQList *t, void *tasks[MAX_TASKS_TO_STEAL][NUM_FIELDS], int num_tasks)
{
int i;
void **args;
t->count += num_tasks;
DEBUG_ASSERT (t->count <= t->size);
for (i = 0; i < num_tasks; i++)
{
args = t->array[t->head].args;
copyArgs (args, tasks[i]);
INDEX_INC (t->head, t->size);
}
}
#endif