Annotation of embedaddon/ntp/ntpd/ntp_data_structures.c, revision 1.1.1.1
1.1 misho 1: /* ntp_data_structures.c
2: *
3: * This file contains the data structures used by the ntp configuration
4: * code and the discrete event simulator.
5: *
6: * Written By: Sachin Kamboj
7: * University of Delaware
8: * Newark, DE 19711
9: * Copyright (c) 2006
10: */
11:
12:
13: #include <stdlib.h> /* Needed for malloc */
14: #include "ntp_data_structures.h"
15: #include "ntp_stdlib.h"
16:
17: /* Priority Queue
18: * --------------
19: * Define a priority queue in which the relative priority of the elements
20: * is determined by a function 'get_order' which is supplied to the
21: * priority_queue
22: */
23:
24:
25: queue *create_priority_queue(int (*get_order)(void *, void *))
26: {
27: queue *my_queue = (queue *) emalloc(sizeof(queue));
28: my_queue->get_order = get_order;
29: my_queue->front = NULL;
30: my_queue->no_of_elements = 0;
31: return my_queue;
32: }
33:
34:
35: /* Define a function to "destroy" a priority queue, freeing-up
36: * all the allocated resources in the process
37: */
38:
39: void destroy_queue(queue *my_queue)
40: {
41: node *temp = NULL;
42:
43: /* Empty out the queue elements if they are not already empty */
44: while (my_queue->front != NULL) {
45: temp = my_queue->front;
46: my_queue->front = my_queue->front->node_next;
47: free(temp);
48: }
49:
50: /* Now free the queue */
51: free(my_queue);
52: }
53:
54:
55: /* Define a function to allocate memory for one element
56: * of the queue. The allocated memory consists of size
57: * bytes plus the number of bytes needed for bookkeeping
58: */
59:
60: void *get_node(size_t size)
61: {
62: node *new_node = emalloc(sizeof(*new_node) + size);
63: new_node->node_next = NULL;
64: return new_node + 1;
65: }
66:
67: /* Define a function to free the allocated memory for a queue node */
68: void free_node(void *my_node)
69: {
70: node *old_node = my_node;
71: free(old_node - 1);
72: }
73:
74:
75: void *
76: next_node(
77: void *pv
78: )
79: {
80: node *pn;
81:
82: pn = pv;
83: pn--;
84:
85: if (pn->node_next == NULL)
86: return NULL;
87:
88: return pn->node_next + 1;
89: }
90:
91:
92: /* Define a function to check if the queue is empty. */
93: int empty(queue *my_queue)
94: {
95: return (!my_queue || !my_queue->front);
96: }
97:
98:
99: void *
100: queue_head(
101: queue *q
102: )
103: {
104: if (NULL == q || NULL == q->front)
105: return NULL;
106:
107: return q->front + 1;
108: }
109:
110:
111: /* Define a function to add an element to the priority queue.
112: * The element is added according to its priority -
113: * relative priority is given by the get_order function
114: */
115: queue *enqueue(queue *my_queue, void *my_node)
116: {
117: node *new_node = ((node *) my_node) - 1;
118: node *i = NULL;
119: node *j = my_queue->front;
120:
121: while (j != NULL && ((*my_queue->get_order)(new_node + 1, j + 1) > 0)) {
122: i = j;
123: j = j->node_next;
124: }
125:
126: if (i == NULL) { /* Insert at beginning of the queue */
127: new_node->node_next = my_queue->front;
128: my_queue->front = new_node;
129: }
130: else { /* Insert Elsewhere, including the end */
131: new_node->node_next = i->node_next;
132: i->node_next = new_node;
133: }
134:
135: ++my_queue->no_of_elements;
136: return my_queue;
137: }
138:
139:
140: /* Define a function to dequeue the first element from the priority
141: * queue and return it
142: */
143:
144: void *dequeue(queue *my_queue)
145: {
146: node *my_node = my_queue->front;
147: if (my_node != NULL) {
148: my_queue->front = my_node->node_next;
149: --my_queue->no_of_elements;
150: return (void *)(my_node + 1);
151: }
152: else
153: return NULL;
154: }
155:
156: /* Define a function that returns the number of elements in the
157: * priority queue
158: */
159: int get_no_of_elements(queue *my_queue)
160: {
161: return my_queue->no_of_elements;
162: }
163:
164: /* Define a function to append a queue onto another.
165: * Note: there is a faster way (O(1) as opposed to O(n))
166: * to do this for simple (FIFO) queues, but we can't rely on
167: * that for priority queues. (Given the current representation)
168: *
169: * I don't anticipate this to be a problem. If it does turn
170: * out to be a bottleneck, I will consider replacing the
171: * current implementation with a binomial or fibonacci heap.
172: */
173:
174: void append_queue(queue *q1, queue *q2)
175: {
176: while (!empty(q2))
177: enqueue(q1, dequeue(q2));
178: destroy_queue(q2);
179: }
180:
181: /* FIFO Queue
182: * ----------
183: * Use the priority queue to create a traditional FIFO queue.
184: * The only extra function needed is the create_queue
185: */
186:
187: /* C is not Lisp and does not allow anonymous lambda functions :-(.
188: * So define a get_fifo_order function here
189: */
190:
191: int get_fifo_order(void *el1, void *el2)
192: { return 1;
193: }
194:
195: /* Define a function to create a FIFO queue */
196:
197: queue *create_queue()
198: { return create_priority_queue(get_fifo_order);
199: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>