Пример #1
0
static void last_nettime(struct timeval2 *last)
{
	rd_lock(&netacc_lock);
	last->tv_sec = nettime.tv_sec;
	last->tv_usec = nettime.tv_usec;
	rd_unlock(&netacc_lock);
}
Пример #2
0
/* In dynamic mode, only the first thread of each device will be in use.
 * This potentially could start a thread that was stopped with the start-stop
 * options if one were to disable dynamic from the menu on a paused GPU */
void pause_dynamic_threads(int gpu)
{
  struct cgpu_info *cgpu = &gpus[gpu];
  int i;

  rd_lock(&mining_thr_lock);
  for (i = 1; i < cgpu->threads; i++) {
    struct thr_info *thr;

    thr = cgpu->thr[i];
    if (!thr->pause && cgpu->dynamic) {
      applog(LOG_WARNING, "Disabling extra threads due to dynamic mode.");
      applog(LOG_WARNING, "Tune dynamic intensity with --gpu-dyninterval");
    }

    thr->pause = cgpu->dynamic;
    if (!cgpu->dynamic && cgpu->deven != DEV_DISABLED)
      cgsem_post(&thr->sem);
  }
  rd_unlock(&mining_thr_lock);
}
Пример #3
0
void manage_gpu(void)
{
  struct thr_info *thr;
  int selected, gpu, i;
  char checkin[40];
  char input;

  if (!opt_g_threads) {
    applog(LOG_ERR, "opt_g_threads not set in manage_gpu()");
    return;
  }

  opt_loginput = true;
  immedok(logwin, true);
  clear_logwin();
retry: // TODO: refactor

  for (gpu = 0; gpu < nDevs; gpu++) {
    struct cgpu_info *cgpu = &gpus[gpu];
    double displayed_rolling, displayed_total;
    bool mhash_base = true;

    displayed_rolling = cgpu->rolling;
    displayed_total = cgpu->total_mhashes / total_secs;
    if (displayed_rolling < 1) {
      displayed_rolling *= 1000;
      displayed_total *= 1000;
      mhash_base = false;
    }

    wlog("GPU %d: %.1f / %.1f %sh/s | A:%d  R:%d  HW:%d  U:%.2f/m  I:%d  xI:%d  rI:%d\n",
      gpu, displayed_rolling, displayed_total, mhash_base ? "M" : "K",
      cgpu->accepted, cgpu->rejected, cgpu->hw_errors,
      cgpu->utility, cgpu->intensity, cgpu->xintensity, cgpu->rawintensity);
#ifdef HAVE_ADL
    if (gpus[gpu].has_adl) {
      int engineclock = 0, memclock = 0, activity = 0, fanspeed = 0, fanpercent = 0, powertune = 0;
      float temp = 0, vddc = 0;

      if (gpu_stats(gpu, &temp, &engineclock, &memclock, &vddc, &activity, &fanspeed, &fanpercent, &powertune)) {
        char logline[255];

        strcpy(logline, ""); // In case it has no data
        if (temp != -1)
          sprintf(logline, "%.1f C  ", temp);
        if (fanspeed != -1 || fanpercent != -1) {
          tailsprintf(logline, sizeof(logline), "F: ");
          if (fanpercent != -1)
            tailsprintf(logline, sizeof(logline), "%d%% ", fanpercent);
          if (fanspeed != -1)
            tailsprintf(logline, sizeof(logline), "(%d RPM) ", fanspeed);
          tailsprintf(logline, sizeof(logline), " ");
        }
        if (engineclock != -1)
          tailsprintf(logline, sizeof(logline), "E: %d MHz  ", engineclock);
        if (memclock != -1)
          tailsprintf(logline, sizeof(logline), "M: %d Mhz  ", memclock);
        if (vddc != -1)
          tailsprintf(logline, sizeof(logline), "V: %.3fV  ", vddc);
        if (activity != -1)
          tailsprintf(logline, sizeof(logline), "A: %d%%  ", activity);
        if (powertune != -1)
          tailsprintf(logline, sizeof(logline), "P: %d%%", powertune);
        tailsprintf(logline, sizeof(logline), "\n");
        _wlog(logline);
      }
    }
#endif
    wlog("Last initialised: %s\n", cgpu->init);

    rd_lock(&mining_thr_lock);
    for (i = 0; i < mining_threads; i++) {
      thr = mining_thr[i];
      if (thr->cgpu != cgpu)
        continue;
      get_datestamp(checkin, sizeof(checkin), &thr->last);
      displayed_rolling = thr->rolling;
      if (!mhash_base)
        displayed_rolling *= 1000;
      wlog("Thread %d: %.1f %sh/s %s ", i, displayed_rolling, mhash_base ? "M" : "K" , cgpu->deven != DEV_DISABLED ? "Enabled" : "Disabled");
      switch (cgpu->status) {
        default:
        case LIFE_WELL:
          wlog("ALIVE");
          break;
        case LIFE_SICK:
          wlog("SICK reported in %s", checkin);
          break;
        case LIFE_DEAD:
          wlog("DEAD reported in %s", checkin);
          break;
        case LIFE_INIT:
        case LIFE_NOSTART:
          wlog("Never started");
          break;
      }
      if (thr->pause)
        wlog(" paused");
      wlog("\n");
    }
    rd_unlock(&mining_thr_lock);

    wlog("\n");
  }

  wlogprint("[E]nable  [D]isable  [R]estart GPU  %s\n",adl_active ? "[C]hange settings" : "");
  wlogprint("[I]ntensity  E[x]perimental intensity  R[a]w Intensity\n");

  wlogprint("Or press any other key to continue\n");
  logwin_update();
  input = getch();

  if (nDevs == 1)
    selected = 0;
  else
    selected = -1;
  if (!strncasecmp(&input, "e", 1)) {
    struct cgpu_info *cgpu;

    if (selected)
      selected = curses_int("Select GPU to enable");
    if (selected < 0 || selected >= nDevs) {
      wlogprint("Invalid selection\n");
      goto retry;
    }
    if (gpus[selected].deven != DEV_DISABLED) {
      wlogprint("Device already enabled\n");
      goto retry;
    }
    gpus[selected].deven = DEV_ENABLED;
    rd_lock(&mining_thr_lock);
    for (i = 0; i < mining_threads; ++i) {
      thr = mining_thr[i];
      cgpu = thr->cgpu;
      if (cgpu->drv->drv_id != DRIVER_opencl)
        continue;
      if (dev_from_id(i) != selected)
        continue;
      if (cgpu->status != LIFE_WELL) {
        wlogprint("Must restart device before enabling it");
        goto retry;
      }
      applog(LOG_DEBUG, "Pushing sem post to thread %d", thr->id);

      cgsem_post(&thr->sem);
    }
    rd_unlock(&mining_thr_lock);
    goto retry;
  } else if (!strncasecmp(&input, "d", 1)) {
    if (selected)
      selected = curses_int("Select GPU to disable");
    if (selected < 0 || selected >= nDevs) {
      wlogprint("Invalid selection\n");
      goto retry;
    }
    if (gpus[selected].deven == DEV_DISABLED) {
      wlogprint("Device already disabled\n");
      goto retry;
    }
    gpus[selected].deven = DEV_DISABLED;
    goto retry;
  } else if (!strncasecmp(&input, "i", 1)) {
    int intensity;
    char *intvar;

    if (selected)
      selected = curses_int("Select GPU to change intensity on");
    if (selected < 0 || selected >= nDevs) {
      wlogprint("Invalid selection\n");
      goto retry;
    }

    intvar = curses_input("Set GPU scan intensity (d or "
                MIN_INTENSITY_STR " -> "
                MAX_INTENSITY_STR ")");
    if (!intvar) {
      wlogprint("Invalid input\n");
      goto retry;
    }
    if (!strncasecmp(intvar, "d", 1)) {
      wlogprint("Dynamic mode enabled on gpu %d\n", selected);
      gpus[selected].dynamic = true;
      pause_dynamic_threads(selected);
      free(intvar);
      goto retry;
    }
    intensity = atoi(intvar);
    free(intvar);
    if (intensity < MIN_INTENSITY || intensity > MAX_INTENSITY) {
      wlogprint("Invalid selection\n");
      goto retry;
    }
    gpus[selected].dynamic = false;
    gpus[selected].intensity = intensity;
    gpus[selected].xintensity = 0; // Disable xintensity when enabling intensity
    gpus[selected].rawintensity = 0; // Disable raw intensity when enabling intensity
    wlogprint("Intensity on gpu %d set to %d\n", selected, intensity);
    pause_dynamic_threads(selected);
    goto retry;
  } else if (!strncasecmp(&input, "x", 1)) {
    int xintensity;
    char *intvar;

    if (selected)
      selected = curses_int("Select GPU to change experimental intensity on");
    if (selected < 0 || selected >= nDevs) {
      wlogprint("Invalid selection\n");
      goto retry;
    }

    intvar = curses_input("Set experimental GPU scan intensity (" MIN_XINTENSITY_STR " -> " MAX_XINTENSITY_STR ")");
    if (!intvar) {
      wlogprint("Invalid input\n");
      goto retry;
    }
    xintensity = atoi(intvar);
    free(intvar);
    if (xintensity < MIN_XINTENSITY || xintensity > MAX_XINTENSITY) {
      wlogprint("Invalid selection\n");
      goto retry;
    }
    gpus[selected].dynamic = false;
    gpus[selected].intensity = 0; // Disable intensity when enabling xintensity
    gpus[selected].rawintensity = 0; // Disable raw intensity when enabling xintensity
    gpus[selected].xintensity = xintensity;
    wlogprint("Experimental intensity on gpu %d set to %d\n", selected, xintensity);
    pause_dynamic_threads(selected);
    goto retry;
  } else if (!strncasecmp(&input, "a", 1)) {
    int rawintensity;
    char *intvar;

    if (selected)
      selected = curses_int("Select GPU to change raw intensity on");
    if (selected < 0 || selected >= nDevs) {
      wlogprint("Invalid selection\n");
      goto retry;
    }

    intvar = curses_input("Set raw GPU scan intensity (" MIN_RAWINTENSITY_STR " -> " MAX_RAWINTENSITY_STR ")");
    if (!intvar) {
      wlogprint("Invalid input\n");
      goto retry;
    }
    rawintensity = atoi(intvar);
    free(intvar);
    if (rawintensity < MIN_RAWINTENSITY || rawintensity > MAX_RAWINTENSITY) {
      wlogprint("Invalid selection\n");
      goto retry;
    }
    gpus[selected].dynamic = false;
    gpus[selected].intensity = 0; // Disable intensity when enabling raw intensity
    gpus[selected].xintensity = 0; // Disable xintensity when enabling raw intensity
    gpus[selected].rawintensity = rawintensity;
    wlogprint("Raw intensity on gpu %d set to %d\n", selected, rawintensity);
    pause_dynamic_threads(selected);
    goto retry;
  } else if (!strncasecmp(&input, "r", 1)) {
    if (selected)
      selected = curses_int("Select GPU to attempt to restart");
    if (selected < 0 || selected >= nDevs) {
      wlogprint("Invalid selection\n");
      goto retry;
    }
    wlogprint("Attempting to restart threads of GPU %d\n", selected);
    reinit_device(&gpus[selected]);
    goto retry;
  } else if (adl_active && (!strncasecmp(&input, "c", 1))) {
    if (selected)
      selected = curses_int("Select GPU to change settings on");
    if (selected < 0 || selected >= nDevs) {
      wlogprint("Invalid selection\n");
      goto retry;
    }
    change_gpusettings(selected);
    goto retry;
  } else
    clear_logwin();

  immedok(logwin, false);
  opt_loginput = false;
}
Пример #4
0
/* We have only one thread that ever re-initialises GPUs, thus if any GPU
 * init command fails due to a completely wedged GPU, the thread will never
 * return, unable to harm other GPUs. If it does return, it means we only had
 * a soft failure and then the reinit_gpu thread is ready to tackle another
 * GPU */
void *reinit_gpu(void *userdata)
{
  struct thr_info *mythr = (struct thr_info *)userdata;
  struct cgpu_info *cgpu;
  struct thr_info *thr;
  struct timeval now;
  char name[256];
  int thr_id;
  int gpu;

  pthread_detach(pthread_self());

select_cgpu:
  cgpu = (struct cgpu_info *)tq_pop(mythr->q, NULL);
  if (!cgpu)
    goto out;

  if (clDevicesNum() != nDevs) {
    applog(LOG_WARNING, "Hardware not reporting same number of active devices, will not attempt to restart GPU");
    goto out;
  }

  gpu = cgpu->device_id;

  rd_lock(&mining_thr_lock);
  for (thr_id = 0; thr_id < mining_threads; ++thr_id) {
    thr = mining_thr[thr_id];
    cgpu = thr->cgpu;
    if (cgpu->drv->drv_id != DRIVER_opencl)
      continue;
    if (dev_from_id(thr_id) != gpu)
      continue;

    thr->rolling = thr->cgpu->rolling = 0;
    /* Reports the last time we tried to revive a sick GPU */
    cgtime(&thr->sick);
    if (!pthread_kill(thr->pth, 0)) {
      applog(LOG_WARNING, "Thread %d still exists, killing it off", thr_id);
      cg_completion_timeout(&thr_info_cancel_join, thr, 5000);
      thr->cgpu->drv->thread_shutdown(thr);
    } else
      applog(LOG_WARNING, "Thread %d no longer exists", thr_id);
  }
  rd_unlock(&mining_thr_lock);

  rd_lock(&mining_thr_lock);
  for (thr_id = 0; thr_id < mining_threads; ++thr_id) {
    int virtual_gpu;

    thr = mining_thr[thr_id];
    cgpu = thr->cgpu;
    if (cgpu->drv->drv_id != DRIVER_opencl)
      continue;
    if (dev_from_id(thr_id) != gpu)
      continue;

    virtual_gpu = cgpu->virtual_gpu;
    /* Lose this ram cause we may get stuck here! */
    //tq_freeze(thr->q);

    thr->q = tq_new();
    if (!thr->q)
      quit(1, "Failed to tq_new in reinit_gpu");

    /* Lose this ram cause we may dereference in the dying thread! */
    //free(clState);

    applog(LOG_INFO, "Reinit GPU thread %d", thr_id);
    clStates[thr_id] = initCl(virtual_gpu, name, sizeof(name), &cgpu->algorithm);
    if (!clStates[thr_id]) {
      applog(LOG_ERR, "Failed to reinit GPU thread %d", thr_id);
      goto select_cgpu;
    }
    applog(LOG_INFO, "initCl() finished. Found %s", name);

    if (unlikely(thr_info_create(thr, NULL, miner_thread, thr))) {
      applog(LOG_ERR, "thread %d create failed", thr_id);
      return NULL;
    }
    applog(LOG_WARNING, "Thread %d restarted", thr_id);
  }
  rd_unlock(&mining_thr_lock);

  cgtime(&now);
  get_datestamp(cgpu->init, sizeof(cgpu->init), &now);

  rd_lock(&mining_thr_lock);
  for (thr_id = 0; thr_id < mining_threads; ++thr_id) {
    thr = mining_thr[thr_id];
    cgpu = thr->cgpu;
    if (cgpu->drv->drv_id != DRIVER_opencl)
      continue;
    if (dev_from_id(thr_id) != gpu)
      continue;

    cgsem_post(&thr->sem);
  }
  rd_unlock(&mining_thr_lock);

  goto select_cgpu;
out:
  return NULL;
}