Back to index

glibc  2.9
ex18.c
Go to the documentation of this file.
00001 /*
00002  * Beat up the pthread_key_create and pthread_key_delete
00003  * functions.
00004  */
00005 
00006 #if 0
00007 #define CHATTY
00008 #endif
00009 
00010 #include <stdio.h>
00011 #include <errno.h>
00012 #include <stdlib.h>
00013 #include <pthread.h>
00014 #include <unistd.h>
00015 
00016 const int beatup_iterations = 10000;
00017 const int num_threads = 30;
00018 const int max_keys = 500;
00019 
00020 struct key_list {
00021   struct key_list *next;
00022   pthread_key_t key; 
00023 };
00024 
00025 struct key_list *key_list;
00026 pthread_mutex_t key_lock = PTHREAD_MUTEX_INITIALIZER;
00027 
00028 /*
00029  * Create a new key and put it at the tail of a linked list.
00030  * If the linked list grows to a certain length, delete a key from the
00031  * head of * the list. 
00032  */
00033 
00034 static void 
00035 beat_up(void)
00036 {
00037   struct key_list *new = malloc(sizeof *new);
00038   struct key_list **iter, *old_key = 0;
00039   int key_count = 0;
00040 
00041   if (new == 0) {
00042     fprintf(stderr, "malloc failed\n");
00043     abort();
00044   }
00045 
00046   new->next = 0;
00047 
00048   if (pthread_key_create(&new->key, 0) != 0) {
00049     fprintf(stderr, "pthread_key_create failed\n");
00050     abort();
00051   }
00052 
00053   if (pthread_getspecific(new->key) != 0) {
00054     fprintf(stderr, "new pthread_key_t resolves to non-null value\n");
00055     abort();
00056   }
00057 
00058   pthread_setspecific(new->key, (void *) 1);
00059 
00060 #ifdef CHATTY
00061   printf("created key\n");
00062 #endif
00063 
00064   pthread_mutex_lock(&key_lock);
00065 
00066   for (iter = &key_list; *iter != 0; iter = &(*iter)->next)
00067     key_count++;
00068 
00069   *iter = new;
00070 
00071   if (key_count > max_keys) {
00072     old_key = key_list;
00073     key_list = key_list->next;
00074   }
00075 
00076   pthread_mutex_unlock(&key_lock);
00077 
00078   if (old_key != 0) {
00079 #ifdef CHATTY
00080     printf("deleting key\n");
00081 #endif
00082     pthread_key_delete(old_key->key);
00083   }
00084 }
00085 
00086 static void *
00087 thread(void *arg)
00088 {
00089   int i;
00090   for (i = 0; i < beatup_iterations; i++) 
00091     beat_up();
00092   return 0;
00093 }
00094 
00095 int
00096 main(void)
00097 {
00098   int i;
00099   pthread_attr_t detached_thread;
00100 
00101   pthread_attr_init(&detached_thread);
00102   pthread_attr_setdetachstate(&detached_thread, PTHREAD_CREATE_DETACHED);
00103 
00104   for (i = 0; i < num_threads; i++) {
00105     pthread_t thread_id;
00106     while (pthread_create(&thread_id, &detached_thread, thread, 0) == EAGAIN) {
00107       /* let some threads die, so system can breathe. :) */
00108       sleep(1);
00109     }
00110   }
00111 
00112   pthread_exit(0);
00113 }