diff options
author | goodale <goodale@17b73243-c579-4c4c-a9d2-2d5706c11dac> | 1999-09-15 18:35:29 +0000 |
---|---|---|
committer | goodale <goodale@17b73243-c579-4c4c-a9d2-2d5706c11dac> | 1999-09-15 18:35:29 +0000 |
commit | ebd506b224d18fc0c9fe580eeb960335b2be1554 (patch) | |
tree | 9e1868dc551b8791025ece5af86ebb83ea76f408 /src/schedule | |
parent | 9b6111e1a0bc00773afe97da63acaaca8fdfcda2 (diff) |
This commit was generated by cvs2svn to compensate for changes in r924,
which included commits to RCS files with non-trunk default branches.
git-svn-id: http://svn.cactuscode.org/flesh/trunk@925 17b73243-c579-4c4c-a9d2-2d5706c11dac
Diffstat (limited to 'src/schedule')
-rw-r--r-- | src/schedule/Makefile | 20 | ||||
-rw-r--r-- | src/schedule/Schedule.h | 29 | ||||
-rw-r--r-- | src/schedule/ScheduleCreater.c | 706 | ||||
-rw-r--r-- | src/schedule/ScheduleSorter.c | 328 |
4 files changed, 1083 insertions, 0 deletions
diff --git a/src/schedule/Makefile b/src/schedule/Makefile new file mode 100644 index 00000000..796cd3cb --- /dev/null +++ b/src/schedule/Makefile @@ -0,0 +1,20 @@ +CC = gcc +CFLAGS = -g -DDEBUG_SCHEDULAR -DTEST_SCHEDULECREATOR + +SRCS = ScheduleCreater.c ScheduleSorter.c ../util/StoreHandledData.c +INCDIRS = ../include + +EXE = schedtest + +OBJS = $(SRCS:%.c=%.o) + +$(EXE): $(OBJS) + cc -o $@ $(CFLAGS) $(notdir $(OBJS)) + +%.o : %.c + cc $(CFLAGS) -c $< $(INCDIRS:%=-I%) + +.PHONY: clean + +clean: + rm -f *.o $(EXE)
\ No newline at end of file diff --git a/src/schedule/Schedule.h b/src/schedule/Schedule.h new file mode 100644 index 00000000..342fb111 --- /dev/null +++ b/src/schedule/Schedule.h @@ -0,0 +1,29 @@ + /*@@ + @header Schedule.h + @date Mon Sep 13 12:24:48 1999 + @author Tom Goodale + @desc + Header file for Schedule routines, etc. + @enddesc + @version $Header$ + @@*/ + +#ifndef _SCHEDULE_H_ +#define _SCHEDULE_H_ + +typedef enum {sched_item_none, sched_group, sched_function} t_sched_item_type; + +typedef enum {sched_mod_none, sched_before, sched_after, sched_while} t_sched_modifier_type; + +typedef struct T_SCHED_MODIFIER +{ + struct T_SCHED_MODIFIER *next; + + t_sched_modifier_type type; + + char *argument; + +} t_sched_modifier; + + +#endif diff --git a/src/schedule/ScheduleCreater.c b/src/schedule/ScheduleCreater.c new file mode 100644 index 00000000..59f03666 --- /dev/null +++ b/src/schedule/ScheduleCreater.c @@ -0,0 +1,706 @@ + /*@@ + @file ScheduleCreater.c + @date Tue Aug 31 12:46:08 1999 + @author Tom Goodale + @desc + + @enddesc + @@*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "Schedule.h" +#include "StoreHandledData.h" + +typedef struct +{ + char *name; + + t_sched_item_type type; + + void *function; + int group; + + int n_whiles; + char **whiles; + + void *attributes; + + t_sched_modifier *modifiers; +} t_sched_item; + +typedef struct +{ + char *name; + int *order; + + int n_scheditems; + + t_sched_item *scheditems; + +} t_sched_group; + + + +t_sched_item *CCTKi_ScheduleCreateItem(const char *name, t_sched_modifier *modifiers, void *attributes); +t_sched_modifier_type CCTKi_ScheduleTranslateModifierType(const char *modifier); +int CCTKi_ScheduleItemNumber(t_sched_group *group, const char *name); + +int *ScheduleCreateIVec(int size); +void ScheduleDestroyIVec(int size, int *vector); +signed char **ScheduleCreateArray(int size); +void ScheduleDestroyArray(int size, signed char **array); + +int CCTKi_ScheduleAddRow(int size, + signed char **array, + int *order, + int item, + int *thisorders); + +static char *rcsid="$Header$"; + +static int n_schedule_groups = 0; +static cHandledData *schedule_groups = NULL; + + /*@@ + @routine CCTKi_ScheduleCreateGroup + @date Wed Sep 8 11:15:32 1999 + @author Tom Goodale + @desc + Creates a schedule group. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +int CCTKi_ScheduleCreateGroup(const char *name) +{ + int retcode; + int handle; + + t_sched_group *this_group; + + handle = Util_GetHandle(schedule_groups, name, (void **)&this_group); + + if(handle > -1) + { + /* Group already exists */ + retcode = -1; + } + else + { + this_group = (t_sched_group *)malloc(sizeof(t_sched_group)); + + if(this_group) + { + this_group->name = (char *)malloc((strlen(name)+1)*sizeof(char)); + + if(this_group->name) + { + strcpy(this_group->name, name); + + this_group->order = NULL; + this_group->n_scheditems = 0; + this_group->scheditems = NULL; + retcode = Util_NewHandle(&schedule_groups, name, (void *)this_group); + n_schedule_groups++; + } + else + { + free(this_group); + + retcode = -2; + } + } + else + { + retcode = -2; + } + } + + return retcode; +} + + /*@@ + @routine CCTK_ScheduleFunction + @date Thu Sep 9 21:42:58 1999 + @author Tom Goodale + @desc + Adds a function to a schedule group. Creates the group if necessary. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +int CCTK_ScheduleFunction(const char *gname, const char *fname, void *func, t_sched_modifier *modifiers, void *attributes) +{ + int retcode; + int handle; + t_sched_group *this_group; + t_sched_item *newitem; + + handle = Util_GetHandle(schedule_groups, gname, (void **)&this_group); + + if(handle < 0) + { + handle = CCTKi_ScheduleCreateGroup(gname); + } + + if(handle < 0) + { + retcode = -1; + } + else + { + newitem = CCTKi_ScheduleCreateItem(fname, modifiers, attributes); + + if(newitem) + { + newitem->type = sched_function; + newitem->function = func; + retcode = CCTKi_ScheduleAddItem(handle, newitem); + } + else + { + retcode = -1; + } + } + + return retcode; +} + + /*@@ + @routine CCTK_ScheduleGroup + @date Thu Sep 9 21:43:44 1999 + @author Tom Goodale + @desc + Adds a group to a schedule group. Creates the group if necessary. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +int CCTK_ScheduleGroup(const char *gname, const char *thisname, t_sched_modifier *modifiers, void *attributes) +{ + int retcode; + int handle; + t_sched_group *this_group; + t_sched_item *newitem; + + handle = Util_GetHandle(schedule_groups, gname, (void **)&this_group); + + if(handle < 0) + { + handle = CCTKi_ScheduleCreateGroup(gname); + } + + if(handle < 0) + { + retcode = -1; + } + else + { + newitem = CCTKi_ScheduleCreateItem(thisname, modifiers, attributes); + + if(newitem) + { + newitem->type = sched_group; + newitem->group = handle; + retcode = CCTKi_ScheduleAddItem(handle, newitem); + } + else + { + retcode = -1; + } + } + + return retcode; +} + + /*@@ + @routine CCTKi_ScheduleCreateItem + @date Thu Sep 9 21:44:17 1999 + @author Tom Goodale + @desc + Creates a schedule item to be scheduled. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +t_sched_item *CCTKi_ScheduleCreateItem(const char *name, t_sched_modifier *modifiers, void *attributes) +{ + t_sched_item *this; + + this = (t_sched_item *)malloc(sizeof(t_sched_item)); + + if(this) + { + this->name = (char *)malloc((strlen(name)+1)*sizeof(char)); + + if(this->name) + { + strcpy(this->name, name); + + this->type = sched_item_none; + this->function = NULL; + this->group = -1; + this->modifiers = modifiers; + + this->n_whiles = 0; + this->whiles = NULL; + + this->attributes = attributes; + +#ifdef DEBUG_SCHEDULAR + printf("Created Schedule item %s\n", this->name); +#endif + + } + else + { + free(this); + this = NULL; + } + } + + return this; +} + + /*@@ + @routine CCTKi_ScheduleAddItem + @date Thu Sep 9 21:45:03 1999 + @author Tom Goodale + @desc + Adds a schedule item to a group. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +int CCTKi_ScheduleAddItem(int ghandle, t_sched_item *item) +{ + int retcode; + t_sched_group *this_group; + t_sched_item *temp; + + this_group = (t_sched_group *)Util_GetHandledData(schedule_groups, ghandle); + + this_group->n_scheditems++; + + temp = (t_sched_item *)realloc(this_group->scheditems, this_group->n_scheditems*sizeof(t_sched_item)); + + if(temp) + { + this_group->scheditems = temp; + this_group->scheditems[this_group->n_scheditems-1] = *item; + +#ifdef DEBUG_SCHEDULAR + printf("Added item '%s' to group '%s'\n", item->name, this_group->name); +#endif + + free(item); + + retcode = 0; + } + else + { + this_group->n_scheditems--; + retcode = -1; + } + + return retcode; +} + + /*@@ + @routine CCTK_ScheduleAddModifer + @date Thu Sep 9 21:45:25 1999 + @author Tom Goodale + @desc + Adds a schedule modifier to a modifier list. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +t_sched_modifier *CCTK_ScheduleAddModifer(t_sched_modifier *orig, const char *modifier, const char *argument) +{ + t_sched_modifier *this; + + this = (t_sched_modifier *)malloc(sizeof(t_sched_modifier)); + + if(this) + { + this->argument = (char *)malloc((strlen(argument)+1)*sizeof(char)); + if(this->argument) + { + strcpy(this->argument, argument); + + this->type = CCTKi_ScheduleTranslateModifierType(modifier); + + this->next = orig; + } + else + { + free(this); + this = NULL; + } + } + + return this; +} + + + /*@@ + @routine CCTKi_ScheduleTranslateModifierType + @date Thu Sep 9 21:45:56 1999 + @author Tom Goodale + @desc + Translates a modifier type from a string to an enum. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +t_sched_modifier_type CCTKi_ScheduleTranslateModifierType(const char *modifier) +{ + /* FIXME */ + + t_sched_modifier_type retval; + + retval = sched_mod_none; + + if(!strcmp(modifier, "before")) + { + retval = sched_before; + } + else if(!strcmp(modifier, "after")) + { + retval = sched_after; + } + else if(!strcmp(modifier, "while")) + { + retval = sched_while; + } + +#ifdef DEBUG_SCHEDULAR + printf("Translated modifier type %s to %d\n", modifier, retval); +#endif + + return retval; +} + + /*@@ + @routine CCTKi_ScheduleSortGroup + @date Mon Sep 13 11:30:19 1999 + @author Tom Goodale + @desc + Sorts the routines in a group. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +int CCTKi_ScheduleSortGroup(t_sched_group *group) +{ + int item; + int *order; + int *thisorders; + t_sched_modifier *modifier; + signed char **array; + int number; + int mod; + int i, j; + int errcode; + + /* Create the data staructures */ + array = ScheduleCreateArray(group->n_scheditems); + order = ScheduleCreateIVec(group->n_scheditems); + thisorders = ScheduleCreateIVec(group->n_scheditems); + + for(item=0; item < group->n_scheditems; item++) + { +#ifdef DEBUG_SCHEDULAR + printf("Scheduling item %d '%s'\n", item, group->scheditems[item].name); +#endif + for(modifier = group->scheditems[item].modifiers; modifier; modifier = modifier->next) + { + if(modifier->type == sched_while) + { + continue; + } + number = CCTKi_ScheduleItemNumber(group, modifier->argument); + +#ifdef DEBUG_SCHEDULAR + printf("Scheduling against item %d '%s' - mod-type %d\n", number, group->scheditems[number].name, modifier->type); +#endif + if(number >= 0 && number < group->n_scheditems) + { + switch(modifier->type) + { + case sched_before : mod = -1; break; + case sched_after : mod = 1; break; + default : + mod = 0; + } +#ifdef DEBUG_SCHEDULAR + printf("Modifier is %d\n", mod); +#endif + + thisorders[number] = mod; + } + } + +#ifdef DEBUG_SCHEDULAR + printf("Orderlist for item %d is...\n", item); + for(i=0; i < group->n_scheditems; i++) + { + printf(" %d", thisorders[i]); + } + printf("\n"); +#endif + + CCTKi_ScheduleAddRow(group->n_scheditems, array, order, item, thisorders); + + /* Clear the array for the next item. */ + for(i=0; i < group->n_scheditems; i++) + { + thisorders[i] = 0; + } + } + +#ifdef DEBUG_SCHEDULAR + printf("Initial array is...\n"); + for(i=0; i < group->n_scheditems; i++) + { + for(j=0; j < group->n_scheditems; j++) + { + printf(" %d", (int)array[i][j]); + } + + printf("\n"); + } + + printf("Initial order is...\n"); + for(i=0; i < group->n_scheditems; i++) + { + printf(" %d", order[i]); + } + printf("\n"); + + printf("Sorting array...\n"); +#endif + + errcode = ScheduleSort(group->n_scheditems, array, order); + + if(errcode) + { + fprintf(stderr, "Schedule sort failed with error code %d\n", errcode); + } + +#ifdef DEBUG_SCHEDULAR + printf("Final array is...\n"); + for(i=0; i < group->n_scheditems; i++) + { + for(j=0; j < group->n_scheditems; j++) + { + printf(" %d", (int)array[i][j]); + } + + printf("\n"); + } + + printf("Final order is...\n"); + for(i=0; i < group->n_scheditems; i++) + { + printf(" %d", order[i]); + } + printf("\n"); +#endif + + /* Free memory */ + ScheduleDestroyIVec(group->n_scheditems,thisorders); + ScheduleDestroyArray(group->n_scheditems, array); + + group->order = order; + + return errcode; +} + + /*@@ + @routine CCTKi_ScheduleItemNumber + @date Mon Sep 13 11:30:49 1999 + @author Tom Goodale + @desc + Returns the number of a specific item in the array of schedule items. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +int CCTKi_ScheduleItemNumber(t_sched_group *group, const char *name) +{ + int retval; + int i; + + retval = -1; + /* This is the quick-to-write way to do this. Should really put into a + * hash table or a tree, but this will do for the moment. + */ + for(i = 0 ; i < group->n_scheditems; i++) + { + if(!strcmp(group->scheditems[i].name, name)) + { + retval = i; + break; + } + } + + return retval; +} + +int CCTKi_ScheduleAllGroups(void) +{ + int group; + t_sched_group *gdata; + int errcode; + int n_errors; + + n_errors = 0; + + for(group = 0; group < n_schedule_groups; group++) + { + if(gdata = (t_sched_group *)Util_GetHandledData(schedule_groups, group)) + { + errcode = CCTKi_ScheduleSortGroup(gdata); + + if(errcode) + { + fprintf(stderr, + "Error while dorting group '%s' - %d remaining unsorted routines.\n", + gdata->name, + -errcode); + + n_errors += -errcode; + } + } + } + + return -n_errors; +} + + /*@@ + @routine CCTKi_ScheduleSetupWhiles + @date Wed Sep 15 20:10:28 1999 + @author Tom Goodale + @desc + Make an array of all the whiles in the modifier list for a schedule item. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +int CCTKi_ScheduleSetupWhiles(t_sched_item *item) +{ + int retval; + t_sched_modifier *modifier; + char **temp; + + retval = 0; + + for(modifier = item->modifiers; modifier; modifier = modifier->next) + { + if(modifier->type == sched_while) + { + item->n_whiles++; + temp = (char **)realloc(item->whiles, item->n_whiles*sizeof(char *)); + + if(temp) + { + item->whiles = temp; + + temp[item->n_whiles-1] = (char *)malloc((strlen(modifier->argument)+1)*sizeof(char)); + if(temp[item->n_whiles-1]) + { + strcpy(temp[item->n_whiles-1], modifier->argument); + } + else + { + item->n_whiles--; + retval--; + } + } + else + { + retval--; + } + } + } + + return retval; +} + +#ifdef TEST_SCHEDULECREATOR + +#define func_x(x) \ +int func_ ## x (void) { return printf("I'm func " #x "\n"); } + +func_x(a) +func_x(b) +func_x(c) + +#define func_x_proto(x) int func_ ## x (void); + +int main(int argc, char *argv[]) +{ + int handle; + t_sched_modifier *modifier; + t_sched_group *this_group; + + modifier = CCTK_ScheduleAddModifer(NULL, "before", "c"); + modifier = CCTK_ScheduleAddModifer(modifier, "after", "a"); + + CCTK_ScheduleFunction("group_a", "c", func_c, NULL, NULL); + CCTK_ScheduleFunction("group_a", "b", func_b, modifier, NULL); + CCTK_ScheduleFunction("group_a", "a", func_a, NULL, NULL); + CCTK_ScheduleFunction("group_b", "a", func_a, NULL, NULL); + CCTK_ScheduleFunction("group_b", "b", func_a, NULL, NULL); + CCTK_ScheduleGroup("group_a", "group_b", modifier, NULL); + + CCTKi_ScheduleAllGroups(); + + return 0; +} +#endif diff --git a/src/schedule/ScheduleSorter.c b/src/schedule/ScheduleSorter.c new file mode 100644 index 00000000..4f77689f --- /dev/null +++ b/src/schedule/ScheduleSorter.c @@ -0,0 +1,328 @@ + /*@@ + @file ScheduleSorter.c + @date Mon Aug 30 11:36:35 1999 + @author Tom Goodale + @desc + Sorter for scheduled routines. + @enddesc + @@*/ + +#include <stdio.h> +#include <stdlib.h> + +static char *rcsid = "$Header$"; + +static void ScheduleSwap(int size, signed char **array, int *order, int row, int column); + + /*@@ + @routine ScheduleSort + @date Mon Aug 30 11:44:35 1999 + @author Tom Goodale + @desc + Sorts the array into sort order + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ + +int ScheduleSort(int size, signed char **array, int *order) +{ + int iter; + int row, column; + int retval; + + for(iter=0; iter < size*(size-1)/2; iter++) + { + + /* Search for the first +ve entry in the matrix */ + for(row = 0; row < size; row++) + { + for(column = row+1; column < size ; column++) + { + if(array[row][column] > 0) break; + } + if(column < size && array[row][column] > 0) break; + } + + /* If beyond end of matrix, must be finished */ + if(row >= size) break; + + /* Swap the rows and columns */ + ScheduleSwap(size, array, order, row, column); + + } + + retval = 0; + + /* Search for +ve entries in the matrix */ + for(row = 0; row < size; row++) + { + for(column = row+1; column <size ; column++) + { + if(array[row][column] > 0) retval -= 1; + } + } + + return retval; +} + +static void ScheduleSwap(int size, signed char **array, int *order, int row, int column) +{ + signed char *tmp; + signed char tmp_char; + int tmp_int; + int this_row; + + /* Swap the rows */ + tmp = array[row]; + array[row] = array[column]; + array[column] = tmp; + + /* Swap the columns */ + for(this_row = 0; this_row < size; this_row++) + { + tmp_char = array[this_row][column]; + array[this_row][column] = array[this_row][row]; + array[this_row][row]=tmp_char; + } + + /* Swap routine orders */ + tmp_int = order[column]; + order[column]=order[row]; + order[row] = tmp_int; + +} + +int CCTKi_ScheduleAddRow(int size, + signed char **array, + int *order, + int item, + int *thisorders) +{ + int retval; + + int row; + int column; + int i; + + retval = 0; + + order[item]=item; + + row = item; + + for(column=0; column < size; column++) + { + if(thisorders[column]) + { + if(array[row][column] && array[row][column] != thisorders[column]) retval--; + array[row][column] = thisorders[column]; + array[column][row] = - thisorders[column]; + } + } + + return retval; +} + +signed char **ScheduleCreateArray(int size) +{ + int i, j; + signed char **array; + + array = (signed char **)malloc(size*sizeof(signed char *)); + + if(array) + { + for(i=0; i < size; i++) + { + array[i] = (signed char *)malloc(size*sizeof(signed char)); + if(!array[i]) break; + } + + /* Check for errors */ + if(i < size) + { + /* Free already allocated memory */ + for(i-1; i >=0; i--) + { + free(array[i]); + } + free(array); + array = NULL; + } + } + + /* Initialise all entries to zero. */ + if(array) + { + for(i=0; i < size; i++) + { + for(j=0; j < size; j++) + { + array[i][j] = 0; + } + } + } + + return array; +} + +void ScheduleDestroyArray(int size, signed char **array) +{ + int i; + + for(i=size-1; i >=0; i--) + { + free(array[i]); + } +} + +int *ScheduleCreateIVec(int size) +{ + int i; + int *vector; + + vector = (int *)malloc(size*sizeof(int)); + + if(vector) + { + for(i=0; i < size; i++) + { + vector[i] = 0; + } + } + + return vector; +} + +void ScheduleDestroyIVec(int size, int *vector) +{ + free(vector); +} + +#ifdef TEST_SORTER +int main(int argc, char *argv[]) +{ + int i, j; + int size; + float weight; + int *order; + int errcode; + signed char **array; + signed char val; + + if(argc < 2) + { + printf("usage: %s size [wieght]\n", argv[0]); + exit(0); + } + + size = atoi(argv[1]); + + if(argc > 2) + { + weight = atof(argv[2]); + } + else + { + weight = 3.0; + } + + if(weight <= 1) + { + fprintf(stderr, "Weight must be greater than 1 ! Resetting to 3\n"); + weight = 3.0; + } + + if(size < 1) + { + fprintf(stderr, "size must be 1 or more, setting to 5\n"); + size = 5; + } + + order = ScheduleCreateIVec(size); + + array = ScheduleCreateArray(size); + + for(i=0; i < size; i++) + { + order[i] = i; + } + + /* Populate the array */ + for(i=0; i < size; i++) + { + for(j=i; j < size; j++) + { + if(i==j) + { + array[i][i]=0; + } + else + { + + val = (signed char)((int)(weight*rand()/(RAND_MAX+1.0))-2); + + /* Normalise */ + if(val) val /= abs(val); + + array[i][j] = val; + array[j][i] = -val; + } + } + } + + printf("Initial array is...\n"); + for(i=0; i < size; i++) + { + for(j=0; j < size; j++) + { + printf(" %d", (int)array[i][j]); + } + + printf("\n"); + } + + printf("Initial order is...\n"); + for(i=0; i < size; i++) + { + printf(" %d", order[i]); + } + printf("\n"); + + printf("Sorting array...\n"); + + errcode = ScheduleSort(size, array, order); + + if(errcode) + { + fprintf(stderr, "Schedule sort failed with error code %d\n", errcode); + } + + printf("Final array is...\n"); + for(i=0; i < size; i++) + { + for(j=0; j < size; j++) + { + printf(" %d", (int)array[i][j]); + } + + printf("\n"); + } + + printf("Final order is...\n"); + for(i=0; i < size; i++) + { + printf(" %d", order[i]); + } + printf("\n"); + + printf("\n All done.\n"); + + return 0; +} +#endif |