// Due to undefined behavior with multiple processes and shm, I'm using four independent shm's at the same time void synchro_logic(const char* my_shm_name, const char* other_shm_name, int number_offset, int times) { sem_t * my_semdes = SEM_FAILED; sem_t * other_semdes = SEM_FAILED; FILE* pts = fopen(PTS_NAME, "w"); my_sem_create((char*)my_shm_name, &my_semdes); while(my_sem_open((char*)other_shm_name, &other_semdes) != 0) { usleep(500000); } my_sem_wait(&my_semdes); if (number_offset > 1) { my_sem_wait(&my_semdes); } for(int count = 0; count < times; count++) { fprintf(pts, "Program %i: Number %i\n", number_offset, (4 * count) + number_offset); my_sem_post(&other_semdes); if(count < times - 1) { my_sem_wait(&my_semdes); } } my_sem_post(&my_semdes); my_sem_close(&my_semdes); my_sem_close(&other_semdes); sem_unlink((char*)my_shm_name); fclose(pts); printf("Program %i: Exit\n", number_offset); }
void* grab_the_lock ( void* uu ) { int r= pthread_mutex_lock( &mx[2] ); assert(!r); my_sem_wait( quit_now ); r= pthread_mutex_unlock( &mx[2] ); assert(!r); return NULL; }
int main (int argc, char *argv[]) { int write_character = -1; g_prog_mode = PRG_SENDER_MODE; /*check parameters */ if ((buffer_size = get_buffer_size(argc, argv)) == RETURN_ERROR) { return EXIT_FAILURE; } /*create semaphore and ringbuffer*/ if (create_environment() == RETURN_ERROR) { return EXIT_FAILURE; } /*write ringbuffer*/ do { /*read stdin input*/ write_character = fgetc(stdin); /*decrement semaphore*/ if (my_sem_wait() == RETURN_ERROR) { return EXIT_FAILURE; } /*write ringbuffer*/ write_char_to_buffer(write_character); /*increment semaphore*/ if (my_sem_post() == RETURN_ERROR) { return EXIT_FAILURE; } } while (write_character != EOF); /*check for errors in input of stdin*/ if (ferror(stdin)) { fprintf(stderr, "%s: %s%s\n", g_program_name, "Error while reading input from \"stdin\".", strerror(errno)); destroy_environment(PRG_ERROR); return EXIT_FAILURE; } /*destroy semaphore and ringbuffer*/ if (destroy_environment(PRG_SUCCESS) == RETURN_ERROR) { return EXIT_FAILURE; } else { return EXIT_SUCCESS; } }
void *down(void *ptr) { int i; for (i = 0; i < TOTAL_RUNS; i++) { my_sem_wait(); x--; my_sem_post(); } printf("Finished subtracting 1 a total of %d times.\n", TOTAL_RUNS); }
void *up(void *ptr) { int i; for (i = 0; i < TOTAL_RUNS; i++) { my_sem_wait(); x++; my_sem_post(); } printf("Finished adding 1 a total of %d times.\n", TOTAL_RUNS); }
// used to execute hydrogen atom pthread void *hydrogen(void *arg) { // get thread id thread_data_t *data = (thread_data_t *)arg; int tid = data->tid; // print that atom spawned print_spawn_atom(false); fflush(stdout); printf("hydrogen (H) atom %d is created\n", tid); fflush(stdout); // wait for mutex my_sem_wait(sem[S]); // print that atom is at thread barrier print_thread_barrier(false, waiting_c, waiting_h); // are there enough h and c atoms to make CH4? if (waiting_h >= 3 && waiting_c >= 1) { int i; for(i = 0; i < 3; i++) my_sem_sig(sem[SH]); waiting_h -= 3; my_sem_sig(sem[SC]); waiting_c -= 1; my_sem_sig(sem[S]); print_full_set(); } else { // if not enough c or h atoms, hydrogen has to wait waiting_h += 1; my_sem_sig(sem[S]); my_sem_wait(sem[SH]); } // exit successfully pthread_exit(NULL); }
// used to execute carbon atom pthread void *carbon(void *arg) { // get thread id thread_data_t *data = (thread_data_t *)arg; int tid = data->tid; // print that the atom spawned print_spawn_atom(true); fflush(stdout); printf("carbon (C) atom %d is created\n", tid); fflush(stdout); // wait for mutex my_sem_wait(sem[S]); // print that the thread has reached the barrier and the // curr waiting c and h atom counts print_thread_barrier(true, waiting_c, waiting_h); // are there enough h atoms waiting to make CH4? if (waiting_h >= 4) { int i; for(i = 0; i < 4; i++) my_sem_sig(sem[SH]); waiting_h -= 4; my_sem_sig(sem[S]); print_full_set(); } else { // if not enough h atoms, carbon has to wait waiting_c += 1; my_sem_sig(sem[S]); my_sem_wait(sem[SC]); } // exit pthread with success pthread_exit(NULL); }
void* rescue_me ( void* uu ) { /* wait for, and unblock, the first wait */ sleep(1); pthread_cond_signal( &cv ); /* wait for, and unblock, the second wait */ sleep(1); pthread_cond_signal( &cv ); /* wait for, and unblock, the third wait */ sleep(1); pthread_cond_signal( &cv ); /* wait for, and unblock, the fourth wait */ sleep(1); pthread_cond_signal( &cv ); my_sem_wait( quit_now ); return NULL; }
/* * Initialise an Insense component and start a POSIX thread running the behaviour function from the component. */ void *component_create(behaviour_ft behaviour, int struct_size, int stack_size, int argc, void *argv[], int core) { // Define thread struct IComponent_data *this_ptr; // Allocate space for the struct #if HEAPS == HEAP_PRIVATE // Private heaps struct shMapType *heapElement = new_PrivateHeap(); // Create a new private heap (to be put to the heap map) this_ptr = DAL_alloc_in_specific_heap(struct_size, true, heapElement); // Allocate space for this_ptr in the newly created private heap if (this_ptr == NULL ) { return NULL ; } else { memset(this_ptr, 0, struct_size); } #else // Shared heap if ((this_ptr = ((struct IComponent_data *) DAL_alloc(struct_size, true))) == NULL ) { return NULL; } else { memset(this_ptr, 0, struct_size); } #endif // Initialize this->comp_create_sem my_sem_init(&(this_ptr->component_create_sem), 0); // Setup the stopped condition if (struct_size) { struct IComponent_data *t = (struct IComponent_data*) this_ptr; t->stopped = 0; } // Define new structure for arguments for the wrapper function // Whenever dealing with garbage collection, first define as NULL struct argStructType * argStruct = malloc(sizeof(struct argStructType)); argStruct->behaviour = behaviour; argStruct->argc = argc; argStruct->argv = argv; argStruct->this_ptr = this_ptr; // Create thread #if HEAPS == HEAP_PRIVATE // Private heaps pthread_mutex_lock(&thread_lock); // Lock mutex to make component thread wait until its heap has been put inserted into the heap map #endif pthread_create(&this_ptr->behav_thread, NULL, startRoutine, argStruct); // Create a POSIX thread, use wrapper function startRoutine to pass three arguments to the function running inside of the thread //Set affinity #if AFFINITY_ALGO != AFFINITY_DYNAMIC if (core != -1) { // Manually passed Core ID setAffinityToCore(this_ptr->behav_thread, core);// Use passed ID of a core } else { // Core ID was not passed to the component_create function setAffinity(this_ptr->behav_thread);// Use an algorithm defined in GlobalVars.h } getAffinityThread(this_ptr->behav_thread); // Check if setting affinity worked. Data outputted only in PRINTMC is defined. #endif // If small heaps are used, add a new entry to the map with a pointer to a newly created pthread. #if HEAPS == HEAP_PRIVATE // Private heaps heapElement->thread_id = this_ptr->behav_thread; // Put a thread id to the element to be to the map PRINTFMC("Component created. Thread ID: %x\n", heapElement->thread_id); listAdd(SHList, heapElement); pthread_mutex_unlock(&thread_lock); // Unlock mutex to permit component to continue now that its heap has been put inserted into the heap map #endif // Insert thread into the list of threads listAdd(threadList, this_ptr->behav_thread); my_sem_wait(&this_ptr->component_create_sem); // Wait for creation of the component return this_ptr; }
void* child_fn ( void* semV ) { int r; sem_t* sem = (sem_t*)semV; r= my_sem_wait(sem); assert(!r); return NULL; }