pelib  2.0.0
include/pelib/stack.c
Go to the documentation of this file.
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