Example #1
0
/* the actual thread entrypoint passed to pthread_create() */
static void *uv__thread_run(void *arg) {
  /* synchronously get the entrypoint and call it */
  uv_thread_shared_t *hnd = (uv_thread_shared_t *)arg;
  pthread_mutex_lock(&hnd->mtx);
  uv_thread_run thread_run = hnd->options->thread_run;
  void *thread_arg = hnd->options->thread_arg;
  /* ... any other processing depending on thread or options here ... */
  pthread_cond_signal(&hnd->cond);
  pthread_mutex_unlock(&hnd->mtx);  
  void *result = (*thread_run)(hnd, thread_arg);
  
  /* close any pipes created */
  if(hnd->stdin_fd != -1) uv__close(hnd->stdin_fd);
  if(hnd->stdout_fd != -1) uv__close(hnd->stdout_fd);
  if(hnd->stderr_fd != -1) uv__close(hnd->stderr_fd);

  /* synchronously notify exit to the client event loop */
  pthread_mutex_lock(&hnd->mtx);
  uv_thread_t *thread = hnd->thread_handle;
  if(thread) {
    /* copy these before they disappear ... */
    thread->exit_status = hnd->exit_status;
    thread->term_signal = hnd->term_signal;
    ev_async_send(thread->loop->ev, &thread->thread_watcher);
  }
  hnd->thread_id = 0;
  pthread_mutex_unlock(&hnd->mtx);

  /* if the handle had gone already, delete shared handle */
  if(!thread)
    uv__thread_shared_delete(hnd);
  
  return result;
}
Example #2
0
int
dcache_set_at(const char path[], uint64_t size, uint64_t nitems)
{
	int ret = 0;
	const time_t ts = time(NULL);

	if(size != DCACHE_UNKNOWN)
	{
		const dcache_data_t data = { .value = size, .timestamp = ts };

		pthread_mutex_lock(&dcache_size_mutex);
		ret |= fsdata_set(dcache_size, path, &data, sizeof(data));
		pthread_mutex_unlock(&dcache_size_mutex);
	}

	if(nitems != DCACHE_UNKNOWN)
	{
		const dcache_data_t data = { .value = nitems, .timestamp = ts };

		pthread_mutex_lock(&dcache_nitems_mutex);
		ret |= fsdata_set(dcache_nitems, path, &data, sizeof(data));
		pthread_mutex_unlock(&dcache_nitems_mutex);
	}

	return ret;
}
Example #3
0
void* Girl::drawAnimation(void * arg) {
	Girl * caller = (Girl*) arg;
	while (true) {
		pthread_mutex_lock(&(caller->lock));
		canvas.draw();
		face.draw();
		eyesOpen.draw();
		mouth.draw();
		pthread_mutex_unlock(&(caller->lock));
		Printer::printToScreen();
		usleep(25000);
		pthread_mutex_lock(&(caller->lock));
		attribute.draw();
		pthread_mutex_unlock(&(caller->lock));
		Printer::printToScreen();
		usleep(25000);
		pthread_mutex_lock(&(caller->lock));
		canvas.draw();
		face.draw();
		eyesClosed.draw();
		mouth.draw();
		pthread_mutex_unlock(&(caller->lock));
		Printer::printToScreen();
		usleep(25000);
		pthread_mutex_lock(&(caller->lock));
		attribute.draw();
		pthread_mutex_unlock(&(caller->lock));
		Printer::printToScreen();
		usleep(25000);
	}

}
int main(void)
{
	//Diccionario de funciones de comunicacion
	fns = dictionary_create();
	dictionary_put(fns, "server_saludar", &server_saludar);

	//Creo estrucutra de datos para esta conexion
	data_client * data = malloc(sizeof(data_client));
	data->x = 2;
	data->y = 9;

	//Me conecto a servidor, si hay error informo y finalizo
	if((socket_server = connectServer(ip, port, fns, &server_connectionClosed, data)) == -1)
	{
		printf("Error al intentar conectar a servidor. IP = %s, Puerto = %d.\n", ip, port);
		exit(1);
	}
	printf("Se ha conectado exitosamente a servidor. Socket = %d, IP = %s, Puerto = %d.\n", socket_server, ip, port);

	//saludo a servidor
	runFunction(socket_server, "client_saludar", 3, "hola", "como", "estas");

	//Dejo bloqueado main
	pthread_mutex_init(&mx_main, NULL);
	pthread_mutex_lock(&mx_main);
	pthread_mutex_lock(&mx_main);

	return EXIT_SUCCESS;
}
Example #5
0
/*Updates map portion of screen*/
void update_map(screen_t* my_screen){
	car_t* player = &my_screen->vw.player;
	car_t* cpu = my_screen->vw.cpu;
	int i;
	int xblit = cord2px(player->bound_box.x);
	int yblit = cord2px(player->bound_box.y);

	pthread_mutex_lock(&my_screen->sems.pcar_mux);
	blit(my_screen->map.background, screen, xblit -10, yblit-10, xblit-10, yblit-10, cord2px(player->bound_box.w)+20, cord2px(player->bound_box.h)+20);
	for(i = 0; i<CPUCARS; i++){
			if(cpu[i].alive){
				pthread_mutex_lock(&my_screen->sems.cpucar_mux[i]);
				xblit = cord2px(cpu[i].bound_box.x);
				yblit = cord2px(cpu[i].bound_box.y);
				blit(my_screen->map.background, screen, xblit-10, yblit-10, xblit-10, yblit-10, cord2px(cpu[i].bound_box.w)+20, cord2px(cpu[i].bound_box.h)+20);
			}
		}
	for(i=0;i<CPUCARS; i++)
		if(cpu[i].alive){
			rotate_sprite(screen, cpu[i].sprite, carx2px(cpu[i].pos.x), cary2px(cpu[i].pos.y), ftofix(cpu[i].angle*256/360));
			pthread_mutex_unlock(&my_screen->sems.cpucar_mux[i]);
		}
	rotate_sprite(screen, player->sprite, carx2px(player->pos.x), cary2px(player->pos.y), ftofix(player->angle*256/360));
	pthread_mutex_unlock(&my_screen->sems.pcar_mux);
}
/*
 *	Thread function
 *		Each thread on the pool will be running this function since creation
 *		The idea is that each one of them will be waiting for some job to be
 *		added to the queue. When that happens, one of them will acquire the job
 *		and execute it
 */
static void* thread_func(void *args) {
	thread_pool_t* pool =(thread_pool_t*) args;

	while(1) {
		pthread_mutex_lock(&pool->mutex);
		while(pool->queue.length == 0) {
			DEBUG("Wating for jobs...");
			pthread_cond_wait(&pool->has_jobs, &pool->mutex);
		}
		pool->n_threads_working++;
		DEBUG("Got a Job!");

		job_t* job = next_job(&pool->queue);
		if(job == NULL)
			continue;

		pthread_mutex_unlock(&pool->mutex);
		job->func(job->arg);

		pthread_mutex_lock(&pool->mutex);
		pool->n_threads_working--;
		pthread_mutex_unlock(&pool->mutex);
	}

	return NULL;
}
Example #7
0
void* workerThread(void *resources){

  //Take the resource, make sure to access and check if there are enough
  do{
    //wait for access
    pthread_mutex_lock(&leMutex);
    //check status
    if((int)available_resources<(int)resources){
     //release mutex if there are not enough resources
     pthread_mutex_unlock(&leMutex);
    }
    else{
     //if there are enough resources use them
     decrease_count(resources);
     printf("Taking %d resources current count = %d\n",resources,available_resources);
     //release access to the resources
     pthread_mutex_unlock(&leMutex);
     break;
    }
  }while(1);

  //do that random sleep
  sleep(rand()%5);

  //Give the resources back, less strict because we are just returning.
  //wait for access
  pthread_mutex_lock(&leMutex);
  //recieve access to resources
  increase_count(resources);
  printf("Returning %d resources current count = %d\n",resources,available_resources);
  //release access to the resources
  pthread_mutex_unlock(&leMutex);

pthread_exit(NULL);
}
Example #8
0
/*
 * This function is used to type cast a session handle to a pointer to
 * the session struct. Also, it does the following things:
 * 1) Check to see if the session struct is tagged with a session
 *    magic number. This is to detect when an application passes
 *    a bogus session pointer.
 * 2) Acquire the locks on the designated session and the slot which owns
 *    this session.
 * 3) Check to see if the session is in the closing state that another
 *    thread is performing.
 * 4) Increment the session reference count by one. This is to prevent
 *    this session from being closed by other thread.
 * 5) Release the locks on the designated session and on the slot.
 */
CK_RV
handle2session(CK_SESSION_HANDLE hSession, kernel_session_t **session_p)
{
	kernel_session_t *sp = (kernel_session_t *)(hSession);
	CK_RV rv;
	kernel_slot_t *pslot;

	if ((sp == NULL) ||
	    (sp->magic_marker != KERNELTOKEN_SESSION_MAGIC)) {
		return (CKR_SESSION_HANDLE_INVALID);
	} else {
		pslot = slot_table[sp->ses_slotid];
		(void) pthread_mutex_lock(&pslot->sl_mutex);
		(void) pthread_mutex_lock(&sp->session_mutex);
		if (sp->ses_close_sync & SESSION_IS_CLOSING) {
			rv = CKR_SESSION_CLOSED;
		} else {
			/* Increment session ref count. */
			sp->ses_refcnt++;
			rv = CKR_OK;
		}
		(void) pthread_mutex_unlock(&sp->session_mutex);
		(void) pthread_mutex_unlock(&pslot->sl_mutex);
	}

	if (rv == CKR_OK)
		*session_p = sp;

	return (rv);
}
Example #9
0
File: final.c Project: chessgit/uc
void *func(void *p)
{//线程函数
	client *q = p;
	int c = q->s;
	pthread_mutex_lock(&m);
	char ip[16];
	strcpy(ip,q->ip);
	pthread_mutex_unlock(&m);
	char msg[1000];
	int n = sprintf(msg,"%s加入聊天\n",ip);
	broadcast(0,msg,n);//对所有客户端广播
	int iplen = sprintf(msg,"%s说:",ip);
	char *info = msg+iplen;//end指向冒号后面	
	for(;;)
	{
		int len = read(c,info,sizeof(msg)-iplen);
		if(len<0)break;
		if(info[0]=='q'&&isspace(info[1]))break;
		broadcast(c,msg,len+iplen);
	}
	//q
	pthread_mutex_lock(&m);
	q->s=0;
	pthread_mutex_unlock(&m);
	close(c);
	n = sprintf(msg,"%s离开了\n",ip);
	broadcast(0,msg,n);
}
Example #10
0
void rxtx_task_exec_stop(struct rxtx_data *rxtx, unsigned char *requests,
                         struct bladerf *dev)
{
    int status;

    *requests = rxtx_get_requests(rxtx,
                                  RXTX_TASK_REQ_STOP | RXTX_TASK_REQ_SHUTDOWN);

    pthread_mutex_lock(&rxtx->data_mgmt.lock);
    bladerf_deinit_stream(rxtx->data_mgmt.stream);
    rxtx->data_mgmt.stream = NULL;
    pthread_mutex_unlock(&rxtx->data_mgmt.lock);

    pthread_mutex_lock(&rxtx->file_mgmt.file_lock);
    if (rxtx->file_mgmt.file != NULL) {
        fclose(rxtx->file_mgmt.file);
        rxtx->file_mgmt.file = NULL;
    }
    pthread_mutex_unlock(&rxtx->file_mgmt.file_lock);

    if (*requests & RXTX_TASK_REQ_SHUTDOWN) {
        rxtx_set_state(rxtx, RXTX_STATE_SHUTDOWN);
    } else {
        rxtx_set_state(rxtx, RXTX_STATE_IDLE);
    }

    status = bladerf_enable_module(dev, rxtx->module, false);
    if (status < 0) {
        set_last_error(&rxtx->last_error, ETYPE_BLADERF, status);
    }

    *requests = 0;

    rxtx_release_wait(rxtx);
}
Example #11
0
void init_field(
  const arg_t args,     // in
  field_t* field) // out
{
  field->height = args.height_field;
  field->width = args.width_field;
  size_t field_size = (field->width + 2) * (field->height + 2);
  printf("allocating field %ix%i=%lu\n", field->width, field->height, field_size);
  field->old_values = calloc(field_size, sizeof(field_value_t));
  field->old_values = &field->old_values[3 + field->width];
  field->new_values = calloc(field_size, sizeof(field_value_t));
  field->new_values = &field->new_values[3 + field->width];
  field->rows_per_thread = 32 * 1024 / (field->width + 2);
  field->n_threads = (field->height)/field->rows_per_thread + (((field->height) % field->rows_per_thread) ? 1 : 0);
  printf("using %i threads\n", field->n_threads);
  field->start_conditions = calloc(field->n_threads, sizeof(pthread_mutex_t));
  field->stop_conditions = calloc(field->n_threads, sizeof(pthread_mutex_t));
  field->threads = calloc(field->n_threads, sizeof(pthread_t));
  field->thread_args = calloc(field->n_threads, sizeof(thread_arg_t));
  for (int i = 0; i < field->n_threads; ++i)
  {
    pthread_mutex_init(&field->start_conditions[i], NULL);
    pthread_mutex_lock(&field->start_conditions[i]);
    pthread_mutex_init(&field->stop_conditions[i], NULL);
    pthread_mutex_lock(&field->stop_conditions[i]);
    field->thread_args[i].id = i;
    field->thread_args[i].field = field;
    pthread_create(&field->threads[i], NULL, thread_main, &field->thread_args[i]);
  }
}
Example #12
0
void *consumer(void *arg)
{
        int index = 0;
        while(1){
                // Protect Buffer
                pthread_mutex_lock(&mut);
                // Check to see if there's anything in the buffer, if not wait
                while (currentIndex == 0){
                        printf("waiting for produce\n");
                        pthread_cond_wait(&conditionConsume, &mut);
                }
                pthread_mutex_unlock(&mut);

                // 'Consume' item
                sleep(buff[currentIndex-1].sleepTime);

                // Protect buffer while we 'consume'
                pthread_mutex_lock(&mut);
                printf("Consumer: Consumed item: %d, with value: %d\n", currentIndex-1, buff[currentIndex-1].number);
                currentIndex--;
                // Wake up producer
                pthread_cond_signal(&conditionProduce);
                pthread_mutex_unlock(&mut);
        }
}
Example #13
0
//////////////////////////////////////////////////
//@Fuction name : am_demux_close(U8 index)
//@Description:close filter
//@param <IN>
//@--index : same as outindex in the function demux_open(DMX_FILTER_TYPE type,U8 index,U8* outindex)
//@param <RET>
//@--TRUE:sucess
//@--FALSE:fail
TAPI_BOOL am_demux_close(TAPI_S8 index) {
    int ret = -1;
    am_demux_filter_t *am_dmx_filter_ptr = NULL;

    pthread_mutex_lock(&am_demux_dev.lock);
    if (TAPI_FALSE == get_filter_by_index(index, &am_dmx_filter_ptr)) {
        pthread_mutex_unlock(&am_demux_dev.lock);
        return TAPI_FALSE;
    }

    if (am_dmx_filter_ptr->fid != -1 && am_dmx_filter_ptr->used) {
        am_dmx_filter_ptr->enable = TAPI_FALSE;
        DEBUG_TIME();DEBUG("filter[%d]close pid = %d\n",am_dmx_filter_ptr->index,am_dmx_filter_ptr->pid);
        ret = AM_DMX_FreeFilter(am_dmx_filter_ptr->dmx_dev_id, am_dmx_filter_ptr->fid);
        if (ret != AM_SUCCESS) {
            LOGE("free filter failure!  filter_index=%d", am_dmx_filter_ptr->fid);
        }
        //free buf list used by filter
        dmx_cbuf_reset(&am_dmx_filter_ptr->cbuf);
        am_dmx_filter_ptr->used = TAPI_FALSE;
        am_dmx_filter_ptr->fid = -1;

        pthread_mutex_unlock(&am_demux_dev.lock);
        AM_DMX_Sync(am_dmx_filter_ptr->dmx_dev_id);
        pthread_mutex_lock(&am_demux_dev.lock);
        am_dmx_filter_ptr->serialnumread = am_dmx_filter_ptr->serialnumwrite = 0;
    }
    pthread_mutex_unlock(&am_demux_dev.lock);
    return ret == AM_SUCCESS ? TAPI_TRUE : TAPI_FALSE;
}
Example #14
0
void Event::set()
{
   #ifdef NDEBUG
   pthread_mutex_lock( &m_mtx );
   m_bIsSet = true;

   if ( m_bAutoReset )
      pthread_cond_signal( &m_cv );
   else
      pthread_cond_broadcast( &m_cv );

   pthread_mutex_unlock( &m_mtx );
   #else
   int result = pthread_mutex_lock( &m_mtx );
   fassert( result == 0 );
   m_bIsSet = true;

   if ( m_bAutoReset )
      result = pthread_cond_signal( &m_cv );
   else
      result = pthread_cond_broadcast( &m_cv );

   fassert( result == 0 );
   result = pthread_mutex_unlock( &m_mtx );
   fassert( result == 0 );
   #endif
}
Example #15
0
static void* emojicodeMalloc(size_t size){
    pthread_mutex_lock(&allocationMutex);
    pauseForGC(&allocationMutex);
    if (memoryUse + size > gcThreshold) {
        if (size > gcThreshold) {
            error("Allocation of %zu bytes is too big. Try to enlarge the heap. (Heap size: %zu)", size, heapSize);
        }
        
        pauseThreads = true;
        pthread_mutex_unlock(&allocationMutex);
        
        pthread_mutex_lock(&pausingThreadsCountMutex);
        pausingThreadsCount++;

        while (pausingThreadsCount < threads) pthread_cond_wait(&threadsCountCondition, &pausingThreadsCountMutex);
        gc();
        
        pausingThreadsCount--;
        pthread_mutex_unlock(&pausingThreadsCountMutex);

        pauseThreads = false;
        pthread_cond_broadcast(&pauseThreadsFalsedCondition);
        pthread_mutex_lock(&allocationMutex);
    }
    Byte *block = currentHeap + memoryUse;
    memoryUse += size;
    pthread_mutex_unlock(&allocationMutex);
    return (void *)block;
}
Example #16
0
/** Finds and performs an action on a word's data atomically, if a match exists.
   This is the magical function that allows parallelism and locking at the same time. First, the global lock is obtained
      to search the list for a match. If a match is not found, `nomatch_fun` is called, and then theglobal lock is
      released and the function returns.
   If a match is found, this function guarantees that a unique lock attached to the match is obtained, and then the
      global list lock is released. Then, `match_fun` is called with the datapreviously associated to `word`. As a
      consequence, this function is atomically executed with respect to the specific structure associated to `word`.
      When that function returns, this unique lock is released, and thisfunction returns.
   This means that multiple threads don't necessarily have to wait for each other when they want to do some work on
      different list nodes. However, if a thread is doing some work on node B, and another thread comes in andasks for
      node B, it will have to wait for the former thread to finish processing, and it will do so while holding the
      global list lock. That is, if two threads concurrently try to access the same node, one of them willhave to wait,
      and will force every other thread trying to access ANY node to wait.
   This is necessary; we can't obtain the unique lock for a node without holding a global lock, otherwise, the
      unfortunate situation in which we release the global lock; another thread deletes node B, and then we get back and
      try to lock node B could arise, and we would be in very big trouble.
   User supplied functions (`match_fun` and `nomatch_fun`) are allowed to be `NULL`, in that case, the corresponding
      pointer to the function is ignored.
   When `word` was not found in the list, `nomatch_fun` is called with `nomatch_fargs` while holding a global list lock.
   When `word` is found, a unique lock associated to `word` is obtained, the global lock is released, and `match_fun` is
      called with the generic data that was previously associated to `word` as its first parameter, and with
      `match_fargs` as second parameter.
   This function should only be called with a `match_fun` that can't possibly invoke list operations that will add or
      delete elements from the list.
   On the other hand, since `nomatch_fun` is called while holding the global lock, it is safe to perform other list
      operations, as far as it uses operations that do not lock (`list_find_word_nolock()` and others).
   @param list The list to perform the search on.
   @param word A pointer to a null terminated characters sequence holding the word to search for.
   @param match_fun A pointer to a function returning a generic pointer that shall be called if a match is found. Under
      such scenario, the function is called while holding a unique lock associated to the node found, but without
      holding a global lock to the list, to increase parallelism. The first parameter passed to this function is the
      matching node's data, and the second is `match_fargs`. Because it does not hold a global lock to the list, this
      function shall not invoke other list operations, especially add or remove.
   @param nomatch_fun A pointer to a function returning a generic pointer that shall be called if a match is not found.
      Under such scenario, the function is called while holding the global list lock, and it is passed
        `nomatch_fargs`.
   @param match_fargs This will be passed to `match_fun` as a second parameter when a match is found.
   @param nomatch_fargs This will be passed to `nomatch_fun` when a match is not found.
   @param success After this function returns, `success` will hold `1` if `(match_fun)()` was called, otherwise it will
      hold `0`. This allows the caller to have `(match_fun)()` or `(nomatch_fun)()` returning `NULL` and still
      distinguish between a successfull and failed match.
   @return
   <ul>
   <li>If no match is found and `nomatch_fun` is `NULL`, then `NULL` is returned.</li>
   <li>If no match is found and `nomatch_fun` is not `NULL`, then the result of evaluating
      `(nomatch_fun)(nomatch_fargs)` is returned.</li>
   <li>If a match is found and `match_fun` is `NULL`, then `NULL` is returned.</li>
   <li>If a match is found and `match_fun` is not `NULL`, then the result of evaluating `(match_fun)(node_data,
      match_fargs)` is returned.</li>
   </ul>
   @warning The functions must not call `pthread_exit()`.
   @warning Read the documentation carefully, and make sure to understand which locks are active inside `match_fun` and
      `nomatch_fun`. It is easy to create deadlock situations when not paying attention.
   @note `nomatch_fun` is free to add or delete elements from the list, since it will be executing inside a globally
      atomic block. Keep in mind that `list_add_nolock()` and `list_delete_nolock()` must be used instead of the regular
      functions. On the other hand, `match_fund` must not add or delete elements from the list, since `match_fun` is
      executed without holding a global lock for the list. See `list_find_and_execute_globalock()` for a possible
       workaround.
 */
void *list_find_and_execute(Word_list_ptr list,
			    char *word,
			    void *(*match_fun)(void *, void *),
			    void *(*nomatch_fun)(void*),
			    void *match_fargs,
			    void *nomatch_fargs,
			    int *success)
{
	void *ret;
	struct yaircd_node *node;
	*success = 0;
	pthread_mutex_lock(&list->mutex);
	ret = find_word_trie(list->trie, word);
	if (ret == NULL) {
		ret = (nomatch_fun != NULL ? (*nomatch_fun)(nomatch_fargs) : NULL);
		pthread_mutex_unlock(&list->mutex);
		return ret;
	}
	node = (struct yaircd_node*)ret;
	pthread_mutex_lock(&node->mutex);
	pthread_mutex_unlock(&list->mutex);
	ret = (match_fun != NULL ? (*match_fun)(node->data, match_fargs) : NULL);
	pthread_mutex_unlock(&node->mutex);
	*success = 1;
	return ret;
}
Example #17
0
File: arreglo.c Project: Elitos/ls2
void * hebra(void * input) {
	int tid = input;
	int myVal;
	int ptid = (tid == 0) ? SIZE-1 : tid-1;

	int minTid = (tid == 0) ? tid : ptid
	,maxTid = (tid == 0) ? ptid : tid;

	myVal = a[tid];

	pthread_barrier_wait(barrera);
	while(1) {
		pthread_mutex_lock(&mutexs[minTid]);
		pthread_mutex_lock(&mutexs[maxTid]);
			if(a[ptid] > myVal) {
				a[tid] = a[ptid];
			} else if(a[ptid] == myVal) {
				printf("El mayor es %d\n", myVal);
				exit(0);
			}
		pthread_mutex_unlock(&mutexs[maxTid]);
		pthread_mutex_unlock(&mutexs[minTid]);
	}
	printf("Hebra %d launched a[%d] = %d\n", tid, tid, a[tid]);
}
Example #18
0
/** Similar to `list_find_and_execute()`, except that both `match_fun` and `nomatch_fun` are executed while holding a
   global lock. This must be used everytime `match_fun` can possibly add or delete items from the list.
   First, a global lock for the list is obtained. The list is searched for `word`.
   When a match is found, it is guaranteed that `match_fun` is called with the data previously associated to `word` and
      with `match_fargs` only when no other thread is working on the same node.
   This holds true even for threads that may be working on this node without holding a global lock. It is safe for
      `match_fun` to commit suicide, i.e., delete the node it's working on, as far as it uses `list_delete_nolock()`.
   No other deletion operations are allowed to be performed by `match_fun` other than deleting the node it's working on.
      To do so, it must call `list_delete_nolock()`.
   We use a clever little trick to ensure both atomicity on this node and the capability to delete itself: after
      acquiring the global lock, a unique lock to the node is acquired and then immediately released; by the time it is
      released,	no other thread can be working on this node, and since the global lock is with us, no one else is stuck
      trying to lock this specific node. Also, because we released the node's lock, it is safe for the node to destroy
      itself.
   If a match is not found, `nomatch_fun` is called with `nomatch_fargs` while holding the global list lock.
   @param list The list to perform the search on.
   @param word A pointer to a null terminated characters sequence holding the word to search for.
   @param match_fun A pointer to a function returning a generic pointer that shall be called if a match is found under
      the scenario described above.
   @param nomatch_fun A pointer to a function returning a generic pointer that shall be called if a match is not found
      under the scenario described above.
   @param match_fargs This will be passed to `match_fun` as a second parameter when a match is found.
   @param nomatch_fargs This will be passed to `nomatch_fun` when a match is not found.
   @param success After this function returns, `success` will hold `1` if `(match_fun)()` was called, otherwise it will
      hold `0`. This allows the caller to have `(match_fun)()` or `(nomatch_fun)()` returning `NULL` and still
      distinguish between a successfull and failed match.
   @return
   <ul>
   <li>If no match is found and `nomatch_fun` is `NULL`, then `NULL` is returned.</li>
   <li>If no match is found and `nomatch_fun` is not `NULL`, then the result of evaluating
      `(nomatch_fun)(nomatch_fargs)` is returned.</li>
   <li>If a match is found and `match_fun` is `NULL`, then `NULL` is returned.</li>
   <li>If a match is found and `match_fun` is not `NULL`, then the result of evaluating `(match_fun)(node_data,
      match_fargs)` is returned.</li>
   </ul>
   @warning Deletion operations inside `match_fun` are only allowed for itself, i.e., `match_fun` cannot delete a node
      that is not the same node with which it is currently working. Ignoring this will lead to race conditions, and all
      bets are off.
 */
void *list_find_and_execute_globalock(Word_list_ptr list,
				      char *word,
				      void *(*match_fun)(void *, void *),
				      void *(*nomatch_fun)(void*),
				      void *match_fargs,
				      void *nomatch_fargs,
				      int *success)
{
	void *ret;
	struct yaircd_node *node;
	*success = 0;
	pthread_mutex_lock(&list->mutex);
	ret = find_word_trie(list->trie, word);
	if (ret == NULL) {
		ret = (nomatch_fun != NULL ? (*nomatch_fun)(nomatch_fargs) : NULL);
		pthread_mutex_unlock(&list->mutex);
		return ret;
	}
	node = (struct yaircd_node*)ret;
	/* Make sure no threads without the global lock are working on this node */
	pthread_mutex_lock(&node->mutex);
	/* By this point, we hold:
	        - The global lock
	        - The lock for this node
	   Nobody is able to access the list and grab this node; we can unlock node->mutex, and in fact we need to,
	   since match_fun can commit suicide (i.e. delete the node it's working on)
	 */
	pthread_mutex_unlock(&node->mutex);
	ret = (match_fun != NULL ? (*match_fun)(node->data, match_fargs) : NULL);
	pthread_mutex_unlock(&list->mutex);
	*success = 1;
	return ret;
}
void *blue(void *num_b){
	int number;
	int i;
	number = *(int *)(num_b);
	
	/*perimenoun ola ta ble amaksia gia na boun sthn oura ths gefuras*/
	pthread_mutex_lock(&m_ex_blue);
	
	check_blue++;
	/*elegxoume an exoun bei sthn oura ths gefuras ta ble autokinhta kai ksupname to prwto pou bhke sthn oura*/
	if(check_blue == i_blue) {
		pthread_cond_signal(&cond_blue);
	}
	/*an uparxoun perissotera tou 1 ble autokinhta, vazoume ta ble autokinhta sthn oura ths gefuras*/
	if(i_blue!=1){
		pthread_cond_wait(&cond_blue,&m_ex_blue);
	}
	/*kathe Niosto amaksi stelnei shma gia N-1 autokinhta*/
	if(count_b%N==0){
		count_b++;
		/*shma gia ta N-1 autokinhta*/
		for(i=1; i<N && i<=(i_blue-count_b); i++) {
			pthread_cond_signal(&cond_blue);
		}
	}
	/*an den hmaste sto Niosto autokinhto auksanoume to metrhth*/
	else {
		count_b++;
	}
	pthread_mutex_unlock(&m_ex_blue);
	
	printf("blue %d\n",number);
	
	/*kleidwnoume to mtx gia na uparxei amoivaios apokleismos metaksu twn ble autokinhtwn*/
	pthread_mutex_lock(&mtx);
	/*auksanoume to metrhth twn amaksiwn pou bainoun sth gefura*/
	un_count_b++;
	if(un_count_b%N == 0 || i_blue == un_count_b) {
		printf("count_blue %d\n",un_count_b);
		/*energopoiei ta kokkina an den exoun teleiwsei*/
		if(i_red != un_count_r) {
			pthread_cond_signal(&cond_red);
		}
		/*an exoun teleiwsei ta kokkina*/
		else {
			/*kai exoun teleiwsei kai ta ble energopoiei th main*/
			if(i_blue == un_count_b) {
				pthread_cond_signal(&cond_main);
			}
			/*kai den exoun teleiwsei ta ble energopoiei ta ble*/
			else {
				pthread_cond_signal(&cond_blue);
			}
		}
	}
	/*stamatame ton amoivaio apokleismo afou teleiwse o krisimos kwdikas*/
	pthread_mutex_unlock(&mtx);
	
	return(NULL);
}
Example #20
0
int
set_page_data(struct DataTable *tbl, void *va, data_t id)
{
  int i;

  pge_t *pge = &(tbl->table)[PGX(va)];
  if(! *pge) {
    pthread_mutex_lock(&tbl->lock);
    *pge = malloc(sizeof(pue_t) * TBLENTRIES);
    memset(*pge, 0, sizeof(pue_t) * TBLENTRIES);
    pthread_mutex_unlock(&tbl->lock);
  }
  
  pue_t *pue = &(*pge)[PUX(va)];
  if(! *pue) {
    pthread_mutex_lock(&tbl->lock);
    *pue = malloc(sizeof(pme_t) * TBLENTRIES);
    memset(*pue, 0, sizeof(pme_t) * TBLENTRIES);
    pthread_mutex_unlock(&tbl->lock);
  }

  pme_t *pme = &(*pue)[PMX(va)];
  if(! *pme) {
    pthread_mutex_lock(&tbl->lock);
    *pme = malloc(sizeof(data_t) * TBLENTRIES);
    memset(*pme, 0, sizeof(data_t) * TBLENTRIES);
    pthread_mutex_unlock(&tbl->lock);
  }

  DEBUG_LOG("set_page_data of %p from %lu to %lu", va, (*pme)[PTX(va)], id);
  (*pme)[PTX(va)] = id;

  return 0;
}
Example #21
0
int evict_cache(void)
{
    struct cache *temp = head.next;
    int flag = 0;

    pthread_mutex_lock(&head.c_lock);
    pthread_mutex_lock(&temp->c_lock);

    if (validate(&head, temp)) {
	head.next = temp->next;
	temp->valid = 0;
	pthread_mutex_lock(&s_lock);
	total_cache_size -= strlen(temp->data);
	pthread_mutex_unlock(&s_lock);
	flag = 1;
    }

    pthread_mutex_unlock(&temp->c_lock);
    pthread_mutex_unlock(&head.c_lock);

    if (flag == 1) {
	Free(temp->data);
	Free(temp->uri);
	Free(temp);
    }
    return flag;
}
    bool transfer_balance(account_id_t acc_id1, account_id_t acc_id2, balance_t amount)
    {
        if (acc_id1 == acc_id2)
            return true;
        pthread_rwlock_rdlock(&accounts_guard);
        if (accounts.find(acc_id1) == accounts.end()
            || accounts.find(acc_id2) == accounts.end())
        {
            pthread_rwlock_unlock(&accounts_guard);
            return false;
        }
        account_info& acc1 = accounts[acc_id1];
        account_info& acc2 = accounts[acc_id2];
        if (acc_id1 > acc_id2)
        {
            pthread_mutex_lock(&acc1.mtx);
            pthread_mutex_lock(&acc2.mtx);
        }
        else
        {
            pthread_mutex_lock(&acc2.mtx);
            pthread_mutex_lock(&acc1.mtx);
        }
        pthread_rwlock_unlock(&accounts_guard);

        acc1.balance -= amount;
        acc2.balance += amount;

        pthread_mutex_unlock(&acc1.mtx);
        pthread_mutex_unlock(&acc2.mtx);
        return true;
    }
Example #23
0
/*sends update messages to other servers, excluding the one who send the update message*/
void updateSrvs(char *msg,char *srvId){
	int i;
	int excluded=0;
	if(msg){
		pthread_mutex_lock (&mtx);
		printf("sending updates for serv : %s \n",msg);
		for(i=0;i<savedIpv4;i++){
			if(excluded == 1 || strcmp(servIds_ipv4[i],srvId)!=0){
				printf("sending updates for IPV4 SRV : %s \n",servIds_ipv4[i]);
				sendMsg(msg,socket_ipv4,&ipv4[i],sizeof(skaddr_in));
			}	
			else
				excluded=1;
		}
		pthread_mutex_unlock (&mtx);
	
		//for ipv6 addressed servers
		pthread_mutex_lock(&mtx);
		for(i=0;i<savedIpv6;i++){
			if(excluded == 1 || strcmp(servIds_ipv6[i],srvId)!=0){
				printf("sending updates for IPV6 SRV : %s \n",servIds_ipv6[i]);
				sendMsg(msg,socket_ipv6,&ipv6[i],sizeof(skaddr_in6));
			}
			else
				excluded=1;
		}			
		pthread_mutex_unlock (&mtx);
	}	
}	
void 	_Jacobi_Thread(struct _Jacobi_ThreadInfo *info)
{
	int i, j;
	j_type *tmp;	// To temporarily store results avoiding cache bouncing

	// Allocating
	if( (tmp = (j_type *) malloc( sizeof(j_type) *(info->lineEnd - info->lineStart +1) )) == NULL )
		return;

	// Run indefinitely. Main will have to kill me
	while(1)
	{
		// Lock this thread's mutex allowing only one iteration
		pthread_mutex_lock(info->jacobi->threadSync +(info->num));

		// Calculate one iteration
		//_Jacobi_ThreadIteration(info);

		for(i = info->lineStart, j=0; i <= info->lineEnd; i++, j++)
			tmp[j] = _Jacobi_SingleIteration(info->jacobi->A, info->jacobi->b, info->jacobi->x1, i, info->jacobi->size);

		// Copy temporary array to results
		pthread_mutex_lock( &(info->jacobi->resultSync) );
		for(i = info->lineStart, j=0; i <= info->lineEnd; i++, j++)
			info->jacobi->x2[i] = tmp[j];
		pthread_mutex_unlock( &(info->jacobi->resultSync) );

		// Raise the semaphore
		sem_post( &(info->jacobi->mainSync) );
	}

	// Free
	free(tmp);
}
Example #25
0
void
dcache_get_at(const char path[], uint64_t *size, uint64_t *nitems)
{
	/* Initialization to make condition false by default. */
	dcache_data_t size_data, nitems_data;

	pthread_mutex_lock(&dcache_size_mutex);
	if(fsdata_get(dcache_size, path, &size_data, sizeof(size_data)) != 0)
	{
		size_data.value = DCACHE_UNKNOWN;
	}
	pthread_mutex_unlock(&dcache_size_mutex);

	pthread_mutex_lock(&dcache_nitems_mutex);
	if(fsdata_get(dcache_nitems, path, &nitems_data, sizeof(nitems_data)) != 0)
	{
		nitems_data.value = DCACHE_UNKNOWN;
	}
	pthread_mutex_unlock(&dcache_nitems_mutex);

	if(size != NULL)
	{
		*size = size_data.value;
	}
	if(nitems != NULL)
	{
		*nitems = nitems_data.value;
	}
}
Example #26
0
/*! \fn int io_device_read(uint16_t procnum)
 *  \brief Richiede un accesso al dispositivo di I/O
 *  \details La funzione si occupa di accodare la richiesta d'accesso al
 *  dispositivo di I/O da parte di uno dei processi. Qualora l'MMU abbia
 *  gia terminato la propria esecuzione, la funzione non accetta
 *  ulteriori richieste.
 *  \param procnum      ID del processo
 *  \return             Restituisce l'esito dell'operazione:
 *                      1  la richiesta e' stata accodata
 *                      0  quando non sono piu' ammesse richieste
 */
int io_device_read(uint16_t procnum)
{
    io_entry_t *req;
    int ret;

    pthread_mutex_lock(&request_lock);

    if (!io_device_should_exit) {
        pthread_mutex_lock(&wait_lock);
        req = XMALLOC(io_entry_t, 1);
        req->pid = proc_table[procnum]->pid;
        req->procnum = procnum;
        pthread_mutex_lock(&fifo_lock);
        if (STAILQ_EMPTY(&io_request_head))
            STAILQ_INSERT_HEAD(&io_request_head, req, entries);
        else
            STAILQ_INSERT_TAIL(&io_request_head, req, entries);
        ioreq_count++;
        pthread_mutex_unlock(&fifo_lock);

        fprintf(LOG_FILE(procnum),
                "\nRichiesta d'accesso a dispositivo I/O accodata\n");

        pthread_mutex_unlock(&wait_lock);
        pthread_cond_signal(&wait_cond);
        ret = 1;
    } else
        ret = 0;

    pthread_mutex_unlock(&request_lock);

    return ret;
}
Example #27
0
void balance_queues(void)
{
	int core_index;
	int count;
	int min_count = RUN_QUEUE_SIZE;
	int max_count = 0;
	int min_index = 0;
	int max_index = 0;

	//Lock Consumer threads, hard coded them for better performance, to avoid branches.
	pthread_mutex_lock(&consumer_mutexes[0]);
	pthread_mutex_lock(&consumer_mutexes[1]);
	pthread_mutex_lock(&consumer_mutexes[2]);
	pthread_mutex_lock(&consumer_mutexes[3]);

	//Go through four cores
	for (core_index = 0; core_index < CORE_NUMBER; ++core_index)
	{
		count = (cpu_queues[core_index].rq0.tail - cpu_queues[core_index].rq0.head) + (cpu_queues[core_index].rq1.tail - cpu_queues[core_index].rq1.head) + (cpu_queues[core_index].rq2.tail - cpu_queues[core_index].rq2.head);
		printf("[Balancer] Core%d has %d processes in its queues\n", core_index, count);	
		if (min_count >= count)
		{
			min_count = count;
			min_index = core_index;
		}
		else if (max_count <= count)
		{
			max_count = count;
			max_index = core_index;
		}
	}

	if (max_count == 0)
	{
		printf("[Balancer] No need to balance this time.\n");
		done_flag = 1;
	}
	else {
		//Check if balance necesery
		if ((max_count - min_count) >= 2)
		{
			/* Move from CPU[max_index] to CPU[min_index] */
			cpu_queues[min_index].rq1.processes[cpu_queues[min_index].rq1.tail] = cpu_queues[max_index].rq1.processes[cpu_queues[max_index].rq1.tail];
			/* Update queues */
			cpu_queues[min_index].rq1.tail++;
			cpu_queues[max_index].rq1.tail--;
		} else {
			printf("[Balancer] No need to balance this time.\n");
		}
	}




	/* Release the mutex */
	pthread_mutex_unlock(&consumer_mutexes[3]);
	pthread_mutex_unlock(&consumer_mutexes[2]);
	pthread_mutex_unlock(&consumer_mutexes[1]);
	pthread_mutex_unlock(&consumer_mutexes[0]);
}
Example #28
0
/*! \fn void *thread_io_device(void *parg)
 *  \brief Thread dispositivo I/O
 *  \details La funzione costituisce il corpo del thread che rappresenta il
 *  dispositivo di I/O. Il suddetto thread sospende la propria esecuzione
 *  fintanto che non siano presenti delle richieste d'accesso al dispositivo.
 *  Il thread termina la propria esecuzione quando sono stati compiuti il
 *  numero massimo d'accessi alla memoria (ad opera dell'MMU).
 *  \param parg         inutilizzato
 *  \return             inutilizzato
 */
static void *
thread_io_device(void *parg)
{
    io_entry_t *req;
    struct timespec timeout;
    int num;

    printf("--> Thread DEVICE I/O avviato [Tmin=%d, Tmax=%d]\n",
           io_dev.Tmin, io_dev.Tmax);

    while (!io_device_should_exit) {
        pthread_mutex_lock(&wait_lock);
        while ((ioreq_count == 0) && !io_device_should_exit) {
            pthread_cond_wait(&wait_cond, &wait_lock);
        }

        if (io_device_should_exit && (ioreq_count == 0)) {
            pthread_mutex_unlock(&wait_lock);
            break;
        }

        /*
         *  Estraggo la prima richiesta e la rimuovo dalla coda, aggiornando
         *  la variabile "ioreq_count" che tiene traccia di quante richieste
         *  sono ancora in attesa.
         */
        req = STAILQ_FIRST(&io_request_head);
        assert(req);

        pthread_mutex_lock(&fifo_lock);
        STAILQ_REMOVE(&io_request_head, req, io_entry, entries);
        ioreq_count--;
        pthread_mutex_unlock(&fifo_lock);

        /*
         *  Genero un numero casuale compreso nell'intervallo chiuso
         *  [Tmin,Tmax] utile a simulare il reperimento dell'informazione dal
         *  dispositivo.
         */
        num = bounded_rand(io_dev.Tmin, io_dev.Tmax);
        timeout.tv_sec = 0;
        timeout.tv_nsec = num * 1000000;
        nanosleep(&timeout, NULL);
        fprintf(LOG_FILE(req->procnum),
                "Richiesta d'accesso servita in %d ms\n", num);

        /*
         *  Aggiorno le statistiche e "risveglio" il processo che ha fatto la
         *  richiesta.
         */
        io_dev.req_count++;
        proc_table[req->procnum]->stats.io_requests++;
        proc_table[req->procnum]->stats.time_elapsed += num;
        pthread_mutex_unlock(&wait_lock);
        pthread_cond_signal(&proc_table[req->procnum]->io_cond);
        XFREE(req);
    }
    printf("<-- Thread DEVICE I/O terminato\n");
    pthread_exit(NULL);
}
Example #29
0
void merge_queues(Queue * q1, Queue * q2) 
{
    Queue_element temp;

    // to avoid deadlock, this function acquires a global package
    // lock!
    pthread_mutex_lock(&global_lock);

    // lock entire queues q1, q2
    pthread_mutex_lock(&(q1->lock));
    pthread_mutex_lock(&(q2->lock));

    temp = q2->queue;

    while (temp != 0) {
        nolock_add_to_queue(q1, temp->info, temp->priority);
        temp = temp->next;
    }

    nolock_rewind_queue(q1);

    // release locks on q1, q2
    pthread_mutex_unlock(&(q2->lock));
    pthread_mutex_unlock(&(q1->lock));

    // release global package lock
    pthread_mutex_unlock(&global_lock);

}
Example #30
0
/* create thread */
void *diner(int *i)
{
    int v;
    int eating = 0;
    printf("I'm diner %d\n", *i);
    v = *i;
    while (eating < 5)
    {
        printf("%d is thinking\n", v);
        sleep(v / 2);
        printf("%d is hungry\n", v);

        pthread_mutex_lock(&grab_mutex); /* take the grab fork lock */
        while (num_eating >= EAT)
        {
            pthread_cond_wait(&eat_cond, &grab_mutex); /* wait until allowed to eat */
        }
        pthread_mutex_lock(&fork_mutex[v]); /* take left fork */
        pthread_mutex_lock(&fork_mutex[(v + 1) % NUMP]); /* take right fork */
        pthread_mutex_unlock(&grab_mutex); /* drop the grab fork lock */
        printf("%d is eating\n", v);
        num_eating++;
        eating++;
        sleep(1);
        printf("%d is done eating\n", v);
        pthread_mutex_lock(&drop_mutex); /* take the drop fork lock */
        num_eating--;
        pthread_mutex_unlock(&fork_mutex[v]); /* drop left fork */
        pthread_mutex_unlock(&fork_mutex[(v + 1) % NUMP]); /* drop right fork */
        pthread_cond_broadcast(&eat_cond); /* signal all allowed to eat */
        pthread_mutex_unlock(&drop_mutex); /* drop the drop fork lock */
    }
    pthread_exit(NULL);
}