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
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 #include <string.h>
00062 #include <unistd.h>
00063 #include <signal.h>
00064
00065 #include "gwlib/gwlib.h"
00066
00067 #define NUM_PRODUCERS (4)
00068 #define NUM_CONSUMERS (4)
00069 #define NUM_ITEMS_PER_PRODUCER (1*1000)
00070
00071 struct producer_info {
00072 List *list;
00073 long start_index;
00074 long id;
00075 };
00076
00077
00078 static char received[NUM_PRODUCERS * NUM_ITEMS_PER_PRODUCER];
00079
00080
00081 typedef struct {
00082 long producer;
00083 long num;
00084 long index;
00085 } Item;
00086
00087
00088 static Item *new_item(long producer, long num, long index) {
00089 Item *item;
00090
00091 item = gw_malloc(sizeof(Item));
00092 item->producer = producer;
00093 item->num = num;
00094 item->index = index;
00095 return item;
00096 }
00097
00098
00099 static void producer(void *arg) {
00100 long i, index;
00101 long id;
00102 struct producer_info *info;
00103
00104 info = arg;
00105
00106 id = gwthread_self();
00107 index = info->start_index;
00108 for (i = 0; i < NUM_ITEMS_PER_PRODUCER; ++i, ++index)
00109 gwlist_produce(info->list, new_item(id, i, index));
00110 gwlist_remove_producer(info->list);
00111 }
00112
00113 static void consumer(void *arg) {
00114 List *list;
00115 Item *item;
00116
00117 list = arg;
00118 for (;;) {
00119 item = gwlist_consume(list);
00120 if (item == NULL)
00121 break;
00122 received[item->index] = 1;
00123 gw_free(item);
00124 }
00125 }
00126
00127
00128 static void init_received(void) {
00129 memset(received, 0, sizeof(received));
00130 }
00131
00132
00133 static void main_for_producer_and_consumer(void) {
00134 List *list;
00135 int i;
00136 Item *item;
00137 struct producer_info tab[NUM_PRODUCERS];
00138 long p, n, index;
00139 int errors;
00140
00141 list = gwlist_create();
00142 init_received();
00143
00144 for (i = 0; i < NUM_PRODUCERS; ++i) {
00145 tab[i].list = list;
00146 tab[i].start_index = i * NUM_ITEMS_PER_PRODUCER;
00147 gwlist_add_producer(list);
00148 tab[i].id = gwthread_create(producer, tab + i);
00149 }
00150 for (i = 0; i < NUM_CONSUMERS; ++i)
00151 gwthread_create(consumer, list);
00152
00153 gwthread_join_every(producer);
00154 gwthread_join_every(consumer);
00155
00156 while (gwlist_len(list) > 0) {
00157 item = gwlist_get(list, 0);
00158 gwlist_delete(list, 0, 1);
00159 warning(0, "main: %ld %ld %ld", (long) item->producer,
00160 item->num, item->index);
00161 }
00162
00163 errors = 0;
00164 for (p = 0; p < NUM_PRODUCERS; ++p) {
00165 for (n = 0; n < NUM_ITEMS_PER_PRODUCER; ++n) {
00166 index = p * NUM_ITEMS_PER_PRODUCER + n;
00167 if (!received[index]) {
00168 error(0, "Not received: producer=%ld "
00169 "item=%ld index=%ld",
00170 tab[p].id, n, index);
00171 errors = 1;
00172 }
00173 }
00174 }
00175
00176 if (errors)
00177 panic(0, "Not all messages were received.");
00178 }
00179
00180
00181 static int compare_cstr(void *item, void *pat) {
00182
00183
00184 #undef strcmp
00185 return strcmp(item, pat) == 0;
00186 }
00187
00188
00189 static void main_for_list_add_and_delete(void) {
00190 static char *items[] = {
00191 "one",
00192 "two",
00193 "three",
00194 };
00195 int num_items = sizeof(items) / sizeof(items[0]);
00196 int num_repeats = 3;
00197 int i, j;
00198 char *p;
00199 List *list;
00200
00201 list = gwlist_create();
00202
00203 for (j = 0; j < num_repeats; ++j)
00204 for (i = 0; i < num_items; ++i)
00205 gwlist_append(list, items[i]);
00206 gwlist_delete_matching(list, items[0], compare_cstr);
00207 for (i = 0; i < gwlist_len(list); ++i) {
00208 p = gwlist_get(list, i);
00209 if (strcmp(p, items[0]) == 0)
00210 panic(0, "list contains `%s' after deleting it!",
00211 items[0]);
00212 }
00213
00214 for (i = 0; i < num_items; ++i)
00215 gwlist_delete_equal(list, items[i]);
00216 if (gwlist_len(list) != 0)
00217 panic(0, "list is not empty after deleting everything");
00218
00219 gwlist_destroy(list, NULL);
00220 }
00221
00222
00223 static void main_for_extract(void) {
00224 static char *items[] = {
00225 "one",
00226 "two",
00227 "three",
00228 };
00229 int num_items = sizeof(items) / sizeof(items[0]);
00230 int num_repeats = 3;
00231 int i, j;
00232 char *p;
00233 List *list, *extracted;
00234
00235 list = gwlist_create();
00236
00237 for (j = 0; j < num_repeats; ++j)
00238 for (i = 0; i < num_items; ++i)
00239 gwlist_append(list, items[i]);
00240
00241 for (j = 0; j < num_items; ++j) {
00242 extracted = gwlist_extract_matching(list, items[j],
00243 compare_cstr);
00244 if (extracted == NULL)
00245 panic(0, "no extracted elements, should have!");
00246 for (i = 0; i < gwlist_len(list); ++i) {
00247 p = gwlist_get(list, i);
00248 if (strcmp(p, items[j]) == 0)
00249 panic(0, "list contains `%s' after "
00250 "extracting it!",
00251 items[j]);
00252 }
00253 for (i = 0; i < gwlist_len(extracted); ++i) {
00254 p = gwlist_get(extracted, i);
00255 if (strcmp(p, items[j]) != 0)
00256 panic(0,
00257 "extraction returned wrong element!");
00258 }
00259 gwlist_destroy(extracted, NULL);
00260 }
00261
00262 if (gwlist_len(list) != 0)
00263 panic(0, "list is not empty after extracting everything");
00264
00265 gwlist_destroy(list, NULL);
00266 }
00267
00268
00269 int main(void) {
00270 gwlib_init();
00271 log_set_output_level(GW_INFO);
00272 main_for_list_add_and_delete();
00273 main_for_extract();
00274 main_for_producer_and_consumer();
00275 gwlib_shutdown();
00276 return 0;
00277 }
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.