/* * sem_list1.c - Shows what can happen as a result of * uncontrolled access to a singly linked list */ #include #include #include #include #include #include typedef struct node { int val; struct node *next; } node; typedef struct list { node *head; } list; // shared global static list mylist; // start flag volatile int start = 0; // The thread process void *thread_routine() { printf("Worker thread: %lu ready\n", pthread_self()); // wait for start from master thread while (start == 0) ; for (int j = 0; j < 1000000; j++) { node *new_node = malloc(sizeof(node)); new_node->val = j; new_node->next = mylist.head; mylist.head = new_node; } printf("Worker thread: %lu done\n", pthread_self()); return NULL; } // Main process int main() { #define THREAD_COUNT 10 pthread_t thr_ids[THREAD_COUNT]; mylist.head = NULL; // Create the threads for (int i = 0; i < THREAD_COUNT; i++) { if (pthread_create(&thr_ids[i], NULL, thread_routine, NULL) == -1) { printf("COULD NOT CREATE A THREAD\n"); exit(EXIT_FAILURE); } } // Signal threads to start start = 1; // Wait for all threads to finish for (int i = 0; i < THREAD_COUNT; i++) { pthread_join(thr_ids[i], NULL); } // Count the elements in the list int length = 0; node *itr = mylist.head; while (itr != NULL) { length++; itr = itr->next; } printf("List contains %d elements\n", length); // Free the list while (mylist.head != NULL) { node *to_delete = mylist.head; mylist.head = mylist.head->next; free(to_delete); } return EXIT_SUCCESS; }