K_STORE *_k_free_store(K_STORE *store, KLIST_FFL_ARGS) { _CHKLIST(store, "store"); if (!(store->is_store)) { quithere(1, "Store %s can't %s() the list" KLIST_FFL, store->name, __func__, KLIST_FFL_PASS); } if (store->master->lock == NULL) store->master->stores--; else { K_WLOCK(store->master); // unlink store from the list if (store->prev_store) store->prev_store->next_store = store->next_store; if (store->next_store) store->next_store->prev_store = store->prev_store; // correct the head if we are the head if (store->master->next_store == store) store->master->next_store = store->next_store; store->master->stores--; K_WUNLOCK(store->master); } free(store); return NULL; }
K_STORE *_k_new_store(K_LIST *list, bool gotlock, KLIST_FFL_ARGS) { K_STORE *store; CHKLIST(list); store = calloc(1, sizeof(*store)); if (!store) quithere(1, "Failed to calloc store for %s", list->name); store->master = list; store->is_store = true; store->lock = NULL; store->name = list->name; store->do_tail = list->do_tail; store->prev_store = NULL; // Only tracked for lists with a lock if (store->master->lock == NULL) { store->next_store = NULL; store->master->stores++; } else { if (!gotlock) K_WLOCK(list); // In the master list, next is the head if (list->next_store) list->next_store->prev_store = store; store->next_store = list->next_store; list->next_store = store; list->stores++; if (!gotlock) K_WUNLOCK(list); } return store; }
bool isdupnonce(struct cgpu_info *cgpu, struct work *work, uint32_t nonce) { struct dupdata *dup = (struct dupdata *)(cgpu->dup_data); struct timeval now; bool unique = true; K_ITEM *item; if (!dup) return false; cgtime(&now); dup->checked++; K_WLOCK(dup->nfree_list); item = dup->nonce_list->tail; while (unique && item) { if (DATAN(item)->work_id == work->id && DATAN(item)->nonce == nonce) { unique = false; applog(LOG_WARNING, "%s%d: Duplicate nonce %08x", cgpu->drv->name, cgpu->device_id, nonce); } else item = item->prev; } if (unique) { item = k_unlink_head(dup->nfree_list); DATAN(item)->work_id = work->id; DATAN(item)->nonce = nonce; memcpy(&(DATAN(item)->when), &now, sizeof(now)); k_add_head(dup->nonce_list, item); } item = dup->nonce_list->tail; while (item && tdiff(&(DATAN(item)->when), &now) > dup->timelimit) { item = k_unlink_tail(dup->nonce_list); k_add_head(dup->nfree_list, item); item = dup->nonce_list->tail; } K_WUNLOCK(dup->nfree_list); if (!unique) dup->dup++; return !unique; }