Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00034 #include "config.h"
00035 #include "daemon/worker.h"
00036 #include "scheduler/fifoq.h"
00037 #include "shared/allocator.h"
00038 #include "shared/log.h"
00039
00040 #include <ldns/ldns.h>
00041
00042 static const char* fifoq_str = "fifo";
00043
00044
00049 fifoq_type*
00050 fifoq_create(allocator_type* allocator)
00051 {
00052 fifoq_type* fifoq;
00053 if (!allocator) {
00054 ods_log_error("[%s] unable to create: no allocator available",
00055 fifoq_str);
00056 return NULL;
00057 }
00058 ods_log_assert(allocator);
00059
00060 fifoq = (fifoq_type*) allocator_alloc(allocator, sizeof(fifoq_type));
00061 if (!fifoq) {
00062 ods_log_error("[%s] unable to create: allocator failed", fifoq_str);
00063 return NULL;
00064 }
00065 ods_log_assert(fifoq);
00066
00067 fifoq->allocator = allocator;
00068 fifoq_wipe(fifoq);
00069 lock_basic_init(&fifoq->q_lock);
00070 lock_basic_set(&fifoq->q_threshold);
00071 return fifoq;
00072 }
00073
00074
00079 void
00080 fifoq_wipe(fifoq_type* q)
00081 {
00082 size_t i = 0;
00083
00084 for (i=0; i < FIFOQ_MAX_COUNT; i++) {
00085 q->blob[i] = NULL;
00086 q->owner[i] = NULL;
00087 }
00088 q->count = 0;
00089 return;
00090 }
00091
00092
00097 void*
00098 fifoq_pop(fifoq_type* q, worker_type** worker)
00099 {
00100 void* pop = NULL;
00101 size_t i = 0;
00102
00103 if (!q) {
00104 return NULL;
00105 }
00106 if (q->count <= 0) {
00107 return NULL;
00108 }
00109
00110 pop = q->blob[0];
00111 *worker = q->owner[0];
00112 for (i = 0; i < q->count-1; i++) {
00113 q->blob[i] = q->blob[i+1];
00114 q->owner[i] = q->owner[i+1];
00115 }
00116 q->count -= 1;
00117 ods_log_deeebug("[%s] popped item, count=%u", fifoq_str, q->count);
00118 return pop;
00119 }
00120
00121
00126 ods_status
00127 fifoq_push(fifoq_type* q, void* item, worker_type* worker)
00128 {
00129 size_t count = 0;
00130
00131 if (!item) {
00132 ods_log_error("[%s] unable to push item: no item", fifoq_str);
00133 return ODS_STATUS_ASSERT_ERR;
00134 }
00135 ods_log_assert(item);
00136 if (!q) {
00137 ods_log_error("[%s] unable to push item: no queue", fifoq_str);
00138 return ODS_STATUS_ASSERT_ERR;
00139 }
00140 ods_log_assert(q);
00141
00142 if (q->count >= FIFOQ_MAX_COUNT) {
00143 ods_log_deeebug("[%s] unable to push item: max cap reached",
00144 fifoq_str);
00145 return ODS_STATUS_UNCHANGED;
00146 }
00147 count = q->count;
00148
00149 q->blob[q->count] = item;
00150 q->owner[q->count] = worker;
00151 q->count += 1;
00152
00153 if (count == 0 && q->count == 1) {
00154 lock_basic_broadcast(&q->q_threshold);
00155 ods_log_deeebug("[%s] threshold %u reached, notify drudgers",
00156 fifoq_str, q->count);
00157 }
00158 return ODS_STATUS_OK;
00159 }
00160
00161
00166 void
00167 fifoq_cleanup(fifoq_type* q)
00168 {
00169 allocator_type* allocator;
00170 lock_basic_type q_lock;
00171 cond_basic_type q_cond;
00172
00173 if (!q) {
00174 return;
00175 }
00176 ods_log_assert(q);
00177 allocator = q->allocator;
00178 q_lock = q->q_lock;
00179 q_cond = q->q_threshold;
00180
00181 allocator_deallocate(allocator, (void*) q);
00182 lock_basic_off(&q_cond);
00183 lock_basic_destroy(&q_lock);
00184 return;
00185 }