00001 #include <stdlib.h>
00002 #include <stdio.h>
00003 #include <string.h>
00004 #include <pvm3.h>
00005 #include <assert.h>
00006 #include "Task.h"
00007
00008
00009
00010
00011 pthread_mutex_t dependsOnMeMutex = PTHREAD_MUTEX_INITIALIZER;
00012
00013
00014
00015 Task *createTask(){
00016 Task *task = (Task *) malloc(sizeof(Task));
00017 if(task == NULL){
00018 printf("createTask: Could not alocate memory\n");
00019 exit(1);
00020 }
00021 task->dataSpace = createDataSpace();
00022 task->dependsOnMe = NULL;
00023 task->state = created;
00024 task->mother = NULL;
00025 task->endedTasks = 0;
00026 task->metaSize = 0;
00027 task->metadata = NULL;
00028
00029 task->children = hashIntVoidCreate(0);
00030 setIntVoidSerializer(task->children, &writeChildTask, &readChildTask);
00031
00032 return task;
00033 }
00034
00035 void destroyTask(Task *task){
00036 if(task == NULL){
00037 printf("destroyTask: We cant destroy a null Task\n");
00038 exit(1);
00039 }
00040
00041 taskIdListDestroy(task->myDeps);
00042 taskIdListDestroy(task->dependsOnMe);
00043 if (task->children != NULL) {
00044 hashIntVoidDestroy(task->children);
00045 }
00046
00047 if(task->metadata != NULL){
00048 free(task->metadata);
00049 }
00050 free(task);
00051 }
00052
00053 void setTaskEndedTasks(Task *task, int endedTasks){
00054 task->endedTasks = endedTasks;
00055 }
00056
00057 void setTaskState(Task *task, TaskState_t state){
00058 task->state = state;
00059 }
00060
00061 void setTaskMyDeps(Task *task, TaskIdList *myDeps){
00062 task->myDeps = taskIdListCopy(myDeps);
00063 }
00064
00065 void setTaskMetadata(Task *task, const char *metadata, const int metaSize){
00066 task->metaSize = metaSize;
00067
00068 if (metaSize == 0) {
00069 task->metadata = NULL;
00070 } else {
00071 task->metadata = malloc(sizeof(char) * metaSize);
00072 memcpy(task->metadata, metadata, metaSize);
00073 }
00074 }
00075
00076 void setTaskDataSpace(Task *task, DataSpace *dataSpace){
00077 task->dataSpace = dataSpace;
00078 }
00079
00080 void setTaskDependsOnMe(Task *task, TaskIdList *dependsOnMe){
00081 pthread_mutex_lock(&dependsOnMeMutex);
00082
00083 if (dependsOnMe == NULL) {
00084 task->dependsOnMe = NULL;
00085 } else {
00086 task->dependsOnMe = taskIdListCopy(dependsOnMe);
00087 }
00088
00089 pthread_mutex_unlock(&dependsOnMeMutex);
00090 }
00091
00092 void addTaskToDependsOnMe(Task *task, int taskId) {
00093 pthread_mutex_lock(&dependsOnMeMutex);
00094
00095 if (task->dependsOnMe == NULL) {
00096 task->dependsOnMe = taskIdListCreate(1);
00097 }
00098 taskIdListAdd(task->dependsOnMe, taskId);
00099
00100 pthread_mutex_unlock(&dependsOnMeMutex);
00101 }
00102
00103 void taskAddChild(Task *mother, int childId, Task *child) {
00104 child->mother = mother;
00105 PosHandlerIntVoid pos = hashIntVoidAdd(mother->children, childId);
00106 posSetValue(pos, child);
00107 }
00108
00109 HashIntVoid *taskTakeChildren(Task *task) {
00110 HashIntVoid *ret = task->children;
00111 task->children = hashIntVoidCreate(0);
00112
00113 return ret;
00114 }
00115
00116 void setTaskMother(Task *task, Task *mother) {
00117 task->mother = mother;
00118 }
00119
00120 void setTaskId(Task *task, int id) {
00121 task->id = id;
00122 }
00123
00124
00125 void taskMove(Task *dest, Task *src) {
00126 if (dest->myDeps != NULL) {
00127 taskIdListDestroy(dest->myDeps);
00128 }
00129 if (dest->dependsOnMe != NULL) {
00130 taskIdListDestroy(dest->dependsOnMe);
00131 }
00132 if (dest->children != NULL) {
00133 hashIntVoidDestroy(dest->children);
00134 }
00135 if (dest->metadata != NULL) {
00136 free(dest->metadata);
00137 }
00138 if (dest->dataSpace != NULL) {
00139 destroyDataSpace(dest->dataSpace);
00140 }
00141
00142 dest->myDeps = src->myDeps;
00143 dest->dependsOnMe = src->dependsOnMe;
00144 dest->children = src->children;
00145 dest->id = src->id;
00146 dest->mother = src->mother;
00147 dest->endedTasks = src->endedTasks;
00148 dest->metadata = src->metadata;
00149 dest->metaSize = src->metaSize;
00150 dest->state = src->state;
00151 dest->dataSpace = src->dataSpace;
00152
00153 free(src);
00154 }
00155
00156
00157
00158 int getTaskEndedTasks(Task *task){
00159 if(task == NULL){
00160 fprintf(stderr, "getTaskEndedTasks with NULL parameter\n");
00161 exit(1);
00162 }
00163 return task->endedTasks;
00164 }
00165
00166 int getTaskMetasize(Task *task){
00167 if(task == NULL){
00168 fprintf(stderr, "getTaskMetasize with NULL parameter\n");
00169 exit(1);
00170 }
00171 return task->metaSize;
00172 }
00173
00174 TaskState_t getTaskState(Task *task){
00175 if(task == NULL){
00176 fprintf(stderr, "getTaskState with NULL parameter\n");
00177 exit(1);
00178 }
00179 return task->state;
00180 }
00181
00182 char *getTaskMetadata(Task *task){
00183 #ifdef DEBUG
00184 if(task->metadata == NULL){
00185 fprintf(stderr, "warning - getTaskMetadata: task->metadata == NULL\n");
00186 }
00187 #endif
00188 return task->metadata;
00189 }
00190
00191 TaskIdList *getTaskMyDeps(Task *task){
00192 #ifdef DEBUG
00193 if(task->myDeps == NULL){
00194 fprintf(stderr, "warning - getTaskMydeps task->myDeps == NULL\n");
00195 }
00196 #endif
00197 return task->myDeps;
00198 }
00199
00200 TaskIdList *getTaskDependsOnMe(Task *task){
00201 #ifdef DEBUG
00202 if(task->dependsOnMe == NULL){
00203 fprintf(stderr, "warning - getTaskdepesOne task->dependsOnMe == NULL\n");
00204 }
00205 #endif
00206 return task->dependsOnMe;
00207 }
00208
00209 HashIntVoid *getTaskChildren(Task *task) {
00210 return task->children;
00211 }
00212
00213 DataSpace *getTaskDataSpace(Task *task){
00214 return task->dataSpace;
00215 }
00216
00217 Task *getTaskMother(Task *task){
00218 return task->mother;
00219 }
00220
00221 int getTaskId(Task *task) {
00222 return task->id;
00223 }
00224
00225
00226
00227 int writeTask(FILE *outputFile, void *task){
00228
00229 int endedTasks, metaSize, taskState;
00230 Task *auxTask = (Task *)task;
00231
00232 pthread_mutex_lock(&dependsOnMeMutex);
00233 writeTaskIdList(outputFile, (void *)auxTask->dependsOnMe);
00234 pthread_mutex_unlock(&dependsOnMeMutex);
00235 writeTaskIdList(outputFile, auxTask->myDeps);
00236
00237 HashIntVoid *children = auxTask->children;
00238 hashIntVoidSerialize(outputFile, children);
00239
00240 int id = getTaskId(auxTask);
00241 WRITE_NUM(outputFile, "id", id);
00242
00243 endedTasks = getTaskEndedTasks(auxTask);
00244 WRITE_NUM(outputFile, "endedTasks", endedTasks);
00245
00246 metaSize = getTaskMetasize(auxTask);
00247 WRITE_NUM(outputFile, "metaSize", metaSize);
00248
00249 WRITE_BYTES(outputFile, getTaskMetadata(auxTask), metaSize);
00250
00251 taskState = getTaskState(auxTask);
00252 WRITE_NUM(outputFile, "taskState", taskState);
00253
00254 writeDataSpace(outputFile, getTaskDataSpace(task));
00255 return 1;
00256 }
00257
00258 void *readTask(FILE *inputFile){
00259 Task *task = createTask();
00260 TaskIdList *list = NULL;
00261 int endedTasks=-1, metaSize=-1, taskState=-1, id=-1;
00262 char *metadata = NULL;
00263
00264 READ_BEGIN(inputFile);
00265
00266 list = (TaskIdList *)readTaskIdList(inputFile);
00267 setTaskDependsOnMe(task, list);
00268 taskIdListDestroy(list);
00269
00270 list = (TaskIdList *)readTaskIdList(inputFile);
00271 setTaskMyDeps(task, list);
00272 taskIdListDestroy(list);
00273
00274 hashIntVoidDeserialize(inputFile, task->children);
00275
00276
00277 HashIntVoidIterator *it = createHashIntVoidIterator(task->children, 0);
00278 PosHandlerIntVoid pos = hashIntVoidIteratorNext(it, task->children);
00279 while (pos != NULL) {
00280 Task *child = posGetValue(pos);
00281 child->mother = task;
00282
00283 pos = hashIntVoidIteratorNext(it, task->children);
00284 }
00285 hashIntVoidIteratorDestroy(it, task->children);
00286
00287 READ_NUM("id", id);
00288 setTaskId(task, id);
00289
00290 READ_NUM("endedTasks", endedTasks);
00291 setTaskEndedTasks(task, endedTasks);
00292
00293 READ_NUM("metaSize", metaSize);
00294 if (metaSize > 0) {
00295 metadata = malloc(metaSize);
00296 } else {
00297 metadata = NULL;
00298 }
00299 READ_BYTES(inputFile, metadata, metaSize);
00300 setTaskMetadata(task, metadata, metaSize);
00301 if(metadata != NULL){
00302 free(metadata);
00303 }
00304
00305 READ_NUM("taskState", taskState);
00306 setTaskState(task, taskState);
00307
00308 DataSpace* dataSpace = createDataSpace();
00309 readDataSpace(inputFile, dataSpace);
00310
00311 setTaskDataSpace(task, dataSpace);
00312
00313 READ_END
00314 return (void *)task;
00315 }
00316
00317
00318
00319
00320 int writeChildTask(FILE *outputFile, void *task){
00321
00322 int metaSize = 0;
00323 Task *auxTask = (Task *)task;
00324
00325 pthread_mutex_lock(&dependsOnMeMutex);
00326 writeTaskIdList(outputFile, (void *)auxTask->dependsOnMe);
00327 pthread_mutex_unlock(&dependsOnMeMutex);
00328 writeTaskIdList(outputFile, auxTask->myDeps);
00329
00330 int id = getTaskId(auxTask);
00331 WRITE_NUM(outputFile, "id", id);
00332
00333 metaSize = getTaskMetasize(auxTask);
00334 WRITE_NUM(outputFile, "metaSize", metaSize);
00335
00336 WRITE_BYTES(outputFile, getTaskMetadata(auxTask), metaSize);
00337
00338 return 1;
00339 }
00340
00341 void *readChildTask(FILE *inputFile){
00342 Task *task = createTask();
00343 TaskIdList *list = NULL;
00344 int metaSize = 0;
00345 char *metadata = NULL;
00346 int id = -1;
00347
00348 READ_BEGIN(inputFile);
00349
00350 list = (TaskIdList *)readTaskIdList(inputFile);
00351 setTaskDependsOnMe(task, list);
00352 taskIdListDestroy(list);
00353
00354 list = (TaskIdList *)readTaskIdList(inputFile);
00355 setTaskMyDeps(task, list);
00356 taskIdListDestroy(list);
00357
00358 READ_NUM("id", id);
00359 setTaskId(task, id);
00360 assert(id != -1);
00361
00362 READ_NUM("metaSize", metaSize);
00363 if (metaSize > 0) {
00364 metadata = malloc(metaSize);
00365 } else {
00366 metadata = NULL;
00367 }
00368 READ_BYTES(inputFile, metadata, metaSize);
00369 setTaskMetadata(task, metadata, metaSize);
00370 if(metadata != NULL){
00371 free(metadata);
00372 }
00373
00374 READ_END
00375 return (void *)task;
00376 }
00377
00378
00379
00380
00381
00382 int compareTasks(Task *task1, Task *task2){
00383 int ret = 0;
00384
00385 ret = taskIdListCompare(task1->myDeps, task2->myDeps);
00386 if (ret != 0) return 1;
00387
00388
00389 if (task1->dependsOnMe == NULL) {
00390 if (task2->dependsOnMe != NULL) {
00391 if (0 != taskIdListGetSize(task2->dependsOnMe)) {
00392 return -1;
00393 }
00394 }
00395 } else {
00396 if (task2->dependsOnMe == NULL) {
00397 if (0 != taskIdListGetSize(task1->dependsOnMe)) {
00398 return 1;
00399 }
00400 } else {
00401 ret = taskIdListCompare(task1->dependsOnMe, task2->dependsOnMe);
00402 if (ret != 0) return ret;
00403 }
00404 }
00405
00406 if (task1->id != task2->id) {
00407 return 1;
00408 }
00409
00410 if(task1->endedTasks != task2->endedTasks || task1->metaSize != task2->metaSize || task1->state != task2->state){
00411 return 1;
00412 }
00413
00414 if(memcmp(task1->metadata, task2->metadata, task1->metaSize)) return 1;
00415
00416
00417
00418 HashIntVoidIterator *it1 = createHashIntVoidIterator(task1->children, 0);
00419 PosHandlerIntVoid pos1 = hashIntVoidIteratorNext(it1, task1->children);
00420 while (pos1!=NULL) {
00421 Task *child1 = posGetValue(pos1);
00422 PosHandlerIntVoid pos2 = hashIntVoidGet(task2->children, posGetKey(pos1));
00423 Task *child2 = posGetValue(pos2);
00424
00425 ret = compareTasks(child1, child2);
00426 if (ret != 0) return ret;
00427
00428 pos1 = hashIntVoidIteratorNext(it1, task1->children);
00429 }
00430
00431 HashIntVoidIterator *it2 = createHashIntVoidIterator(task2->children, 0);
00432 PosHandlerIntVoid pos2 = hashIntVoidIteratorNext(it2, task2->children);
00433 while (pos2!=NULL) {
00434 Task *child2 = posGetValue(pos2);
00435 pos1 = hashIntVoidGet(task1->children, posGetKey(pos2));
00436 Task *child1 = posGetValue(pos1);
00437
00438 ret = compareTasks(child1, child2);
00439 if (ret != 0) return ret;
00440
00441 pos2 = hashIntVoidIteratorNext(it2, task2->children);
00442 }
00443 return 0;
00444 }