00001 /* SVN FILE INFO 00002 * $Revision: 174 $ : Last Committed Revision 00003 * $Date: 2008年06月24日 10:50:29 -0700 (2008年6月24日) $ : Last Committed Date */ 00004 /*[ 00005 * Copyright (c) 2007 Integration Engineering Laboratory 00006 University of California, Davis 00007 * 00008 * Permission to use, copy, and distribute this software and its 00009 * documentation for any purpose with or without fee is hereby granted, 00010 * provided that the above copyright notice appear in all copies and 00011 * that both that copyright notice and this permission notice appear 00012 * in supporting documentation. 00013 * 00014 * Permission to modify the software is granted, but not the right to 00015 * distribute the complete modified source code. Modifications are to 00016 * be distributed as patches to the released version. Permission to 00017 * distribute binaries produced by compiling modified sources is granted, 00018 * provided you 00019 * 1. distribute the corresponding source modifications from the 00020 * released version in the form of a patch file along with the binaries, 00021 * 2. add special version identification to distinguish your version 00022 * in addition to the base release version number, 00023 * 3. provide your name and address as the primary contact for the 00024 * support of your modified version, and 00025 * 4. retain our contact information in regard to use of the base 00026 * software. 00027 * Permission to distribute the released version of the source code along 00028 * with corresponding source modifications in the form of a patch file is 00029 * granted with same provisions 2 through 4 for binary distributions. 00030 * 00031 * This software is provided "as is" without express or implied warranty 00032 * to the extent permitted by applicable law. 00033 ]*/ 00034 00035 #include "include/barrier.h" 00036 #include "include/mc_error.h" 00037 00038 /* Node Funcs */ 00039 barrier_node_p 00040 barrier_node_Initialize(int id, int num_registered) 00041 { 00042 barrier_node_p node; 00043 00044 /* Memory Allocation */ 00045 node = (barrier_node_p)malloc(sizeof(barrier_node_t)); 00046 CHECK_NULL(node, return NULL;); 00047 node->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T)); 00048 CHECK_NULL(node->lock, return NULL;); 00049 node->cond = (COND_T*)malloc(sizeof(COND_T)); 00050 CHECK_NULL(node->cond, return NULL;); 00051 00052 /* Sync Init */ 00053 MUTEX_INIT(node->lock); 00054 COND_INIT(node->cond); 00055 00056 /* Initial values */ 00057 node->id = id; 00058 node->num_registered = num_registered; 00059 node->num_waiting = 0; 00060 00061 return node; 00062 } 00063 00064 int 00065 barrier_node_Destroy(barrier_node_p node) 00066 { 00067 /* Sync Destroy */ 00068 MUTEX_DESTROY(node->lock); 00069 COND_DESTROY(node->cond); 00070 00071 /* Free Memory */ 00072 free(node->cond); 00073 free(node->lock); 00074 free(node); 00075 00076 return MC_SUCCESS; 00077 } 00078 00079 /* List Funcs */ 00080 00081 int 00082 barrier_queue_Add(barrier_queue_p list, barrier_node_p node) 00083 { 00084 /* Check for identical IDs and warn */ 00085 int err_code = MC_SUCCESS; 00086 listNode_t *tmp; 00087 RWLOCK_WRLOCK(list->lock); 00088 tmp = (listNode_t*)list->list->listhead; 00089 while(tmp != NULL) { 00090 if (((barrier_node_p)(tmp->node_data))->id == node->id) { 00091 fprintf(stderr, 00092 "Warning: Barrier node id %d reregistered. %s:%d\n", 00093 node->id, __FILE__, __LINE__ ); 00094 err_code = MC_WARN_DUPLICATE; 00095 continue; 00096 } 00097 tmp = tmp->next; 00098 } 00099 ListAdd(list->list, (DATA) node); 00100 list->size++; 00101 RWLOCK_WRUNLOCK(list->lock); 00102 return err_code; 00103 } 00104 00105 int 00106 barrier_queue_Delete(int id, barrier_queue_p list) 00107 { 00108 int i; 00109 barrier_node_p tmp; 00110 RWLOCK_WRLOCK(list->lock); 00111 for (i = 0; i < list->list->size; i++) { 00112 tmp = (barrier_node_p)ListSearch(list->list, i); 00113 if (tmp->id == id) { 00114 ListDelete(list->list, id); 00115 barrier_node_Destroy(tmp); 00116 list->size--; 00117 RWLOCK_WRUNLOCK(list->lock); 00118 return MC_SUCCESS; 00119 } 00120 } 00121 RWLOCK_WRUNLOCK(list->lock); 00122 return MC_ERR_NOT_FOUND; 00123 } 00124 00125 int 00126 barrier_queue_Destroy(barrier_queue_p queue) 00127 { 00128 barrier_node_p node; 00129 while((node = barrier_queue_Pop(queue)) != NULL) { 00130 barrier_node_Destroy(node); 00131 } 00132 ListTerminate(queue->list); 00133 RWLOCK_DESTROY(queue->lock); 00134 free(queue->lock); 00135 free(queue); 00136 return MC_SUCCESS; 00137 } 00138 00139 barrier_node_p 00140 barrier_queue_Get(barrier_queue_p list, int id) 00141 { 00142 listNode_t* tmp; 00143 RWLOCK_RDLOCK(list->lock); 00144 tmp = (listNode_t*)list->list->listhead; 00145 while (tmp != NULL) { 00146 if (((barrier_node_p)(tmp->node_data))->id == id) { 00147 RWLOCK_RDUNLOCK(list->lock); 00148 return ((barrier_node_p)tmp->node_data); 00149 } 00150 tmp = tmp->next; 00151 } 00152 RWLOCK_RDUNLOCK(list->lock); 00153 return NULL; 00154 } 00155 00156 barrier_queue_p 00157 barrier_queue_New(void) 00158 { 00159 barrier_queue_p new_list; 00160 new_list = (barrier_queue_p)malloc(sizeof(barrier_queue_t)); 00161 CHECK_NULL(new_list, return NULL;); 00162 new_list->lock = (RWLOCK_T*)malloc(sizeof(RWLOCK_T)); 00163 CHECK_NULL(new_list->lock, return NULL;); 00164 RWLOCK_INIT(new_list->lock); 00165 00166 new_list->list = ListInitialize(); 00167 return new_list; 00168 } 00169 00170 barrier_node_p 00171 barrier_queue_Pop(barrier_queue_p queue) 00172 { 00173 barrier_node_p node = (barrier_node_p)ListPop(queue->list); 00174 return node; 00175 } 00176