#include #include #include #include #include #include #include #define COUNT 10 #define INSERTS 5000 int silent = 0; cp_hashtable *t[COUNT]; cp_list *tl[COUNT]; pthread_cond_t cond[COUNT]; pthread_mutex_t lock[COUNT]; int running = 0; pthread_mutex_t start_mutex; pthread_cond_t start_cond; void *writer(void *prm) { int i, num; long count = (long) prm; char kbuf[30]; char *entry; pthread_mutex_lock(&start_mutex); while (!running) pthread_cond_wait(&start_cond, &start_mutex); pthread_mutex_unlock(&start_mutex); for (i = 0; i < count; i++) { sprintf(kbuf, "ENTRY %d", i); entry = strdup(kbuf); num = i % COUNT; if (!silent) printf("writing (%d): %s\n", num, entry); cp_hashtable_put(t[num], entry, entry); cp_list_append(tl[num], entry); pthread_mutex_lock(&lock[i % COUNT]); pthread_cond_broadcast(&cond[i % COUNT]); pthread_mutex_unlock(&lock[i % COUNT]); } return NULL; } void *reader(void *prm) { char *entry; int num = (int) prm; int total = 0; pthread_mutex_lock(&start_mutex); while (!running) pthread_cond_wait(&start_cond, &start_mutex); pthread_mutex_unlock(&start_mutex); while (running || cp_hashtable_count(t[num]) > 0) { pthread_mutex_lock(&lock[num]); while (running && cp_list_is_empty(tl[num])) pthread_cond_wait(&cond[num], &lock[num]); entry = (char *) cp_list_remove_head(tl[num]); pthread_mutex_unlock(&lock[num]); if (entry) { cp_hashtable_remove(t[num], entry); if (!silent) printf("[%d]: (%ld) entry: %s\n", num, cp_hashtable_count(t[num]), entry); total++; free(entry); } } printf("\n (-) reader %d: processed %d entries\n", num, total); return NULL; } int main(int argc, char *argv[]) { int i; pthread_t w[COUNT]; pthread_t r[COUNT]; long total; if (argc > 1) silent = atoi(argv[1]); for (i = 0; i < COUNT; i++) { pthread_mutex_init(&lock[i], NULL); pthread_cond_init(&cond[i], NULL); t[i] = cp_hashtable_create(10, cp_hash_string, cp_hash_compare_string); tl[i] = cp_list_create(); } pthread_mutex_init(&start_mutex, NULL); pthread_cond_init(&start_cond, NULL); for (i = 0; i < COUNT; i++) pthread_create(&r[i], NULL, reader, (void *) i); for (i = 0; i < COUNT; i++) pthread_create(&w[i], NULL, writer, (void *) INSERTS); printf("press enter\n"); getchar(); pthread_mutex_lock(&start_mutex); running = 1; total = time(NULL); pthread_cond_broadcast(&start_cond); pthread_mutex_unlock(&start_mutex); for (i = 0; i < COUNT; i++) pthread_join(w[i], NULL); running = 0; for (i = 0; i < COUNT; i++) { pthread_mutex_lock(&lock[i]); if (cp_hashtable_count(t[i])) { pthread_cond_signal(&cond[i]); pthread_mutex_unlock(&lock[i]); pthread_join(r[i], NULL); } else { pthread_cond_signal(&cond[i]); pthread_mutex_unlock(&lock[i]); pthread_join(r[i], NULL); } } total = time(NULL) - total; printf("\ndone in %ld seconds. tables should be empty now. press enter.\n", total); getchar(); for (i = 0; i < COUNT; i++) { printf("table %d: %ld items\n", i, cp_hashtable_count(t[i])); cp_hashtable_destroy(t[i]); printf("list %d: %ld items\n", i, cp_list_item_count(tl[i])); while (cp_list_item_count(tl[i])) { char *leftover = cp_list_remove_head(tl[i]); printf(" * %s\n", leftover); } cp_list_destroy(tl[i]); } printf("deleted them tables. press enter.\n"); getchar(); printf("bye.\n"); return 0; }