comm.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include "comm.h"
  2. #include "util.h"
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. struct comm_str {
  6. char *str;
  7. struct rb_node rb_node;
  8. int ref;
  9. };
  10. /* Should perhaps be moved to struct machine */
  11. static struct rb_root comm_str_root;
  12. static void comm_str__get(struct comm_str *cs)
  13. {
  14. cs->ref++;
  15. }
  16. static void comm_str__put(struct comm_str *cs)
  17. {
  18. if (!--cs->ref) {
  19. rb_erase(&cs->rb_node, &comm_str_root);
  20. free(cs->str);
  21. free(cs);
  22. }
  23. }
  24. static struct comm_str *comm_str__alloc(const char *str)
  25. {
  26. struct comm_str *cs;
  27. cs = zalloc(sizeof(*cs));
  28. if (!cs)
  29. return NULL;
  30. cs->str = strdup(str);
  31. if (!cs->str) {
  32. free(cs);
  33. return NULL;
  34. }
  35. return cs;
  36. }
  37. static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root)
  38. {
  39. struct rb_node **p = &root->rb_node;
  40. struct rb_node *parent = NULL;
  41. struct comm_str *iter, *new;
  42. int cmp;
  43. while (*p != NULL) {
  44. parent = *p;
  45. iter = rb_entry(parent, struct comm_str, rb_node);
  46. cmp = strcmp(str, iter->str);
  47. if (!cmp)
  48. return iter;
  49. if (cmp < 0)
  50. p = &(*p)->rb_left;
  51. else
  52. p = &(*p)->rb_right;
  53. }
  54. new = comm_str__alloc(str);
  55. if (!new)
  56. return NULL;
  57. rb_link_node(&new->rb_node, parent, p);
  58. rb_insert_color(&new->rb_node, root);
  59. return new;
  60. }
  61. struct comm *comm__new(const char *str, u64 timestamp)
  62. {
  63. struct comm *comm = zalloc(sizeof(*comm));
  64. if (!comm)
  65. return NULL;
  66. comm->start = timestamp;
  67. comm->comm_str = comm_str__findnew(str, &comm_str_root);
  68. if (!comm->comm_str) {
  69. free(comm);
  70. return NULL;
  71. }
  72. comm_str__get(comm->comm_str);
  73. return comm;
  74. }
  75. void comm__override(struct comm *comm, const char *str, u64 timestamp)
  76. {
  77. struct comm_str *old = comm->comm_str;
  78. comm->comm_str = comm_str__findnew(str, &comm_str_root);
  79. if (!comm->comm_str) {
  80. comm->comm_str = old;
  81. return;
  82. }
  83. comm->start = timestamp;
  84. comm_str__get(comm->comm_str);
  85. comm_str__put(old);
  86. }
  87. void comm__free(struct comm *comm)
  88. {
  89. comm_str__put(comm->comm_str);
  90. free(comm);
  91. }
  92. const char *comm__str(const struct comm *comm)
  93. {
  94. return comm->comm_str->str;
  95. }