ia64/xen-unstable

view tools/xcs/bindings.c @ 3966:0b9ff7354a95

bitkeeper revision 1.1236.1.47 (4225ff68LvKUt73k78dKjnXxsnQt7A)

Fix tools build. Clean up barrier defs.
Signed-off-by: Jerone Young <jyoung5@us.ibm.com>
Signed-off-by: Keir Fraser <keir.fraser@cl.cam.ac.uk>
author kaf24@scramble.cl.cam.ac.uk
date Wed Mar 02 18:01:12 2005 +0000 (2005-03-02)
parents 0a4b76b6b5a0
children
line source
1 /* bindings.c
2 *
3 * Manage subscriptions for the control interface switch.
4 *
5 * (c) 2004, Andrew Warfield
6 *
7 */
9 /* Interfaces:
10 *
11 * xcs_bind (port, type, connection)
12 * - Register connection to receive messages of this type.
13 * xcs_unbind (port, type, connection)
14 * - Remove an existing registration. (Must be an exact match)
15 * xcs_lookup (port, type)
16 * - Return a list of connections matching a registration.
17 *
18 * - All connections have a connection.bindings list of current bindings.
19 * - (port, type) pairs may be wildcarded with -1.
20 */
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <string.h>
26 #include "xcs.h"
29 typedef struct binding_ent_st {
30 connection_t *con;
31 struct binding_ent_st *next;
32 } binding_ent_t;
34 #define BINDING_TABLE_SIZE 1024
36 static binding_ent_t *binding_table[BINDING_TABLE_SIZE];
38 #define PORT_WILD(_ent) ((_ent)->port == PORT_WILDCARD)
39 #define TYPE_WILD(_ent) ((_ent)->type == TYPE_WILDCARD)
40 #define FULLY_WILD(_ent) (PORT_WILD(_ent) && TYPE_WILD(_ent))
42 #define BINDING_HASH(_key) \
43 ((((_key)->port * 11) ^ (_key)->type) % BINDING_TABLE_SIZE)
46 void init_bindings(void)
47 {
48 memset(binding_table, 0, sizeof(binding_table));
49 }
51 static int table_add(binding_ent_t *table[],
52 connection_t *con,
53 binding_key_t *key)
54 {
55 binding_ent_t **curs, *ent;
57 curs = &table[BINDING_HASH(key)];
59 while (*curs != NULL) {
60 if ((*curs)->con == con) {
61 DPRINTF("Tried to add an ent that already existed.\n");
62 goto done;
63 }
64 curs = &(*curs)->next;
65 }
67 if (connection_add_binding(con, key) != 0)
68 {
69 DPRINTF("couldn't add binding on connection (%lu)\n", con->id);
70 goto fail;
71 }
72 ent = (binding_ent_t *)malloc(sizeof(binding_ent_t));
73 if (ent == 0) {
74 DPRINTF("couldn't alloc binding ent!\n");
75 goto fail;
76 }
77 ent->con = con;
78 ent->next = NULL;
79 *curs = ent;
81 done:
82 return 0;
84 fail:
85 return -1;
86 }
89 static inline int binding_has_colliding_hashes(connection_t *con,
90 binding_key_t *key)
91 {
92 int hash, count = 0;
93 binding_key_ent_t *ent;
95 ent = con->bindings;
96 hash = BINDING_HASH(key);
98 while (ent != NULL) {
99 if (BINDING_HASH(&ent->key) == hash) count ++;
100 ent = ent->next;
101 }
103 return (count > 1);
104 }
105 static int table_remove(binding_ent_t *table[],
106 connection_t *con,
107 binding_key_t *key)
108 {
109 binding_ent_t **curs, *ent;
111 if (!binding_has_colliding_hashes(con, key))
112 {
114 curs = &table[BINDING_HASH(key)];
116 while ((*curs != NULL) && ((*curs)->con != con))
117 curs = &(*curs)->next;
119 if (*curs != NULL) {
120 ent = *curs;
121 *curs = (*curs)->next;
122 free(ent);
123 }
124 }
126 connection_remove_binding(con, key);
128 return 0;
129 }
131 int xcs_bind(connection_t *con, int port, u16 type)
132 {
133 binding_key_t key;
135 key.port = port;
136 key.type = type;
138 return table_add(binding_table, con, &key);
139 }
141 int xcs_unbind(connection_t *con, int port, u16 type)
142 {
143 binding_key_t key;
145 key.port = port;
146 key.type = type;
148 return table_remove(binding_table, con, &key);
149 }
152 static void for_each_binding(binding_ent_t *list, binding_key_t *key,
153 void (*f)(connection_t *, void *), void *arg)
154 {
155 while (list != NULL)
156 {
157 if (connection_has_binding(list->con, key))
158 f(list->con, arg);
159 list = list->next;
160 }
161 }
163 void xcs_lookup(int port, u16 type, void (*f)(connection_t *, void *),
164 void *arg)
165 {
166 binding_key_t key;
168 key.port = port; key.type = type;
169 for_each_binding(binding_table[BINDING_HASH(&key)], &key, f, arg);
171 key.port = port; key.type = TYPE_WILDCARD;
172 for_each_binding(binding_table[BINDING_HASH(&key)], &key, f, arg);
174 key.port = PORT_WILDCARD; key.type = type;
175 for_each_binding(binding_table[BINDING_HASH(&key)], &key, f, arg);
177 key.port = PORT_WILDCARD; key.type = TYPE_WILDCARD;
178 for_each_binding(binding_table[BINDING_HASH(&key)], &key, f, arg);
179 }