diff --git a/cgminer.c b/cgminer.c index d0077190..78b7d00e 100644 --- a/cgminer.c +++ b/cgminer.c @@ -6251,6 +6251,30 @@ void __work_completed(struct cgpu_info *cgpu, struct work *work) cgpu->queued_count--; HASH_DEL(cgpu->queued_work, work); } + +/* This iterates over a queued hashlist finding work started more than secs + * seconds ago and discards the work as completed. The driver must set the + * work->tv_work_start value appropriately. Returns the number of items aged. */ +int age_queued_work(struct cgpu_info *cgpu, double secs) +{ + struct work *work, *tmp; + struct timeval tv_now; + int aged = 0; + + cgtime(&tv_now); + + wr_lock(&cgpu->qlock); + HASH_ITER(hh, cgpu->queued_work, work, tmp) { + if (tdiff(&tv_now, &work->tv_work_start) > secs) { + __work_completed(cgpu, work); + aged++; + } + } + wr_unlock(&cgpu->qlock); + + return aged; +} + /* This function should be used by queued device drivers when they're sure * the work struct is no longer in use. */ void work_completed(struct cgpu_info *cgpu, struct work *work) diff --git a/miner.h b/miner.h index 60c97cde..04be7d04 100644 --- a/miner.h +++ b/miner.h @@ -1368,6 +1368,7 @@ extern struct work *__find_work_bymidstate(struct work *que, char *midstate, siz extern struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen); extern struct work *clone_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen); extern void __work_completed(struct cgpu_info *cgpu, struct work *work); +extern int age_queued_work(struct cgpu_info *cgpu, double secs); extern void work_completed(struct cgpu_info *cgpu, struct work *work); extern struct work *take_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen); extern void hash_driver_work(struct thr_info *mythr);