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;
}
Esempio n. 2
0
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);
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
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;
}
Esempio n. 9
0
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);
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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);
    }
}
Esempio n. 14
0
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;
}
Esempio n. 15
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;
}