1
/* Copyright (c) 2005 SNAP Innovation 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 "xt_linklist.h"
27
#include "xt_thread.h"
28
#include "xt_memory.h"
30
xtPublic XTLinkedListPtr xt_new_linkedlist(struct XTThread *self, void *thunk, XTFreeFunc free_func, xtBool with_lock)
34
ll = (XTLinkedListPtr) xt_calloc(self, sizeof(XTLinkedListRec));
37
ll->ll_lock = xt_calloc(self, sizeof(xt_mutex_type));
39
xt_init_mutex(self, ll->ll_lock);
42
xt_free(self, ll->ll_lock);
47
ll->ll_cond = xt_calloc(self, sizeof(xt_cond_type));
49
xt_init_cond(self, ll->ll_cond);
52
xt_free(self, ll->ll_cond);
59
ll->ll_free_func = free_func;
62
xt_free_linkedlist(self, ll);
69
xtPublic void xt_free_linkedlist(XTThreadPtr self, XTLinkedListPtr ll)
72
xt_lock_mutex(self, ll->ll_lock);
74
xt_ll_remove(self, ll, ll->ll_items, FALSE);
76
xt_unlock_mutex(self, ll->ll_lock);
78
xt_free_mutex(ll->ll_lock);
79
xt_free(self, ll->ll_lock);
82
xt_free_cond(ll->ll_cond);
83
xt_free(self, ll->ll_cond);
88
xtPublic void xt_ll_add(XTThreadPtr self, XTLinkedListPtr ll, XTLinkedItemPtr li, xtBool lock)
90
if (lock && ll->ll_lock)
91
xt_lock_mutex(self, ll->ll_lock);
92
li->li_next = ll->ll_items;
95
ll->ll_items->li_prev = li;
98
if (lock && ll->ll_lock)
99
xt_unlock_mutex(self, ll->ll_lock);
102
xtPublic XTLinkedItemPtr xt_ll_first_item(XTThreadPtr self, XTLinkedListPtr ll)
105
return ll ? ll->ll_items : NULL;
108
xtPublic XTLinkedItemPtr xt_ll_next_item(XTThreadPtr self, XTLinkedItemPtr item)
111
return item->li_next;
114
xtPublic xtBool xt_ll_exists(XTThreadPtr self, XTLinkedListPtr ll, XTLinkedItemPtr li, xtBool lock)
118
if (lock && ll->ll_lock)
119
xt_lock_mutex(self, ll->ll_lock);
123
for (ptr = ll->ll_items; ptr && (ptr != li); ptr = ptr->li_next){}
125
if (lock && ll->ll_lock)
126
xt_unlock_mutex(self, ll->ll_lock);
131
xtPublic void xt_ll_remove(XTThreadPtr self, XTLinkedListPtr ll, XTLinkedItemPtr li, xtBool lock)
133
if (lock && ll->ll_lock)
134
xt_lock_mutex(self, ll->ll_lock);
136
/* Move front pointer: */
137
if (ll->ll_items == li)
138
ll->ll_items = li->li_next;
140
/* Remove from list: */
142
li->li_prev->li_next = li->li_next;
144
li->li_next->li_prev = li->li_prev;
147
if (ll->ll_free_func)
148
(*ll->ll_free_func)(self, ll->ll_thunk, li);
150
/* Signal one less: */
152
xt_signal_cond(self, ll->ll_cond);
154
if (lock && ll->ll_lock)
155
xt_unlock_mutex(self, ll->ll_lock);
158
xtPublic void xt_ll_lock(XTThreadPtr self, XTLinkedListPtr ll)
161
xt_lock_mutex(self, ll->ll_lock);
164
xtPublic void xt_ll_unlock(XTThreadPtr self, XTLinkedListPtr ll)
167
xt_unlock_mutex(self, ll->ll_lock);
170
xtPublic void xt_ll_wait_till_empty(XTThreadPtr self, XTLinkedListPtr ll)
172
xt_lock_mutex(self, ll->ll_lock);
173
pushr_(xt_unlock_mutex, ll->ll_lock);
175
if (ll->ll_item_count == 0)
177
xt_wait_cond(self, ll->ll_cond, ll->ll_lock);
179
freer_(); // xt_unlock_mutex(ll->ll_lock)
182
xtPublic u_int xt_ll_get_size(XTLinkedListPtr ll)
184
return ll->ll_item_count;
187
xtPublic void xt_init_linkedqueue(XTThreadPtr self, XTLinkedQueuePtr lq)
195
xtPublic void xt_exit_linkedqueue(XTThreadPtr self, XTLinkedQueuePtr lq)
203
xtPublic void xt_lq_add(XTThreadPtr self, XTLinkedQueuePtr lq, XTLinkedQItemPtr qi)
211
lq->lq_back->qi_next = qi;
215
xtPublic XTLinkedQItemPtr xt_lq_remove(XTThreadPtr self, XTLinkedQueuePtr lq)
218
XTLinkedQItemPtr qi = NULL;
222
lq->lq_front = qi->qi_next;