コード例 #1
0
ファイル: thread_index.c プロジェクト: danklmn/embb
embb_counter_t* embb_thread_index_counter() {
  int compare_to = 0;
  if (embb_atomic_load_int(&embb_thread_index_counter_flag) != 2) {
    if (embb_atomic_compare_and_swap_int(
        &embb_thread_index_counter_flag, &compare_to, 1)) {
      embb_counter_init(&embb_thread_index_counter_index);
      embb_atomic_store_int(&embb_thread_index_counter_flag, 2);
    }
    while (embb_atomic_load_int(&embb_thread_index_counter_flag) != 2) {}
  }
  return &embb_thread_index_counter_index;
}
コード例 #2
0
ファイル: thread_index.c プロジェクト: danklmn/embb
unsigned int* embb_max_number_thread_indices() {
  int compare_to = 0;
  if (embb_atomic_load_int(&embb_max_number_thread_indices_flag) != 2) {
    if (embb_atomic_compare_and_swap_int(
        &embb_max_number_thread_indices_flag, &compare_to, 1)) {
      embb_max_number_thread_indices_max =
        (int)(embb_core_count_available() * 2);
      embb_atomic_store_int(&embb_max_number_thread_indices_flag, 2);
    }
    while (embb_atomic_load_int(&embb_max_number_thread_indices_flag) != 2) {}
  }
  return (unsigned int*) &embb_max_number_thread_indices_max;
}
コード例 #3
0
mtapi_boolean_t embb_mtapi_thread_context_start(
  embb_mtapi_thread_context_t* that,
  embb_mtapi_scheduler_t * scheduler) {
  int err;
  embb_mtapi_scheduler_worker_func_t * worker_func;
  embb_core_set_t core_set;

  assert(MTAPI_NULL != that);
  assert(MTAPI_NULL != scheduler);

  worker_func = embb_mtapi_scheduler_worker_func(scheduler);

  /* pin thread to core */
  embb_core_set_init(&core_set, 0);
  embb_core_set_add(&core_set, that->core_num);

  /* create thread */
  if (that->is_main_thread) {
    /* reuse main thread */
    that->thread = embb_thread_current();
    err = embb_tss_create(&that->tss_id);
    if (EMBB_SUCCESS != err) {
      /* report error to scheduler */
      embb_atomic_store_int(&that->run, -1);
      return MTAPI_FALSE;
    }
    embb_tss_set(&(that->tss_id), that);
    embb_atomic_store_int(&that->run, 1);
  } else {
    err = embb_thread_create_with_priority(
      &that->thread, &core_set, that->thread_priority, worker_func, that);
    if (EMBB_SUCCESS != err) {
      embb_mtapi_log_error(
        "embb_mtapi_ThreadContext_initializeWithNodeAndCoreNumber() could not "
        "create thread %d on core %d\n", that->worker_index, that->core_num);
      return MTAPI_FALSE;
    }
    /* wait for worker to come up */
    while (0 == embb_atomic_load_int(&that->run)) {
      embb_thread_yield();
    }
  }

  if (0 < embb_atomic_load_int(&that->run)) {
    return MTAPI_TRUE;
  } else {
    return MTAPI_FALSE;
  }
}
コード例 #4
0
ファイル: embb_mtapi_group_t.c プロジェクト: cfeld/embb
void mtapi_group_delete(
  MTAPI_IN mtapi_group_hndl_t group,
  MTAPI_OUT mtapi_status_t* status) {
  mtapi_status_t local_status = MTAPI_ERR_UNKNOWN;

  if (embb_mtapi_node_is_initialized()) {
    embb_mtapi_node_t* node = embb_mtapi_node_get_instance();
    if (embb_mtapi_group_pool_is_handle_valid(node->group_pool, group)) {
      embb_mtapi_group_t* local_group =
        embb_mtapi_group_pool_get_storage_for_handle(
          node->group_pool, group);

      if (embb_atomic_load_int(&local_group->deleted)) {
        local_status = MTAPI_ERR_GROUP_INVALID;
      } else {
        embb_mtapi_group_finalize(local_group);
        embb_mtapi_group_pool_deallocate(node->group_pool, local_group);
        local_status = MTAPI_SUCCESS;
      }
    } else {
      local_status = MTAPI_ERR_GROUP_INVALID;
    }
  } else {
    local_status = MTAPI_ERR_NODE_NOTINIT;
  }

  mtapi_status_set(status, local_status);
}
コード例 #5
0
mtapi_task_state_t mtapi_context_taskstate_get(
  MTAPI_IN mtapi_task_context_t* task_context,
  MTAPI_OUT mtapi_status_t* status) {
  mtapi_status_t local_status = MTAPI_ERR_UNKNOWN;
  mtapi_task_state_t task_state = MTAPI_TASK_ERROR;

  embb_mtapi_log_trace("mtapi_context_taskstate_get() called\n");

  if (MTAPI_NULL != task_context) {
    embb_mtapi_thread_context_t* local_context =
      (embb_mtapi_thread_context_t*)embb_tss_get(
        &(task_context->thread_context->tss_id));

    if (local_context == task_context->thread_context) {
      task_state = (mtapi_task_state_t)embb_atomic_load_int(
        &task_context->task->state);
      local_status = MTAPI_SUCCESS;
    } else {
      local_status = MTAPI_ERR_CONTEXT_OUTOFCONTEXT;
    }
  } else {
    local_status = MTAPI_ERR_CONTEXT_INVALID;
  }

  mtapi_status_set(status, local_status);
  return task_state;
}
コード例 #6
0
void embb_mtapi_thread_context_stop(embb_mtapi_thread_context_t* that) {
  int result;
  if (0 < embb_atomic_load_int(&that->run)) {
    embb_atomic_store_int(&that->run, 0);
    embb_condition_notify_one(&that->work_available);
    if (MTAPI_FALSE == that->is_main_thread) {
      embb_thread_join(&(that->thread), &result);
    }
  }
}
コード例 #7
0
ファイル: embb_mtapi_action_t.c プロジェクト: cfeld/embb
void mtapi_action_disable(
  MTAPI_IN mtapi_action_hndl_t action,
  MTAPI_IN mtapi_timeout_t timeout,
  MTAPI_OUT mtapi_status_t* status) {
  mtapi_status_t local_status = MTAPI_ERR_UNKNOWN;

  embb_mtapi_log_trace("mtapi_action_disable() called\n");

  if (embb_mtapi_node_is_initialized()) {
    embb_mtapi_node_t* node = embb_mtapi_node_get_instance();
    if (embb_mtapi_action_pool_is_handle_valid(node->action_pool, action)) {
      embb_mtapi_action_t* local_action =
        embb_mtapi_action_pool_get_storage_for_handle(
          node->action_pool, action);
      local_action->enabled = MTAPI_FALSE;

      embb_mtapi_thread_context_t * context = NULL;

      embb_duration_t wait_duration;
      embb_time_t end_time;
      if (MTAPI_INFINITE < timeout) {
        embb_duration_set_milliseconds(
          &wait_duration, (unsigned long long)timeout);
        embb_time_in(&end_time, &wait_duration);
      }

      /* cancel all tasks */
      embb_mtapi_scheduler_process_tasks(
        node->scheduler, embb_mtapi_action_disable_visitor, local_action);

      /* find out on which thread we are */
      context = embb_mtapi_scheduler_get_current_thread_context(
        node->scheduler);

      local_status = MTAPI_SUCCESS;
      while (embb_atomic_load_int(&local_action->num_tasks)) {
        if (MTAPI_INFINITE < timeout) {
          embb_time_t current_time;
          embb_time_now(&current_time);
          if (embb_time_compare(&current_time, &end_time) > 0) {
            /* timeout! */
            local_status = MTAPI_TIMEOUT;
            break;
          }
        }

        /* do other work if applicable */
        embb_mtapi_scheduler_execute_task_or_yield(
          node->scheduler,
          node,
          context);
      }
    } else {
      local_status = MTAPI_ERR_ACTION_INVALID;
    }
  } else {
    embb_mtapi_log_error("mtapi not initialized\n");
    local_status = MTAPI_ERR_NODE_NOTINIT;
  }

  mtapi_status_set(status, local_status);
}
コード例 #8
0
ファイル: embb_mtapi_group_t.c プロジェクト: Hundsbuah/embb
void mtapi_group_wait_any(
  MTAPI_IN mtapi_group_hndl_t group,
  MTAPI_OUT void** result,
  MTAPI_IN mtapi_timeout_t timeout,
  MTAPI_OUT mtapi_status_t* status) {
  mtapi_status_t local_status = MTAPI_ERR_UNKNOWN;

  embb_mtapi_log_trace("mtapi_group_wait_any() called\n");

  if (embb_mtapi_node_is_initialized()) {
    embb_mtapi_node_t* node = embb_mtapi_node_get_instance();
    if (embb_mtapi_group_pool_is_handle_valid(node->group_pool, group)) {
      embb_mtapi_group_t* local_group =
        embb_mtapi_group_pool_get_storage_for_handle(
          node->group_pool, group);

      embb_mtapi_task_t* local_task;
      /* are there any tasks left? */
      if (0 == embb_atomic_load_int(&local_group->num_tasks)) {
        /* group becomes invalid, so delete it */
        mtapi_group_delete(group, &local_status);
        local_status = MTAPI_GROUP_COMPLETED;
      } else {
        embb_mtapi_thread_context_t * context = NULL;

        embb_duration_t wait_duration;
        embb_time_t end_time;
        if (MTAPI_INFINITE < timeout) {
          embb_duration_set_milliseconds(
            &wait_duration, (unsigned long long)timeout);
          embb_time_in(&end_time, &wait_duration);
        }

        /* find out on which thread we are */
        context = embb_mtapi_scheduler_get_current_thread_context(
          node->scheduler);

        /* wait for any task to arrive */
        local_status = MTAPI_SUCCESS;
        local_task = embb_mtapi_task_queue_pop(&local_group->queue);
        while (MTAPI_NULL == local_task) {
          if (MTAPI_INFINITE < timeout) {
            embb_time_t current_time;
            embb_time_now(&current_time);
            if (embb_time_compare(&current_time, &end_time) > 0) {
              /* timeout! */
              local_status = MTAPI_TIMEOUT;
              break;
            }
          }

          /* do other work if applicable */
          embb_mtapi_scheduler_execute_task_or_yield(
            node->scheduler,
            node,
            context);

          /* try to pop a task from the group queue */
          local_task = embb_mtapi_task_queue_pop(&local_group->queue);
        }
        /* was there a timeout, or is there a result? */
        if (MTAPI_NULL != local_task) {
          /* store result */
          if (MTAPI_NULL != result) {
            *result = local_task->result_buffer;
          }

          /* return error code set by the task */
          local_status = local_task->error_code;

          /* delete task */
          embb_mtapi_task_delete(local_task, node->task_pool);
          embb_atomic_fetch_and_add_int(&local_group->num_tasks, -1);
        }
      }
    } else {
      local_status = MTAPI_ERR_GROUP_INVALID;
    }
  } else {
    embb_mtapi_log_error("mtapi not initialized\n");
    local_status = MTAPI_ERR_NODE_NOTINIT;
  }

  mtapi_status_set(status, local_status);
  embb_mtapi_log_trace("mtapi_group_wait_any() returns\n");
}