Tizen 2.1 base
[platform/upstream/gcd.git] / pthread_workqueue-0.8.2 / src / witem_cache.c
1 /*
2  * Copyright (c) 2011, Joakim Johansson <jocke@tbricks.com>
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice unmodified, this list of conditions, and the following
11  *    disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28
29 #include "private.h"
30
31
32 /* no witem cache */
33
34 #if (WITEM_CACHE_TYPE == 1)
35
36 int
37 witem_cache_init(void)
38 {
39    return (0);
40 }
41
42 struct work *
43 witem_alloc(void (*func)(void *), void *func_arg)
44 {
45         struct work *witem;
46     
47         while (!(witem = fastpath(malloc(ROUND_UP_TO_CACHELINE_SIZE(sizeof(*witem)))))) {
48                 sleep(1);
49         }
50
51     witem->gencount = 0;
52     witem->flags = 0;
53     witem->item_entry.stqe_next = 0;
54     witem->func = func;
55     witem->func_arg = func_arg;
56
57         return witem;
58 }
59
60 void 
61 witem_free(struct work *wi)
62 {
63     dbg_printf("freed work item %p", wi);
64     free(wi);
65 }
66
67 void
68 witem_cache_cleanup(void *value)
69 {
70     (void) value;
71 }
72
73 /* libumem based object cache */
74
75 #elif (WITEM_CACHE_TYPE == 2)
76
77 #include <umem.h>
78
79 static umem_cache_t  *witem_cache;
80
81 int
82 witem_cache_init(void)
83 {
84     witem_cache = umem_cache_create((char *) "witem_cache",   
85                                     sizeof(struct work),   
86                                     CACHELINE_SIZE,  
87                                     NULL,
88                                     NULL, 
89                                     NULL, 
90                                     NULL, 
91                                     NULL, 
92                                     0);
93     return (0);
94 }
95
96 struct work *
97 witem_alloc(void (*func)(void *), void *func_arg)
98 {
99         struct work *witem;
100     
101         while (!(witem = fastpath(umem_cache_alloc(witem_cache, UMEM_DEFAULT)))) {
102                 sleep(1);
103         }
104     
105     witem->gencount = 0;
106     witem->flags = 0;
107     witem->item_entry.stqe_next = 0;
108     witem->func = func;
109     witem->func_arg = func_arg;
110
111         return witem;
112 }
113
114 void 
115 witem_free(struct work *wi)
116 {
117     umem_cache_free(witem_cache, wi);
118     return;
119 }
120
121 void
122 witem_cache_cleanup(void *value)
123 {
124     void * p;
125     p = value;
126 }
127
128 /* TSD based cacheing per thread */
129
130 #elif (WITEM_CACHE_TYPE == 3)
131
132 pthread_key_t witem_cache_key;
133
134 int
135 witem_cache_init(void)
136 {
137     pthread_key_create(&witem_cache_key, witem_cache_cleanup);
138     return (0);
139 }
140
141 static struct work *
142 witem_alloc_from_heap(void)
143 {
144         struct work *witem;
145     
146         while (!(witem = fastpath(malloc(ROUND_UP_TO_CACHELINE_SIZE(sizeof(*witem)))))) {
147                 sleep(1);
148         }
149     
150     witem->gencount = 0;
151     witem->flags = 0;
152     witem->item_entry.stqe_next = 0;
153
154         return witem;
155 }
156
157 struct work *
158 witem_alloc(void (*func)(void *), void *func_arg)
159 {
160     struct work *witem = fastpath(pthread_getspecific(witem_cache_key));
161         if (witem) 
162     {
163                 pthread_setspecific(witem_cache_key, witem->wi_next);
164         }
165     else
166     {
167         witem = witem_alloc_from_heap();
168     }
169
170     witem->func = func;
171     witem->func_arg = func_arg;
172     
173         return witem;
174 }
175
176 void 
177 witem_free(struct work *witem)
178 {
179         struct work *prev_wi = pthread_getspecific(witem_cache_key);
180
181         witem->wi_next = prev_wi;
182     
183     // We need to initialize here also...
184     witem->gencount = 0;
185     witem->flags = 0;
186     witem->item_entry.stqe_next = 0;
187     witem->func = NULL;
188     witem->func_arg = NULL;
189
190         pthread_setspecific(witem_cache_key, witem);
191 }
192
193 void
194 witem_cache_cleanup(void *value)
195 {
196         struct work *wi, *next_wi = value;
197     
198         while ((wi = next_wi)) {
199                 next_wi = wi->wi_next;
200                 free(wi);
201         }
202 }
203 #else
204
205 #error Invalid witem cache type specified
206
207 #endif