fixed_queue_t *fixed_queue_new(size_t capacity) { fixed_queue_t *ret = calloc(1, sizeof(fixed_queue_t)); if (!ret) goto error; ret->list = list_new(NULL); if (!ret->list) goto error; ret->enqueue_sem = semaphore_new(capacity); if (!ret->enqueue_sem) goto error; ret->dequeue_sem = semaphore_new(0); if (!ret->dequeue_sem) goto error; pthread_mutex_init(&ret->lock, NULL); ret->capacity = capacity; return ret; error:; if (ret) { list_free(ret->list); semaphore_free(ret->enqueue_sem); semaphore_free(ret->dequeue_sem); } free(ret); return NULL; }
void msg_do_delete(msg_info_t *info) { llist_t *_m; sysv_msg_t *m; llist_unlink((llist_t *) info); for (_m = llist_remove_last(&(info->msgs)); _m != NULL; _m = llist_remove_last(&(info->msgs))) { m = (sysv_msg_t *) _m; heapmm_free(m->mtext, m->msize); heapmm_free(m, sizeof(sysv_msg_t)); } semaphore_free(info->rwaitsem); semaphore_free(info->swaitsem); heapmm_free(info, sizeof(msg_info_t)); }
void fixed_queue_free(fixed_queue_t *queue, fixed_queue_free_cb free_cb) { if (!queue) return; if (free_cb) for (const list_node_t *node = list_begin(queue->list); node != list_end(queue->list); node = list_next(node)) free_cb(list_node(node)); list_free(queue->list); semaphore_free(queue->enqueue_sem); semaphore_free(queue->dequeue_sem); pthread_mutex_destroy(&queue->lock); free(queue); }
static gboolean test_decr_wait(void) { GThread *th; struct test_decr_wait_data data = { NULL, FALSE }; int rv; data.sem = semaphore_new_with_value(10), th = g_thread_create(test_decr_wait_thread, (gpointer)&data, TRUE, NULL); /* sleep to give semaphore_decrement() a chance to block (or not). */ g_usleep(G_USEC_PER_SEC / 4); /* and then increment the semaphore enough that the decrement can succeed */ data.increment_called = TRUE; semaphore_increment(data.sem, 10); /* join the thread and see how it fared. */ rv = GPOINTER_TO_INT(g_thread_join(th)); semaphore_free(data.sem); return (rv == 1); }
static gboolean test_force_set(void) { GThread *th; semaphore_t *sem = semaphore_new_with_value(10); th = g_thread_create(test_force_set_thread, (gpointer)sem, TRUE, NULL); /* sleep to give semaphore_decrement() a chance to block (or not). */ g_usleep(G_USEC_PER_SEC / 4); /* set it to 30, so decrement can proceed, but leave the value at 10 */ semaphore_force_set(sem, 30); /* sleep to give semaphore_wait_empty() a chance to block (or not). */ g_usleep(G_USEC_PER_SEC / 4); /* and empty out the semaphore */ semaphore_force_set(sem, 0); g_thread_join(th); semaphore_free(sem); /* it we didn't hang yet, it's all good */ return TRUE; }
static gboolean test_wait_empty(void) { GThread *th; semaphore_t *sem = semaphore_new_with_value(10); int rv; th = g_thread_create(test_wait_empty_thread, (gpointer)sem, TRUE, NULL); /* sleep to give semaphore_decrement() a chance to block (or not). */ g_usleep(G_USEC_PER_SEC / 4); /* add another 10, so decrement can hit zero next time it's called */ semaphore_increment(sem, 10); /* and wait on the semaphore emptying */ semaphore_wait_empty(sem); /* join the thread and see how it fared. */ rv = GPOINTER_TO_INT(g_thread_join(th)); semaphore_free(sem); return (rv == 1); }
void mutex_free (dk_mutex_t *mtx) { semaphore_free ((semaphore_t *) mtx->mtx_handle); #ifdef MTX_DEBUG dk_free_box (mtx->mtx_name); #endif dk_free (mtx, sizeof (dk_mutex_t)); dk_set_delete (&all_mtxs, (void*) mtx); }
thread_t * thread_attach (void) { thread_t *thr; int rc; thr = thread_alloc (); thr->thr_stack_size = (unsigned long) -1; thr->thr_attached = 1; if (thr->thr_cv == NULL) goto failed; *((pthread_t *) thr->thr_handle) = pthread_self (); rc = pthread_setspecific (_key_current, thr); CKRET (rc); /* Store the context so we can easily restart a dead thread */ setjmp (thr->thr_init_context); thr->thr_status = RUNNING; _thread_init_attributes (thr); thr->thr_stack_base = 0; return thr; failed: if (thr->thr_sem) semaphore_free (thr->thr_sem); if (thr->thr_schedule_sem) semaphore_free (thr->thr_schedule_sem); if (thr->thr_handle) dk_free (thr->thr_handle, sizeof (pthread_t)); dk_free (thr, sizeof (thread_t)); return NULL; }
void alarm_cleanup(void) { // If lazy_initialize never ran there is nothing to do if (!alarms) return; callback_thread_active = false; semaphore_post(alarm_expired); thread_free(callback_thread); callback_thread = NULL; semaphore_free(alarm_expired); alarm_expired = NULL; timer_delete(&timer); list_free(alarms); alarms = NULL; pthread_mutex_destroy(&monitor); }
thread_t *thread_new_sized(const char *name, size_t work_queue_capacity) { assert(name != NULL); assert(work_queue_capacity != 0); thread_t *ret = osi_calloc(sizeof(thread_t)); if (!ret) goto error; ret->reactor = reactor_new(); if (!ret->reactor) goto error; ret->work_queue = fixed_queue_new(work_queue_capacity); if (!ret->work_queue) goto error; // Start is on the stack, but we use a semaphore, so it's safe struct start_arg start; start.start_sem = semaphore_new(0); if (!start.start_sem) goto error; strncpy(ret->name, name, THREAD_NAME_MAX); start.thread = ret; start.error = 0; pthread_create(&ret->pthread, NULL, run_thread, &start); semaphore_wait(start.start_sem); semaphore_free(start.start_sem); if (start.error) goto error; return ret; error:; if (ret) { fixed_queue_free(ret->work_queue, osi_free); reactor_free(ret->reactor); } osi_free(ret); return NULL; }
void tsdr_free(tsdr_lib_t ** tsdr) { (*tsdr)->callback = NULL; (*tsdr)->plotready_callback = NULL; unloadplugin(*tsdr); free((*tsdr)->errormsg); (*tsdr)->errormsg_size = 0; semaphore_free(&(*tsdr)->threadsync); mutex_free(&(*tsdr)->stopsync); dsp_post_process_free(&(*tsdr)->dsp_postprocess); dsp_resample_free(&(*tsdr)->dsp_resample); frameratedetector_free(&(*tsdr)->frameratedetect); superb_free(&(*tsdr)->super); free (*tsdr); *tsdr = NULL; }
thread_t *thread_new(const char *name) { assert(name != NULL); // Start is on the stack, but we use a semaphore, so it's safe thread_t *ret = calloc(1, sizeof(thread_t)); if (!ret) goto error; ret->reactor = reactor_new(); if (!ret->reactor) goto error; ret->work_queue = fixed_queue_new(WORK_QUEUE_CAPACITY); if (!ret->work_queue) goto error; struct start_arg start; start.start_sem = semaphore_new(0); if (!start.start_sem) goto error; strncpy(ret->name, name, THREAD_NAME_MAX); start.thread = ret; start.error = 0; pthread_create(&ret->pthread, NULL, run_thread, &start); semaphore_wait(start.start_sem); semaphore_free(start.start_sem); if (start.error) goto error; return ret; error:; if (ret) { fixed_queue_free(ret->work_queue, free); reactor_free(ret->reactor); } free(ret); return NULL; }
void thread_exit (int n) { thread_t *thr = current_thread; volatile int is_attached = thr->thr_attached; if (thr == _main_thread) { call_exit (n); } thr->thr_retcode = n; thr->thr_status = DEAD; if (is_attached) { thr->thr_status = TERMINATE; goto terminate; } Q_LOCK (); thread_queue_to (&_deadq, thr); _thread_num_dead++; do { int rc = pthread_cond_wait ((pthread_cond_t *) thr->thr_cv, (pthread_mutex_t*) &_q_lock->mtx_mtx); CKRET (rc); } while (thr->thr_status == DEAD); Q_UNLOCK (); if (thr->thr_status == TERMINATE) goto terminate; /* Jumps back into _thread_boot */ longjmp (thr->thr_init_context, 1); failed: thread_queue_remove (&_deadq, thr); _thread_num_dead--; Q_UNLOCK (); terminate: if (thr->thr_status == TERMINATE) { #ifndef OLD_PTHREADS pthread_detach (* (pthread_t *)thr->thr_handle); #else pthread_detach ( (pthread_t *)thr->thr_handle); #endif _thread_free_attributes (thr); dk_free ((void *) thr->thr_cv, sizeof (pthread_cond_t)); semaphore_free (thr->thr_sem); semaphore_free (thr->thr_schedule_sem); dk_free (thr->thr_handle, sizeof (pthread_t)); thr_free_alloc_cache (thr); dk_free (thr, sizeof (thread_t)); } if (!is_attached) { _thread_num_total--; pthread_exit ((void *) 1L); } }
int main(int argc, char** argv) { //variables int A; // number of slots to Actions that can be received int B; // number of bartenders int C; // number of cups int S; // number of students int M; // maximum number of students that can be at the bar at once int fconf; int conf_size; struct stat bufstat; fconf = open("con.conf",O_RDONLY); fstat(fconf,&bufstat); conf_size = bufstat.size; char bufconf[conf_size]; read(fconf,bufconf,conf_size); int inputs_parsed[5]; //{Aval, Bval, Cval, Sval, Mval} parse_buffer(bufconf, inputs_parsed); A = inputs_parsed[0]; B = inputs_parsed[1]; C = inputs_parsed[2]; S = inputs_parsed[3]; M = inputs_parsed[4]; printf(1,"A: %d B: %d C: %d S: %d M: %d\n",A,B,C,S,M); void* students_stacks[S]; void* bartenders_stacks[B]; void* cup_boy_stack; int i; int student_tids[S]; //int bartender_tids[B]; finished_shift = 0; // cup_boy changes it to 1 if all students left the bar and sends Action => GO_HOME to bartenders file_to_write = open("out.txt",(O_CREATE | O_WRONLY)); // if(file_to_write == -1){ printf(1,"There was an error opening out.txt\n"); exit(); } //Databases bouncer = semaphore_create(M); //this is the bouncer to the Beinstein ABB = BB_create(A); //this is a BB for student actions: drink, ans for a dring DrinkBB = BB_create(A); //this is a BB holding the drinks that are ready to be drinking CBB = BB_create(C); //this is a BB hold clean cups DBB = BB_create(C); //this is a BB hold dirty cups cup_boy_lock = binary_semaphore_create(0); // initial cup_boy with 0 so he goes to sleep imidietly on first call to down general_mutex = binary_semaphore_create(1); //initialize C clean cups struct Cup* cup_array[C]; for(i = 0; i < C; i++){ cup_array[i] = malloc(sizeof(struct Cup)); //TODO free cups //memset(cup_array[i],0,sizeof(void*)*STACK_SIZE); cup_array[i]->id = i; add_clean_cup(cup_array[i]); } //initialize cup_boy cup_boy_stack = (void*)malloc(sizeof(void*)*STACK_SIZE); memset(cup_boy_stack,0,sizeof(void*)*STACK_SIZE); if(thread_create((void*)cup_boy,cup_boy_stack,sizeof(void*)*STACK_SIZE) < 0){ printf(2,"Failed to create cupboy thread. Exiting...\n"); exit(); } //initialize B bartenders for(i = 0; i < B; i++){ bartenders_stacks[i] = (void*)malloc(sizeof(void*)*STACK_SIZE); memset(bartenders_stacks[i],0,sizeof(void*)*STACK_SIZE); thread_create((void*)bartender,bartenders_stacks[i],sizeof(void*)*STACK_SIZE);//TODO test //bartender_tids[i] = } //initialize S students for(i = 0; i < S; i++){//TODO test for fail students_stacks[i] = malloc(sizeof(void*)*STACK_SIZE); memset(students_stacks[i],0,sizeof(void*)*STACK_SIZE); student_tids[i] = thread_create((void*)student,students_stacks[i],sizeof(void*)*STACK_SIZE); } join_peoples(student_tids,S); //join students finished_shift = 1; //join_peoples(bartender_tids,B); //join bartenders sleep(2); // delay so exit will not come before threads finished TODO (need better soloution) if(finished_shift){ binary_semaphore_up(cup_boy_lock); } if(close(file_to_write) == -1){ printf(1,"There was an error closing out.txt\n"); exit(); } //free cup_boy_stack free(cup_boy_stack); //after all students have finished need to exit all bartenders and cup boy, and free all memory allocation //free cups for(i = 0; i < C; i++){ free(cup_array[i]); } //free bartenders_stacks for(i = 0; i < B; i++){ free(bartenders_stacks[i]); } //free students_stacks for(i = 0; i < S; i++){ free(students_stacks[i]); } semaphore_free(bouncer); BB_free(ABB); BB_free(DrinkBB); BB_free(CBB); BB_free(DBB); exit(); return 0; }
int _sys_msgget(key_t key, int flags) { msg_info_t *info = NULL; if (key != IPC_PRIVATE) info = msg_get_by_key(key); if (info && (flags & IPC_CREAT) && (flags & IPC_EXCL)) { syscall_errno = EEXIST; return -1; } else if (!info) { if ((key != IPC_PRIVATE) && !(flags & IPC_CREAT)) { syscall_errno = ENOENT; return -1; } info = heapmm_alloc(sizeof(msg_info_t)); if (!info) { syscall_errno = ENOMEM; return -1; } info->rwaitsem = semaphore_alloc(); if (!info->rwaitsem) { heapmm_free(info, sizeof(msg_info_t)); syscall_errno = ENOMEM; return -1; } info->swaitsem = semaphore_alloc(); if (!info->swaitsem) { semaphore_free(info->rwaitsem); heapmm_free(info, sizeof(msg_info_t)); syscall_errno = ENOMEM; return -1; } /* Initialize info */ info->id = msg_alloc_id(); if (info->id == -1) { //semaphore_free(info->zwaitsem); //semaphore_free(info->nwaitsem); //heapmm_free(info->sems, sizeof(sysv_msg_t) * nsems); heapmm_free(info, sizeof(msg_info_t)); return -1; } info->del = 0; info->refs = 0; info->key = key; info->used_bytes = 0; llist_create(&(info->msgs)); /* Initialize semid_ds */ info->info.msg_perm.cuid = info->info.msg_perm.uid = get_effective_uid(); info->info.msg_perm.cgid = info->info.msg_perm.gid = get_effective_gid(); info->info.msg_perm.mode = flags & 0x1FF; info->info.msg_qnum = 0; info->info.msg_lspid = 0; info->info.msg_lrpid = 0; info->info.msg_stime = 0; info->info.msg_rtime = 0; info->info.msg_ctime = (time_t) system_time; info->info.msg_qbytes = CONFIG_SYSV_MSG_SIZE_LIMIT; llist_add_end(&msg_list, (llist_t *) info); } else if (!ipc_have_permissions(&(info->info.msg_perm), IPC_PERM_READ)) { syscall_errno = EACCES; return -1; } else if (info->del) { syscall_errno = EIDRM; return -1; } return info->id; }