1
/* Copyright (c) 2005 PrimeBase Technologies GmbH
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
* 2005-02-03 Paul McCullagh
24
#include "xt_config.h"
26
#include "pthread_xt.h"
27
#include "linklist_xt.h"
28
#include "thread_xt.h"
29
#include "memory_xt.h"
31
xtPublic XTLinkedListPtr xt_new_linkedlist(struct XTThread *self, void *thunk, XTFreeFunc free_func, xtBool with_lock)
35
ll = (XTLinkedListPtr) xt_calloc(self, sizeof(XTLinkedListRec));
38
ll->ll_lock = (xt_mutex_type *) xt_calloc(self, sizeof(xt_mutex_type));
40
xt_init_mutex_with_autoname(self, ll->ll_lock);
43
xt_free(self, ll->ll_lock);
48
ll->ll_cond = (xt_cond_type *) xt_calloc(self, sizeof(xt_cond_type));
50
xt_init_cond(self, ll->ll_cond);
53
xt_free(self, ll->ll_cond);
60
ll->ll_free_func = free_func;
63
xt_free_linkedlist(self, ll);
70
xtPublic void xt_free_linkedlist(XTThreadPtr self, XTLinkedListPtr ll)
73
xt_lock_mutex(self, ll->ll_lock);
75
xt_ll_remove(self, ll, ll->ll_items, FALSE);
77
xt_unlock_mutex(self, ll->ll_lock);
79
xt_free_mutex(ll->ll_lock);
80
xt_free(self, ll->ll_lock);
83
xt_free_cond(ll->ll_cond);
84
xt_free(self, ll->ll_cond);
89
xtPublic void xt_ll_add(XTThreadPtr self, XTLinkedListPtr ll, XTLinkedItemPtr li, xtBool lock)
91
if (lock && ll->ll_lock)
92
xt_lock_mutex(self, ll->ll_lock);
93
li->li_next = ll->ll_items;
96
ll->ll_items->li_prev = li;
99
if (lock && ll->ll_lock)
100
xt_unlock_mutex(self, ll->ll_lock);
103
xtPublic XTLinkedItemPtr xt_ll_first_item(XTThreadPtr XT_UNUSED(self), XTLinkedListPtr ll)
105
return ll ? ll->ll_items : NULL;
108
xtPublic XTLinkedItemPtr xt_ll_next_item(XTThreadPtr XT_UNUSED(self), XTLinkedItemPtr item)
110
return item->li_next;
113
xtPublic xtBool xt_ll_exists(XTThreadPtr self, XTLinkedListPtr ll, XTLinkedItemPtr li, xtBool lock)
117
if (lock && ll->ll_lock)
118
xt_lock_mutex(self, ll->ll_lock);
122
for (ptr = ll->ll_items; ptr && (ptr != li); ptr = ptr->li_next){}
124
if (lock && ll->ll_lock)
125
xt_unlock_mutex(self, ll->ll_lock);
130
xtPublic void xt_ll_remove(XTThreadPtr self, XTLinkedListPtr ll, XTLinkedItemPtr li, xtBool lock)
132
if (lock && ll->ll_lock)
133
xt_lock_mutex(self, ll->ll_lock);
135
/* Move front pointer: */
136
if (ll->ll_items == li)
137
ll->ll_items = li->li_next;
139
/* Remove from list: */
141
li->li_prev->li_next = li->li_next;
143
li->li_next->li_prev = li->li_prev;
146
if (ll->ll_free_func)
147
(*ll->ll_free_func)(self, ll->ll_thunk, li);
149
/* Signal one less: */
151
xt_signal_cond(self, ll->ll_cond);
153
if (lock && ll->ll_lock)
154
xt_unlock_mutex(self, ll->ll_lock);
157
xtPublic void xt_ll_lock(XTThreadPtr self, XTLinkedListPtr ll)
160
xt_lock_mutex(self, ll->ll_lock);
163
xtPublic void xt_ll_unlock(XTThreadPtr self, XTLinkedListPtr ll)
166
xt_unlock_mutex(self, ll->ll_lock);
169
xtPublic void xt_ll_wait_till_empty(XTThreadPtr self, XTLinkedListPtr ll)
171
xt_lock_mutex(self, ll->ll_lock);
172
pushr_(xt_unlock_mutex, ll->ll_lock);
174
if (ll->ll_item_count == 0)
176
xt_wait_cond(self, ll->ll_cond, ll->ll_lock);
178
freer_(); // xt_unlock_mutex(ll->ll_lock)
181
xtPublic u_int xt_ll_get_size(XTLinkedListPtr ll)
183
return ll->ll_item_count;
186
xtPublic void xt_init_linkedqueue(XTThreadPtr XT_UNUSED(self), XTLinkedQueuePtr lq)
193
xtPublic void xt_exit_linkedqueue(XTThreadPtr XT_UNUSED(self), XTLinkedQueuePtr lq)
200
xtPublic void xt_lq_add(XTThreadPtr XT_UNUSED(self), XTLinkedQueuePtr lq, XTLinkedQItemPtr qi)
207
lq->lq_back->qi_next = qi;
211
xtPublic XTLinkedQItemPtr xt_lq_remove(XTThreadPtr XT_UNUSED(self), XTLinkedQueuePtr lq)
213
XTLinkedQItemPtr qi = NULL;
217
lq->lq_front = qi->qi_next;