Browse Source

Standardise the way all non-mining threads are destroyed to make sure we can safely cancel them, freeing ram and NULLifying pointers.

nfactor-troky
Con Kolivas 13 years ago
parent
commit
833e020dfd
  1. 64
      main.c
  2. 3
      miner.h
  3. 27
      util.c

64
main.c

@ -85,7 +85,6 @@ static inline void affine_to_cpu(int id, int cpu)
enum workio_commands { enum workio_commands {
WC_GET_WORK, WC_GET_WORK,
WC_SUBMIT_WORK, WC_SUBMIT_WORK,
WC_DIE,
}; };
struct workio_cmd { struct workio_cmd {
@ -2252,62 +2251,41 @@ static void print_summary(void);
void kill_work(void) void kill_work(void)
{ {
struct workio_cmd *wc;
struct thr_info *thr; struct thr_info *thr;
unsigned int i; unsigned int i;
disable_curses(); disable_curses();
applog(LOG_INFO, "Received kill message"); applog(LOG_INFO, "Received kill message");
if (opt_debug)
applog(LOG_DEBUG, "Killing off watchdog thread");
/* Kill the watchdog thread */ /* Kill the watchdog thread */
thr = &thr_info[watchdog_thr_id]; thr = &thr_info[watchdog_thr_id];
if (thr && thr->pth) thr_info_cancel(thr);
pthread_cancel(*thr->pth);
if (opt_debug)
applog(LOG_DEBUG, "Killing off mining threads");
/* Stop the mining threads*/ /* Stop the mining threads*/
for (i = 0; i < mining_threads; i++) { for (i = 0; i < mining_threads; i++) {
thr = &thr_info[i]; thr = &thr_info[i];
if (!thr) thr_info_cancel(thr);
continue;
if (!thr->pth)
continue;
if (thr->q)
tq_freeze(thr->q);
/* No need to check if this succeeds or not */
pthread_cancel(*thr->pth);
} }
if (opt_debug)
applog(LOG_DEBUG, "Killing off stage thread");
/* Stop the others */ /* Stop the others */
thr = &thr_info[stage_thr_id]; thr = &thr_info[stage_thr_id];
if (thr && thr->pth) thr_info_cancel(thr);
pthread_cancel(*thr->pth);
thr = &thr_info[longpoll_thr_id];
if (thr && thr->pth)
pthread_cancel(*thr->pth);
wc = calloc(1, sizeof(*wc));
if (unlikely(!wc)) {
applog(LOG_ERR, "Failed to calloc wc in kill_work");
/* We're just trying to die anyway, so forget graceful */
exit (1);
}
wc->cmd = WC_DIE;
wc->thr = 0;
if (opt_debug) if (opt_debug)
applog(LOG_DEBUG, "Pushing die request to work thread"); applog(LOG_DEBUG, "Killing off longpoll thread");
thr = &thr_info[longpoll_thr_id];
thr_info_cancel(thr);
if (opt_debug)
applog(LOG_DEBUG, "Killing off work thread");
thr = &thr_info[work_thr_id]; thr = &thr_info[work_thr_id];
if (thr) { thr_info_cancel(thr);
if (unlikely(!tq_push(thr->q, wc))) {
applog(LOG_ERR, "Failed to tq_push work in kill_work");
exit (1);
}
if (thr->pth)
pthread_cancel(*thr->pth);
}
} }
void quit(int status, const char *format, ...); void quit(int status, const char *format, ...);
@ -3315,7 +3293,6 @@ static void *workio_thread(void *userdata)
case WC_SUBMIT_WORK: case WC_SUBMIT_WORK:
ok = workio_submit_work(wc); ok = workio_submit_work(wc);
break; break;
case WC_DIE:
default: default:
ok = false; ok = false;
break; break;
@ -4472,9 +4449,7 @@ static void stop_longpoll(void)
{ {
struct thr_info *thr = &thr_info[longpoll_thr_id]; struct thr_info *thr = &thr_info[longpoll_thr_id];
tq_freeze(thr->q); thr_info_cancel(thr);
if (thr->pth)
pthread_cancel(*thr->pth);
have_longpoll = false; have_longpoll = false;
} }
@ -4566,10 +4541,15 @@ select_cgpu:
continue; continue;
thr = &thr_info[thr_id]; thr = &thr_info[thr_id];
if (!thr) {
applog(LOG_WARNING, "No reference to thread %d exists", thr_id);
continue;
}
thr->rolling = thr->cgpu->rolling = 0; thr->rolling = thr->cgpu->rolling = 0;
/* Reports the last time we tried to revive a sick GPU */ /* Reports the last time we tried to revive a sick GPU */
gettimeofday(&thr->sick, NULL); gettimeofday(&thr->sick, NULL);
if (!pthread_cancel(*thr->pth)) { if (thr->pth && !pthread_cancel(*thr->pth)) {
applog(LOG_WARNING, "Thread %d still exists, killing it off", thr_id); applog(LOG_WARNING, "Thread %d still exists, killing it off", thr_id);
} else } else
applog(LOG_WARNING, "Thread %d no longer exists", thr_id); applog(LOG_WARNING, "Thread %d no longer exists", thr_id);

3
miner.h

@ -236,7 +236,8 @@ struct thr_info {
double rolling; double rolling;
}; };
extern inline int thr_info_create(struct thr_info *thr, pthread_attr_t *attr, void *(*start) (void *), void *arg); extern int thr_info_create(struct thr_info *thr, pthread_attr_t *attr, void *(*start) (void *), void *arg);
extern void thr_info_cancel(struct thr_info *thr);
static inline uint32_t swab32(uint32_t v) static inline uint32_t swab32(uint32_t v)
{ {

27
util.c

@ -653,18 +653,37 @@ out:
return rval; return rval;
} }
inline int thr_info_create(struct thr_info *thr, pthread_attr_t *attr, void *(*start) (void *), void *arg) int thr_info_create(struct thr_info *thr, pthread_attr_t *attr, void *(*start) (void *), void *arg)
{ {
int ret = 0; int ret = -1;
thr->pth = malloc(sizeof(pthread_t)); thr->pth = malloc(sizeof(pthread_t));
ret = pthread_create(thr->pth, attr, start, arg); if (unlikely(!thr->pth)) {
applog(LOG_ERR, "Failed to malloc in thr_info_create");
return ret;
}
ret = pthread_create(thr->pth, attr, start, arg);
if (unlikely(ret)) { if (unlikely(ret)) {
applog(LOG_ERR, "Failed to pthread_create in thr_info_create");
free(thr->pth); free(thr->pth);
thr->pth = 0; thr->pth = NULL;
} }
return ret; return ret;
} }
void thr_info_cancel(struct thr_info *thr)
{
if (!thr)
return;
if (thr->q)
tq_freeze(thr->q);
if (thr->pth) {
if (pthread_cancel(*thr->pth))
pthread_join(*thr->pth, NULL);
free(thr->pth);
thr->pth = NULL;
}
}

Loading…
Cancel
Save