static void
test_string_literals (gimple *stmt)
{
  gcall *call = check_for_named_call (stmt, "__emit_string_literal_range", 4);
  if (!call)
    return;

  /* We expect an ADDR_EXPR with a STRING_CST inside it for the
     initial arg.  */
  tree t_addr_string = gimple_call_arg (call, 0);
  if (TREE_CODE (t_addr_string) != ADDR_EXPR)
    {
      error_at (call->location, "string literal required for arg 1");
      return;
    }

  tree t_string = TREE_OPERAND (t_addr_string, 0);
  if (TREE_CODE (t_string) != STRING_CST)
    {
      error_at (call->location, "string literal required for arg 1");
      return;
    }

  tree t_caret_idx = gimple_call_arg (call, 1);
  if (TREE_CODE (t_caret_idx) != INTEGER_CST)
    {
      error_at (call->location, "integer constant required for arg 2");
      return;
    }
  int caret_idx = TREE_INT_CST_LOW (t_caret_idx);

  tree t_start_idx = gimple_call_arg (call, 2);
  if (TREE_CODE (t_start_idx) != INTEGER_CST)
    {
      error_at (call->location, "integer constant required for arg 3");
      return;
    }
  int start_idx = TREE_INT_CST_LOW (t_start_idx);

  tree t_end_idx = gimple_call_arg (call, 3);
  if (TREE_CODE (t_end_idx) != INTEGER_CST)
    {
      error_at (call->location, "integer constant required for arg 4");
      return;
    }
  int end_idx = TREE_INT_CST_LOW (t_end_idx);

  /* A STRING_CST doesn't have a location, but the ADDR_EXPR does.  */
  location_t strloc = EXPR_LOCATION (t_addr_string);
  location_t loc;
  substring_loc substr_loc (strloc, TREE_TYPE (t_string),
			    caret_idx, start_idx, end_idx);
  const char *err = substr_loc.get_location (&loc);
  if (err)
    error_at (strloc, "unable to read substring location: %s", err);
  else
    emit_warning (loc);
}
Exemple #2
0
int os_thread_create(
        void (*run)(void *arg), void *arg,
        bool high_priority,
        struct OsThread ** out_thread)
{
    *out_thread = NULL;

    struct OsThread *thread = allocate_zero<OsThread>(1);
    if (!thread) {
        os_thread_destroy(thread);
        return GenesisErrorNoMem;
    }

    thread->run = run;
    thread->arg = arg;

#if defined(GENESIS_OS_WINDOWS)
    thread->handle = CreateThread(NULL, 0, run_win32_thread, thread, 0, &thread->id);
    if (!thread->handle) {
        os_thread_destroy(thread);
        return GenesisErrorSystemResources;
    }
    if (high_priority) {
        if (!SetThreadPriority(thread->handle, THREAD_PRIORITY_TIME_CRITICAL)) {
            emit_warning(WarningHighPriorityThread);
        }
    }
#else
    int err;
    if ((err = pthread_attr_init(&thread->attr))) {
        os_thread_destroy(thread);
        return GenesisErrorNoMem;
    }
    thread->attr_init = true;
    
    if (high_priority) {
        int max_priority = sched_get_priority_max(SCHED_FIFO);
        if (max_priority == -1) {
            os_thread_destroy(thread);
            return GenesisErrorSystemResources;
        }

        if ((err = pthread_attr_setschedpolicy(&thread->attr, SCHED_FIFO))) {
            os_thread_destroy(thread);
            return GenesisErrorSystemResources;
        }

        struct sched_param param;
        param.sched_priority = max_priority;
        if ((err = pthread_attr_setschedparam(&thread->attr, &param))) {
            os_thread_destroy(thread);
            return GenesisErrorSystemResources;
        }
    }

    if ((err = pthread_create(&thread->id, &thread->attr, run_pthread, thread))) {
        if (err == EPERM && high_priority) {
            emit_warning(WarningHighPriorityThread);
            err = pthread_create(&thread->id, NULL, run_pthread, thread);
        }
        if (err) {
            os_thread_destroy(thread);
            return GenesisErrorNoMem;
        }
    }
    thread->running = true;
#endif

    *out_thread = thread;
    return 0;
}