OpenDNSSEC-signer  1.3.16
fifoq.c
Go to the documentation of this file.
1 /*
2  * $Id$
3  *
4  * Copyright (c) 2011 NLNet Labs. 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, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
34 #include "config.h"
35 #include "daemon/worker.h"
36 #include "scheduler/fifoq.h"
37 #include "shared/allocator.h"
38 #include "shared/log.h"
39 
40 #include <ldns/ldns.h>
41 
42 static const char* fifoq_str = "fifo";
43 
44 
51 {
52  fifoq_type* fifoq;
53  if (!allocator) {
54  ods_log_error("[%s] unable to create: no allocator available",
55  fifoq_str);
56  return NULL;
57  }
58  ods_log_assert(allocator);
59 
60  fifoq = (fifoq_type*) allocator_alloc(allocator, sizeof(fifoq_type));
61  if (!fifoq) {
62  ods_log_error("[%s] unable to create: allocator failed", fifoq_str);
63  return NULL;
64  }
65  ods_log_assert(fifoq);
66 
67  fifoq->allocator = allocator;
68  fifoq_wipe(fifoq);
69  fifoq->q_locked = 0;
70  lock_basic_init(&fifoq->q_lock);
71  lock_basic_set(&fifoq->q_threshold);
72  lock_basic_set(&fifoq->q_nonfull);
73  return fifoq;
74 }
75 
76 
81 void
83 {
84  size_t i = 0;
85 
86  for (i=0; i < FIFOQ_MAX_COUNT; i++) {
87  q->blob[i] = NULL;
88  q->owner[i] = NULL;
89  }
90  q->count = 0;
91  return;
92 }
93 
94 
99 void*
101 {
102  void* pop = NULL;
103  size_t i = 0;
104 
105  if (!q) {
106  return NULL;
107  }
108  if (q->count <= 0) {
109  return NULL;
110  }
111 
112  pop = q->blob[0];
113  *worker = q->owner[0];
114  for (i = 0; i < q->count-1; i++) {
115  q->blob[i] = q->blob[i+1];
116  q->owner[i] = q->owner[i+1];
117  }
118  q->count -= 1;
119 
120  if (q->count <= (size_t) FIFOQ_MAX_COUNT * 0.1) {
121  /* notify waiting workers that they can start queuing again */
123  }
124  return pop;
125 }
126 
127 
133 fifoq_push(fifoq_type* q, void* item, worker_type* worker, int* tries)
134 {
135  ods_log_assert(q);
136  ods_log_assert(item);
137  ods_log_assert(worker);
138 
139  if (q->count >= FIFOQ_MAX_COUNT) {
140  /* #262 if drudgers remain on hold, do additional broadcast */
141  if (*tries > FIFOQ_TRIES_COUNT) {
143  ods_log_debug("[%s] queue full, notify drudgers again", fifoq_str);
144  /* reset tries */
145  *tries = 0;
146  }
147  return ODS_STATUS_UNCHANGED;
148  }
149 
150  q->blob[q->count] = item;
151  q->owner[q->count] = worker;
152  q->count += 1;
153  if (q->count == 1) {
155  ods_log_deeebug("[%s] threshold %u reached, notify drudgers",
156  fifoq_str, q->count);
157  }
158  return ODS_STATUS_OK;
159 }
160 
161 
166 void
168 {
170  lock_basic_type q_lock;
171  cond_basic_type q_threshold;
172  cond_basic_type q_nonfull;
173 
174  if (!q) {
175  return;
176  }
177  ods_log_assert(q);
178  allocator = q->allocator;
179  q_lock = q->q_lock;
180  q_threshold = q->q_threshold;
181  q_nonfull = q->q_nonfull;
182 
183  allocator_deallocate(allocator, (void*) q);
184  lock_basic_off(&q_threshold);
185  lock_basic_off(&q_nonfull);
186  lock_basic_destroy(&q_lock);
187  return;
188 }
#define lock_basic_off(cond)
Definition: locks.h:161
void ods_log_debug(const char *format,...)
Definition: log.c:285
#define lock_basic_destroy(lock)
Definition: locks.h:153
cond_basic_type q_threshold
Definition: fifoq.h:68
void * allocator_alloc(allocator_type *allocator, size_t size)
Definition: allocator.c:67
lock_basic_type q_lock
Definition: fifoq.h:67
#define FIFOQ_MAX_COUNT
Definition: fifoq.h:55
enum ods_enum_status ods_status
Definition: status.h:64
void ods_log_error(const char *format,...)
Definition: log.c:349
int q_locked
Definition: fifoq.h:70
#define lock_basic_set(cond)
Definition: locks.h:157
ods_status fifoq_push(fifoq_type *q, void *item, worker_type *worker, int *tries)
Definition: fifoq.c:133
#define FIFOQ_TRIES_COUNT
Definition: fifoq.h:56
void fifoq_cleanup(fifoq_type *q)
Definition: fifoq.c:167
int lock_basic_type
Definition: locks.h:151
fifoq_type * fifoq_create(allocator_type *allocator)
Definition: fifoq.c:50
size_t count
Definition: fifoq.h:66
allocator_type * allocator
Definition: zonelist.h:51
void fifoq_wipe(fifoq_type *q)
Definition: fifoq.c:82
void * blob[FIFOQ_MAX_COUNT]
Definition: fifoq.h:64
worker_type * owner[FIFOQ_MAX_COUNT]
Definition: fifoq.h:65
#define lock_basic_init(lock)
Definition: locks.h:152
allocator_type * allocator
Definition: fifoq.h:63
void ods_log_deeebug(const char *format,...)
Definition: log.c:269
void allocator_deallocate(allocator_type *allocator, void *data)
Definition: allocator.c:136
cond_basic_type q_nonfull
Definition: fifoq.h:69
#define ods_log_assert(x)
Definition: log.h:141
#define lock_basic_broadcast(cond)
Definition: locks.h:160
void * fifoq_pop(fifoq_type *q, worker_type **worker)
Definition: fifoq.c:100