pelib
2.0.0
|
00001 /* 00002 * stack.h 00003 * 00004 * Created on: 18 Oct 2011 00005 * Copyright 2011 Nicolas Melot 00006 * 00007 * This file is part of pelib. 00008 * 00009 * pelib is free software: you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation, either version 3 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * pelib is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with pelib. If not, see <http://www.gnu.org/licenses/>. 00021 * 00022 */ 00023 00024 #include <assert.h> 00025 #include <pthread.h> 00026 #include <string.h> 00027 #include <stdlib.h> 00028 #include <stdio.h> 00029 #include <stdint.h> 00030 00031 int 00032 pelib_init(stackelem_t(STACK_T))(stackelem_t(STACK_T) *elem) 00033 { 00034 assert(elem != NULL); 00035 elem->next = NULL; 00036 00037 return 1; 00038 } 00039 00040 int 00041 pelib_stackelem_write(STACK_T)(stackelem_t(STACK_T) *elem, STACK_T buffer) 00042 { 00043 assert(pelib_stackelem_check(STACK_T)(elem) == 0); 00044 00045 return pelib_copy(STACK_T)(buffer, &elem->buffer); 00046 } 00047 00048 int 00049 pelib_stackelem_read(STACK_T)(stackelem_t(STACK_T) *elem, STACK_T* buffer) 00050 { 00051 assert(buffer != NULL); 00052 assert(pelib_stackelem_check(STACK_T)(elem) == 0); 00053 00054 return pelib_copy(STACK_T)(elem->buffer, buffer); 00055 } 00056 00057 int 00058 pelib_stackelem_check(STACK_T)(stackelem_t(STACK_T) *elem) 00059 { 00060 assert(elem != NULL); 00061 00062 return 1; 00063 } 00064 00065 stack_t(STACK_T) * 00066 pelib_alloc_collection(stack_t(STACK_T))(size_t aux) 00067 { 00068 stack_t(STACK_T) *res; 00069 00070 res = malloc(sizeof(stack_t(STACK_T))); 00071 assert(res != NULL); 00072 00073 if (res == NULL) 00074 return NULL; 00075 00076 res->top = NULL; 00077 00078 return res; 00079 } 00080 00081 int 00082 pelib_init(stack_t(STACK_T))(stack_t(STACK_T) *s) 00083 { 00084 pthread_mutexattr_t attr; 00085 00086 assert(s != NULL); 00087 00088 pthread_mutexattr_init(&attr); 00089 pthread_mutex_init(&s->lock, &attr); 00090 s->top = NULL; 00091 00092 return 1; 00093 } 00094 00095 int 00096 pelib_free(stack_t(STACK_T))(stack_t(STACK_T) *s) 00097 { 00098 pthread_mutex_destroy(&s->lock); 00099 free(s); 00100 00101 return 1; 00102 } 00103 00104 int 00105 pelib_stack_check(STACK_T)(stack_t(STACK_T) *s) 00106 { 00107 assert(s != NULL); 00108 00109 return 1; 00110 } 00111 00112 int 00113 pelib_stack_isempty(STACK_T)(stack_t(STACK_T) *s) 00114 { 00115 return s->top == NULL; 00116 } 00117 00118 int 00119 pelib_stack_push(STACK_T)(stack_t(STACK_T) *s, STACK_T buffer) 00120 { 00121 stackelem_t(STACK_T) * elem; 00122 00123 elem = malloc(sizeof(stackelem_t(STACK_T))); 00124 assert(elem != NULL); 00125 if (elem == NULL) 00126 return 0; 00127 00128 pelib_init(stackelem_t(STACK_T))(elem); 00129 pelib_stackelem_write(STACK_T)(elem, buffer); 00130 00131 pelib_stack_push_elem(STACK_T)(s, elem); 00132 00133 return 1; 00134 } 00135 00136 int 00137 pelib_stack_pop(STACK_T)(stack_t(STACK_T) *s, STACK_T* buffer) 00138 { 00139 stackelem_t(STACK_T) * elem; 00140 00141 if (!pelib_stack_peek(STACK_T)(s, buffer)) 00142 { 00143 return 0; 00144 } 00145 00146 pelib_stack_pop_elem(STACK_T)(s, &elem); 00147 free(elem); 00148 00149 return 1; 00150 } 00151 00152 int 00153 pelib_stack_peek(STACK_T)(stack_t(STACK_T) *s, STACK_T* buffer) 00154 { 00155 if (s->top == NULL) 00156 { 00157 return 0; 00158 } 00159 00160 pelib_stackelem_read(STACK_T)(s->top, buffer); 00161 00162 return 1; 00163 } 00164 00165 int 00166 pelib_stack_push_safe(STACK_T)(stack_t(STACK_T) *s, STACK_T buffer) 00167 { 00168 pthread_mutex_lock(&s->lock); 00169 pelib_stack_push(STACK_T)(s, buffer); 00170 pthread_mutex_unlock(&s->lock); 00171 00172 return 1; 00173 } 00174 00175 int 00176 pelib_stack_pop_safe(STACK_T)(stack_t(STACK_T) *s, STACK_T* buffer) 00177 { 00178 pthread_mutex_lock(&s->lock); 00179 pelib_stack_pop(STACK_T)(s, buffer); 00180 pthread_mutex_unlock(&s->lock); 00181 00182 return 1; 00183 } 00184 00185 int 00186 pelib_stack_push_elem(STACK_T)(stack_t(STACK_T) *s, stackelem_t(STACK_T) *elem) 00187 { 00188 assert(pelib_stack_check(STACK_T)(s) == 0); 00189 assert(s->top != elem); 00190 00191 // Here comes the swap 00192 elem->next = s->top; 00193 s->top = elem; 00194 00195 return 1; 00196 } 00197 00198 int 00199 pelib_stack_pop_elem(STACK_T)(stack_t(STACK_T) *s, stackelem_t(STACK_T) **elem) 00200 { 00201 assert(pelib_stack_check(STACK_T)(s) == 0); 00202 00203 if (s->top == NULL) 00204 { 00205 return 0; 00206 } 00207 00208 // Here comes the swap 00209 *elem = s->top; 00210 s->top = (*elem)->next; 00211 00212 (*elem)->next = NULL; 00213 00214 return 1; 00215 } 00216 00217 int 00218 pelib_stack_push_elem_safe(STACK_T)(stack_t(STACK_T) *s, stackelem_t(STACK_T) *elem) 00219 { 00220 assert(s->top != elem); 00221 00222 pthread_mutex_lock(&s->lock); 00223 pelib_stack_push_elem(STACK_T)(s, elem); 00224 pthread_mutex_unlock(&s->lock); 00225 00226 return 1; 00227 } 00228 00229 int 00230 pelib_stack_pop_elem_safe(STACK_T)(stack_t(STACK_T) *s, stackelem_t(STACK_T) **elem) 00231 { 00232 pthread_mutex_lock(&s->lock); 00233 pelib_stack_pop_elem(STACK_T)(s, elem); 00234 pthread_mutex_unlock(&s->lock); 00235 00236 return 1; 00237 } 00238 00239 int 00240 pelib_stack_push_safe_managed(STACK_T)(stack_t(STACK_T) *s, stack_t(STACK_T) *pool, STACK_T buffer) 00241 { 00242 stackelem_t(STACK_T) *elem = NULL; 00243 00244 assert(pelib_stack_check(STACK_T)(pool) == 0); 00245 00246 if (pelib_stack_pop_elem(STACK_T)(pool, &elem) != 1) 00247 { 00248 elem = malloc(sizeof(stackelem_t(STACK_T))); 00249 pelib_init(stackelem_t(STACK_T))(elem); 00250 } 00251 00252 pelib_stackelem_write(STACK_T)(elem, buffer); 00253 00254 pelib_stack_push_elem_safe(STACK_T)(s, elem); 00255 00256 return 1; 00257 } 00258 00259 int 00260 pelib_stack_pop_safe_managed(STACK_T)(stack_t(STACK_T) *s, stack_t(STACK_T) *pool, STACK_T* buffer) 00261 { 00262 stackelem_t(STACK_T) *elem = NULL; 00263 00264 if (pelib_stack_pop_elem_safe(STACK_T)(s, &elem) != 1) 00265 { 00266 return 0; 00267 } 00268 pelib_stackelem_read(STACK_T)(elem, buffer); 00269 00270 pelib_stack_push_elem(STACK_T)(pool, elem); 00271 00272 return 1; 00273 } 00274 00275 #undef STACK_T