noncedup.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /*
  2. * Copyright 2014 Andrew Smith
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License as published by the Free
  6. * Software Foundation; either version 3 of the License, or (at your option)
  7. * any later version. See COPYING for more details.
  8. */
  9. #include "miner.h"
  10. #include "klist.h"
  11. // Nonce
  12. typedef struct nitem {
  13. uint32_t work_id;
  14. uint32_t nonce;
  15. struct timeval when;
  16. } NITEM;
  17. #define DATAN(_item) ((NITEM *)(_item->data))
  18. struct dupdata {
  19. int timelimit;
  20. K_LIST *nfree_list;
  21. K_STORE *nonce_list;
  22. uint64_t checked;
  23. uint64_t dups;
  24. };
  25. void dupalloc(struct cgpu_info *cgpu, int timelimit)
  26. {
  27. struct dupdata *dup;
  28. dup = calloc(1, sizeof(*dup));
  29. if (unlikely(!dup))
  30. quithere(1, "Failed to calloc dupdata");
  31. dup->timelimit = timelimit;
  32. dup->nfree_list = k_new_list("Nonces", sizeof(NITEM), 1024, 0, true);
  33. dup->nonce_list = k_new_store(dup->nfree_list);
  34. cgpu->dup_data = dup;
  35. }
  36. void dupcounters(struct cgpu_info *cgpu, uint64_t *checked, uint64_t *dups)
  37. {
  38. struct dupdata *dup = (struct dupdata *)(cgpu->dup_data);
  39. if (!dup) {
  40. *checked = 0;
  41. *dups = 0;
  42. } else {
  43. *checked = dup->checked;
  44. *dups = dup->dups;
  45. }
  46. }
  47. bool isdupnonce(struct cgpu_info *cgpu, struct work *work, uint32_t nonce)
  48. {
  49. struct dupdata *dup = (struct dupdata *)(cgpu->dup_data);
  50. struct timeval now;
  51. bool unique = true;
  52. K_ITEM *item;
  53. if (!dup)
  54. return false;
  55. cgtime(&now);
  56. dup->checked++;
  57. K_WLOCK(dup->nfree_list);
  58. item = dup->nonce_list->tail;
  59. while (unique && item) {
  60. if (DATAN(item)->work_id == work->id && DATAN(item)->nonce == nonce) {
  61. unique = false;
  62. applog(LOG_WARNING, "%s%d: Duplicate nonce %08x",
  63. cgpu->drv->name, cgpu->device_id, nonce);
  64. } else
  65. item = item->prev;
  66. }
  67. if (unique) {
  68. item = k_unlink_head(dup->nfree_list);
  69. DATAN(item)->work_id = work->id;
  70. DATAN(item)->nonce = nonce;
  71. memcpy(&(DATAN(item)->when), &now, sizeof(now));
  72. k_add_head(dup->nonce_list, item);
  73. }
  74. item = dup->nonce_list->tail;
  75. while (item && tdiff(&(DATAN(item)->when), &now) > dup->timelimit) {
  76. item = k_unlink_tail(dup->nonce_list);
  77. k_add_head(dup->nfree_list, item);
  78. item = dup->nonce_list->tail;
  79. }
  80. K_WUNLOCK(dup->nfree_list);
  81. if (!unique)
  82. dup->dups++;
  83. return !unique;
  84. }