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) @@ -85,7 +85,6 @@ static inline void affine_to_cpu(int id, int cpu)
enum workio_commands {
WC_GET_WORK,
WC_SUBMIT_WORK,
WC_DIE,
};
struct workio_cmd {
@ -2252,62 +2251,41 @@ static void print_summary(void); @@ -2252,62 +2251,41 @@ static void print_summary(void);
void kill_work(void)
{
struct workio_cmd *wc;
struct thr_info *thr;
unsigned int i;
disable_curses();
applog(LOG_INFO, "Received kill message");
if (opt_debug)
applog(LOG_DEBUG, "Killing off watchdog thread");
/* Kill the watchdog thread */
thr = &thr_info[watchdog_thr_id];
if (thr && thr->pth)
pthread_cancel(*thr->pth);
thr_info_cancel(thr);
if (opt_debug)
applog(LOG_DEBUG, "Killing off mining threads");
/* Stop the mining threads*/
for (i = 0; i < mining_threads; i++) {
thr = &thr_info[i];
if (!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);
thr_info_cancel(thr);
}
if (opt_debug)
applog(LOG_DEBUG, "Killing off stage thread");
/* Stop the others */
thr = &thr_info[stage_thr_id];
if (thr && thr->pth)
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;
thr_info_cancel(thr);
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];
if (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);
}
thr_info_cancel(thr);
}
void quit(int status, const char *format, ...);
@ -3315,7 +3293,6 @@ static void *workio_thread(void *userdata) @@ -3315,7 +3293,6 @@ static void *workio_thread(void *userdata)
case WC_SUBMIT_WORK:
ok = workio_submit_work(wc);
break;
case WC_DIE:
default:
ok = false;
break;
@ -4472,9 +4449,7 @@ static void stop_longpoll(void) @@ -4472,9 +4449,7 @@ static void stop_longpoll(void)
{
struct thr_info *thr = &thr_info[longpoll_thr_id];
tq_freeze(thr->q);
if (thr->pth)
pthread_cancel(*thr->pth);
thr_info_cancel(thr);
have_longpoll = false;
}
@ -4566,10 +4541,15 @@ select_cgpu: @@ -4566,10 +4541,15 @@ select_cgpu:
continue;
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;
/* Reports the last time we tried to revive a sick GPU */
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);
} else
applog(LOG_WARNING, "Thread %d no longer exists", thr_id);

3
miner.h

@ -236,7 +236,8 @@ struct thr_info { @@ -236,7 +236,8 @@ struct thr_info {
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)
{

27
util.c

@ -653,18 +653,37 @@ out: @@ -653,18 +653,37 @@ out:
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));
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)) {
applog(LOG_ERR, "Failed to pthread_create in thr_info_create");
free(thr->pth);
thr->pth = 0;
thr->pth = NULL;
}
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