Tizen 2.1 base
[platform/upstream/gcd.git] / pthread_workqueue-0.8.2 / src / api.c
1 /*-
2  * Copyright (c) 2010, Mark Heily <mark@heily.com>
3  * Copyright (c) 2009, Stacey Son <sson@freebsd.org>
4  * Copyright (c) 2000-2008, Apple Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice unmodified, this list of conditions, and the following
12  *    disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29
30 #include "private.h"
31
32 unsigned int PWQ_ACTIVE_CPU = 0;
33 int DEBUG_WORKQUEUE = 0;
34 char *WORKQUEUE_DEBUG_IDENT = "WQ";
35
36 static int
37 valid_workq(pthread_workqueue_t workq) 
38 {
39     if (workq->sig == PTHREAD_WORKQUEUE_SIG)
40         return (1);
41     else
42         return (0);
43 }
44
45 int VISIBLE CONSTRUCTOR
46 pthread_workqueue_init_np(void)
47 {
48 #ifdef NDEBUG
49     DEBUG_WORKQUEUE = 0;
50 #else
51     DEBUG_WORKQUEUE = (getenv("PWQ_DEBUG") == NULL) ? 0 : 1;
52 # ifndef _WIN32
53     PWQ_RT_THREADS = (getenv("PWQ_RT_THREADS") == NULL) ? 0 : 1;
54     PWQ_ACTIVE_CPU = (getenv("PWQ_ACTIVE_CPU") == NULL) ? 0 : atoi(getenv("PWQ_ACTIVE_CPU"));
55
56     if (getenv("PWQ_SPIN_USEC") != NULL)
57         PWQ_SPIN_USEC = atoi(getenv("PWQ_SPIN_USEC"));
58     
59     if (getenv("PWQ_SPIN_THREADS") != NULL)
60         PWQ_SPIN_THREADS =  atoi(getenv("PWQ_SPIN_THREADS"));
61
62 # endif
63 #endif
64
65     if (manager_init() < 0)
66         return (-1);
67
68     dbg_puts("pthread_workqueue library initialized");
69     return (0);
70 }
71
72 int VISIBLE
73 pthread_workqueue_create_np(pthread_workqueue_t *workqp,
74                             const pthread_workqueue_attr_t * attr)
75 {
76     pthread_workqueue_t workq;
77
78     if ((attr != NULL) && ((attr->sig != PTHREAD_WORKQUEUE_ATTR_SIG) ||
79          (attr->queueprio < 0) || (attr->queueprio >= WORKQ_NUM_PRIOQUEUE)))
80         return (EINVAL);
81     if ((workq = calloc(1, sizeof(*workq))) == NULL)
82         return (ENOMEM);
83     workq->sig = PTHREAD_WORKQUEUE_SIG;
84     workq->flags = 0;
85     STAILQ_INIT(&workq->item_listhead);
86     pthread_spin_init(&workq->mtx, PTHREAD_PROCESS_PRIVATE);
87     if (attr == NULL) {
88         workq->queueprio = WORKQ_DEFAULT_PRIOQUEUE;
89         workq->overcommit = 0;
90     } else {
91         workq->queueprio = attr->queueprio;
92         workq->overcommit = attr->overcommit;
93     }
94
95     manager_workqueue_create(workq);
96
97     dbg_printf("created queue %p", (void *) workq);
98
99     *workqp = workq;
100     return (0);
101 }
102
103 int VISIBLE
104 pthread_workqueue_additem_np(pthread_workqueue_t workq,
105                      void (*workitem_func)(void *), void * workitem_arg,
106                      pthread_workitem_handle_t * itemhandlep, 
107                      unsigned int *gencountp)
108 {
109     struct work *witem;
110     
111     if (valid_workq(workq) == 0)
112         return (EINVAL);
113
114     witem = witem_alloc(workitem_func, workitem_arg);
115
116     if (itemhandlep != NULL)
117         *itemhandlep = (pthread_workitem_handle_t *) witem;
118     if (gencountp != NULL)
119         *gencountp = witem->gencount;
120
121     manager_workqueue_additem(workq, witem);
122
123     dbg_printf("added item %p to queue %p", (void *) witem, (void *) workq);
124
125     return (0);
126 }
127
128 int VISIBLE
129 pthread_workqueue_attr_init_np(pthread_workqueue_attr_t *attr)
130 {
131     attr->queueprio = WORKQ_DEFAULT_PRIOQUEUE;
132     attr->sig = PTHREAD_WORKQUEUE_ATTR_SIG;
133     attr->overcommit = 0;
134     return (0);
135 }
136
137 int VISIBLE
138 pthread_workqueue_attr_destroy_np(pthread_workqueue_attr_t *attr)
139 {
140     if (attr->sig == PTHREAD_WORKQUEUE_ATTR_SIG)
141         return (0);
142     else
143         return (EINVAL); /* Not an attribute struct. */
144 }
145
146 int VISIBLE
147 pthread_workqueue_attr_getovercommit_np(
148         const pthread_workqueue_attr_t *attr, int *ocommp)
149 {
150     if (attr->sig == PTHREAD_WORKQUEUE_ATTR_SIG) {
151         *ocommp = attr->overcommit;
152         return (0);
153     } else 
154         return (EINVAL); /* Not an attribute struct. */
155 }
156
157 int VISIBLE
158 pthread_workqueue_attr_setovercommit_np(pthread_workqueue_attr_t *attr,
159                            int ocomm)
160 {
161     if (attr->sig == PTHREAD_WORKQUEUE_ATTR_SIG) {
162         attr->overcommit = ocomm;
163         return (0);
164     } else
165         return (EINVAL);
166 }
167
168 int VISIBLE
169 pthread_workqueue_attr_getqueuepriority_np(
170         pthread_workqueue_attr_t *attr, int *qpriop)
171 {
172     if (attr->sig == PTHREAD_WORKQUEUE_ATTR_SIG) {
173         *qpriop = attr->queueprio;
174         return (0);
175     } else 
176         return (EINVAL);
177 }
178
179 int VISIBLE
180 pthread_workqueue_attr_setqueuepriority_np(
181         pthread_workqueue_attr_t *attr, int qprio)
182 {
183     if (attr->sig == PTHREAD_WORKQUEUE_ATTR_SIG) {
184         switch(qprio) {
185             case WORKQ_HIGH_PRIOQUEUE:
186             case WORKQ_DEFAULT_PRIOQUEUE:
187             case WORKQ_LOW_PRIOQUEUE:
188                 attr->queueprio = qprio;
189                 return (0);
190             default:
191                 return (EINVAL);
192         }
193     } else
194         return (EINVAL);
195 }
196
197 unsigned long VISIBLE
198 pthread_workqueue_peek_np(const char *key)
199 {
200     return manager_peek(key);
201 }