~vkolesnikov/pbxt/pbxt-07-diskfull

« back to all changes in this revision

Viewing changes to pbxt/src/c_linklist.c

  • Committer: paul-mccullagh
  • Date: 2006-10-23 09:14:04 UTC
  • Revision ID: paul-mccullagh-918861e03d351978a9541168a96e58cc826734ee
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2005 SNAP Innovation GmbH
 
2
 *
 
3
 * PrimeBase XT
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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
 
18
 *
 
19
 * 2005-02-03   Paul McCullagh
 
20
 *
 
21
 * H&G2JCtL
 
22
 */
 
23
 
 
24
#include "xt_config.h"
 
25
 
 
26
#include "xt_linklist.h"
 
27
#include "xt_thread.h"
 
28
#include "xt_memory.h"
 
29
 
 
30
xtPublic XTLinkedListPtr xt_new_linkedlist(struct XTThread *self, void *thunk, XTFreeFunc free_func, xtBool with_lock)
 
31
{
 
32
        XTLinkedListPtr ll;
 
33
 
 
34
        ll = (XTLinkedListPtr) xt_calloc(self, sizeof(XTLinkedListRec));
 
35
        try_(a) {
 
36
                if (with_lock) {
 
37
                        ll->ll_lock = xt_calloc(self, sizeof(xt_mutex_type));
 
38
                        try_(b) {
 
39
                                xt_init_mutex(self, ll->ll_lock);
 
40
                        }
 
41
                        catch_(b) {
 
42
                                xt_free(self, ll->ll_lock);
 
43
                                ll->ll_lock = NULL;
 
44
                                throw_();
 
45
                        }
 
46
                        cont_(b);
 
47
                        ll->ll_cond = xt_calloc(self, sizeof(xt_cond_type));
 
48
                        try_(c) {
 
49
                                xt_init_cond(self, ll->ll_cond);
 
50
                        }
 
51
                        catch_(c) {
 
52
                                xt_free(self, ll->ll_cond);
 
53
                                ll->ll_cond = NULL;
 
54
                                throw_();
 
55
                        }
 
56
                        cont_(c);
 
57
                }
 
58
                ll->ll_thunk = thunk;
 
59
                ll->ll_free_func = free_func;
 
60
        }
 
61
        catch_(a) {
 
62
                xt_free_linkedlist(self, ll);
 
63
                throw_();
 
64
        }
 
65
        cont_(a);
 
66
        return ll;
 
67
}
 
68
 
 
69
xtPublic void xt_free_linkedlist(XTThreadPtr self, XTLinkedListPtr ll)
 
70
{
 
71
        if (ll->ll_lock)
 
72
                xt_lock_mutex(self, ll->ll_lock);
 
73
        while (ll->ll_items)
 
74
                xt_ll_remove(self, ll, ll->ll_items, FALSE);
 
75
        if (ll->ll_lock)
 
76
                xt_unlock_mutex(self, ll->ll_lock);
 
77
        if (ll->ll_lock) {
 
78
                xt_free_mutex(ll->ll_lock);
 
79
                xt_free(self, ll->ll_lock);
 
80
        }
 
81
        if (ll->ll_cond) {
 
82
                xt_free_cond(ll->ll_cond);
 
83
                xt_free(self, ll->ll_cond);
 
84
        }
 
85
        xt_free(self, ll);
 
86
}
 
87
 
 
88
xtPublic void xt_ll_add(XTThreadPtr self, XTLinkedListPtr ll, XTLinkedItemPtr li, xtBool lock)
 
89
{
 
90
        if (lock && ll->ll_lock)
 
91
                xt_lock_mutex(self, ll->ll_lock);
 
92
        li->li_next = ll->ll_items;
 
93
        li->li_prev = NULL;
 
94
        if (ll->ll_items)
 
95
                ll->ll_items->li_prev = li;
 
96
        ll->ll_items = li;
 
97
        ll->ll_item_count++;
 
98
        if (lock && ll->ll_lock)
 
99
                xt_unlock_mutex(self, ll->ll_lock);
 
100
}
 
101
 
 
102
xtPublic XTLinkedItemPtr xt_ll_first_item(XTThreadPtr self, XTLinkedListPtr ll)
 
103
{
 
104
#pragma unused(self)
 
105
        return ll ? ll->ll_items : NULL;
 
106
}
 
107
 
 
108
xtPublic XTLinkedItemPtr xt_ll_next_item(XTThreadPtr self, XTLinkedItemPtr item)
 
109
{
 
110
#pragma unused(self)
 
111
        return item->li_next;
 
112
}
 
113
 
 
114
xtPublic xtBool xt_ll_exists(XTThreadPtr self, XTLinkedListPtr ll, XTLinkedItemPtr li, xtBool lock)
 
115
{
 
116
XTLinkedItemPtr ptr;
 
117
 
 
118
        if (lock && ll->ll_lock)
 
119
                xt_lock_mutex(self, ll->ll_lock);
 
120
 
 
121
        ptr = ll->ll_items;
 
122
        
 
123
        for (ptr = ll->ll_items; ptr && (ptr != li); ptr = ptr->li_next){}
 
124
        
 
125
        if (lock && ll->ll_lock)
 
126
                xt_unlock_mutex(self, ll->ll_lock);
 
127
                
 
128
        return (ptr == li);
 
129
}
 
130
 
 
131
xtPublic void xt_ll_remove(XTThreadPtr self, XTLinkedListPtr ll, XTLinkedItemPtr li, xtBool lock)
 
132
{
 
133
        if (lock && ll->ll_lock)
 
134
                xt_lock_mutex(self, ll->ll_lock);
 
135
 
 
136
        /* Move front pointer: */
 
137
        if (ll->ll_items == li)
 
138
                ll->ll_items = li->li_next;
 
139
 
 
140
        /* Remove from list: */
 
141
        if (li->li_prev)
 
142
                li->li_prev->li_next = li->li_next;
 
143
        if (li->li_next)
 
144
                li->li_next->li_prev = li->li_prev;
 
145
 
 
146
        ll->ll_item_count--;
 
147
        if (ll->ll_free_func)
 
148
                (*ll->ll_free_func)(self, ll->ll_thunk, li);
 
149
 
 
150
        /* Signal one less: */
 
151
        if (ll->ll_cond)
 
152
                xt_signal_cond(self, ll->ll_cond);
 
153
 
 
154
        if (lock && ll->ll_lock)
 
155
                xt_unlock_mutex(self, ll->ll_lock);
 
156
}
 
157
 
 
158
xtPublic void xt_ll_lock(XTThreadPtr self, XTLinkedListPtr ll)
 
159
{
 
160
        if (ll->ll_lock)
 
161
                xt_lock_mutex(self, ll->ll_lock);
 
162
}
 
163
 
 
164
xtPublic void xt_ll_unlock(XTThreadPtr self, XTLinkedListPtr ll)
 
165
{
 
166
        if (ll->ll_lock)
 
167
                xt_unlock_mutex(self, ll->ll_lock);
 
168
}
 
169
 
 
170
xtPublic void xt_ll_wait_till_empty(XTThreadPtr self, XTLinkedListPtr ll)
 
171
{
 
172
        xt_lock_mutex(self, ll->ll_lock);
 
173
        pushr_(xt_unlock_mutex, ll->ll_lock);
 
174
        for (;;) {
 
175
                if (ll->ll_item_count == 0)
 
176
                        break;
 
177
                xt_wait_cond(self, ll->ll_cond, ll->ll_lock);
 
178
        }
 
179
        freer_(); // xt_unlock_mutex(ll->ll_lock)
 
180
}
 
181
 
 
182
xtPublic u_int xt_ll_get_size(XTLinkedListPtr ll)
 
183
{
 
184
        return ll->ll_item_count;
 
185
}
 
186
 
 
187
xtPublic void xt_init_linkedqueue(XTThreadPtr self, XTLinkedQueuePtr lq)
 
188
{
 
189
#pragma unused(self)
 
190
        lq->lq_count = 0;
 
191
        lq->lq_front = NULL;
 
192
        lq->lq_back = NULL;
 
193
}
 
194
 
 
195
xtPublic void xt_exit_linkedqueue(XTThreadPtr self, XTLinkedQueuePtr lq)
 
196
{
 
197
#pragma unused(self)
 
198
        lq->lq_count = 0;
 
199
        lq->lq_front = NULL;
 
200
        lq->lq_back = NULL;
 
201
}
 
202
 
 
203
xtPublic void xt_lq_add(XTThreadPtr self, XTLinkedQueuePtr lq, XTLinkedQItemPtr qi)
 
204
{
 
205
#pragma unused(self)
 
206
        lq->lq_count++;
 
207
        qi->qi_next = NULL;
 
208
        if (!lq->lq_front)
 
209
                lq->lq_front = qi;
 
210
        if (lq->lq_back)
 
211
                lq->lq_back->qi_next = qi;
 
212
        lq->lq_back = qi;
 
213
}
 
214
 
 
215
xtPublic XTLinkedQItemPtr xt_lq_remove(XTThreadPtr self, XTLinkedQueuePtr lq)
 
216
{
 
217
#pragma unused(self)
 
218
        XTLinkedQItemPtr qi = NULL;
 
219
 
 
220
        if (!lq->lq_front) {
 
221
                qi = lq->lq_front;
 
222
                lq->lq_front = qi->qi_next;
 
223
                if (!lq->lq_front)
 
224
                        lq->lq_back = NULL;
 
225
                qi->qi_next = NULL;
 
226
        }
 
227
        return qi;
 
228
}
 
229