Best to serialise the restarting of threads to avoid device initialisation issues.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
diff --git a/main.c b/main.c
index 53a215d..b8ee0c1 100644
--- a/main.c
+++ b/main.c
@@ -1818,7 +1818,7 @@ retry:
}
#ifdef HAVE_OPENCL
-static void reinit_thread(long thr_id);
+static void reinit_device(struct cgpu_info *cgpu);
static void manage_gpu(void)
{
@@ -1895,12 +1895,8 @@ retry:
wlogprint("Invalid selection\n");
goto retry;
}
- for (i = 0; i < gpu_threads; i++) {
- if (dev_from_id(i) != selected)
- continue;
- wlogprint("Attempting to restart thread %d\n", i);
- reinit_thread(i);
- }
+ wlogprint("Attempting to restart threads of GPU %d\n", selected);
+ reinit_device(&gpus[selected]);
}
clear_logwin();
@@ -3101,9 +3097,12 @@ static void restart_longpoll(void)
start_longpoll();
}
-static void *reinit_cputhread(void *userdata)
+static void *reinit_cpu(void *userdata)
{
- long thr_id = (long)userdata;
+#if 0
+ struct cgpu_info *cgpu = (struct cgpu_info *)userdata;
+ int cpu = cgpu->cpu_gpu;
+ long thr_id = ....(long)userdata;
struct thr_info *thr = &thr_info[thr_id];
int cpu = dev_from_id(thr_id);
@@ -3126,67 +3125,75 @@ static void *reinit_cputhread(void *userdata)
tq_push(thr->q, &ping);
applog(LOG_WARNING, "Thread %d restarted", thr_id);
-
+#endif
return NULL;
}
#ifdef HAVE_OPENCL
-static void *reinit_gputhread(void *userdata)
+static void *reinit_gpu(void *userdata)
{
- long thr_id = (long)userdata;
- int gpu = dev_from_id(thr_id);
- struct thr_info *thr = &thr_info[thr_id];
+ struct cgpu_info *cgpu = (struct cgpu_info *)userdata;
+ int gpu = cgpu->cpu_gpu;
+ struct thr_info *thr;
char name[256];
+ int thr_id;
gpus[gpu].alive = false;
- thr->rolling = thr->cgpu->rolling = 0;
- tq_freeze(thr->q);
- if (!pthread_cancel(*thr->pth))
- pthread_join(*thr->pth, NULL);
- free(thr->q);
- thr->q = tq_new();
- if (!thr->q)
- quit(1, "Failed to tq_new in reinit_gputhread");
- free(clStates[thr_id]);
+ for (thr_id = 0; thr_id < gpu_threads; thr_id ++) {
+ if (dev_from_id(thr_id) != gpu)
+ continue;
- applog(LOG_INFO, "Reinit GPU thread %d", thr_id);
- clStates[thr_id] = initCl(gpu, name, sizeof(name));
- if (!clStates[thr_id]) {
- applog(LOG_ERR, "Failed to reinit GPU thread %d", thr_id);
- return NULL;
- }
- applog(LOG_INFO, "initCl() finished. Found %s", name);
+ thr = &thr_info[thr_id];
+ thr->rolling = thr->cgpu->rolling = 0;
+ tq_freeze(thr->q);
+ if (!pthread_cancel(*thr->pth))
+ pthread_join(*thr->pth, NULL);
+ free(thr->q);
+ thr->q = tq_new();
+ if (!thr->q)
+ quit(1, "Failed to tq_new in reinit_gputhread");
- if (unlikely(thr_info_create(thr, NULL, gpuminer_thread, thr))) {
- applog(LOG_ERR, "thread %d create failed", thr_id);
- return NULL;
- }
- /* Try to re-enable it */
- gpu_devices[gpu] = true;
- tq_push(thr->q, &ping);
+ free(clStates[thr_id]);
- applog(LOG_WARNING, "Thread %d restarted", thr_id);
+ applog(LOG_INFO, "Reinit GPU thread %d", thr_id);
+ clStates[thr_id] = initCl(gpu, name, sizeof(name));
+ if (!clStates[thr_id]) {
+ applog(LOG_ERR, "Failed to reinit GPU thread %d", thr_id);
+ return NULL;
+ }
+ applog(LOG_INFO, "initCl() finished. Found %s", name);
+
+ if (unlikely(thr_info_create(thr, NULL, gpuminer_thread, thr))) {
+ applog(LOG_ERR, "thread %d create failed", thr_id);
+ return NULL;
+ }
+ /* Try to re-enable it */
+ gpu_devices[gpu] = true;
+ tq_push(thr->q, &ping);
+
+ applog(LOG_WARNING, "Thread %d restarted", thr_id);
+ }
return NULL;
}
#else
-static void *reinit_gputhread(void *userdata)
+static void *reinit_gpu(void *userdata)
{
}
#endif
-static void reinit_thread(long thr_id)
+static void reinit_device(struct cgpu_info *cgpu)
{
pthread_t resus_thread;
void *reinit;
- if (thr_id < gpu_threads)
- reinit = reinit_gputhread;
+ if (cgpu->is_gpu)
+ reinit = reinit_gpu;
else
- reinit = reinit_cputhread;
+ reinit = reinit_cpu;
- if (unlikely(pthread_create(&resus_thread, NULL, reinit, (void *)thr_id)))
+ if (unlikely(pthread_create(&resus_thread, NULL, reinit, (void *)cgpu)))
applog(LOG_ERR, "Failed to create reinit thread");
}
@@ -3282,7 +3289,11 @@ static void *watchdog_thread(void *userdata)
kill_work();
break;
}
- reinit_thread(i);
+ reinit_device(thr->cgpu);
+ /* Only initialise the device once since there
+ * will be multiple threads on the same device
+ * and it will be declared !alive */
+ break;
}
}
}