LabelSplicer.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #ifndef LabelSplicer_H
  16. #define LabelSplicer_H
  17. #include "switch/NumberCompress.h"
  18. #include "util/Bits.h"
  19. #include <stdint.h>
  20. #include <stdbool.h>
  21. /**
  22. * Convert a full path (represention we can use) to a representaiton which a node
  23. * along that path can use.
  24. *
  25. * @param fullPath the full route to the destination
  26. * @param midPath a path to a node which falls somewhere within fullPath
  27. * @return a version of fullPath which is sutible for use by node at midPath
  28. */
  29. static inline uint64_t LabelSplicer_unsplice(uint64_t fullPath, uint64_t midPath)
  30. {
  31. return fullPath >> Bits_log2x64(midPath);
  32. }
  33. /**
  34. * Splice a label and a label fragment together.
  35. *
  36. */
  37. static inline uint64_t LabelSplicer_splice(uint64_t goHere, uint64_t viaHere)
  38. {
  39. uint64_t log2ViaHere = Bits_log2x64(viaHere);
  40. if (Bits_log2x64(goHere) + log2ViaHere > 59) {
  41. // Too big, can't splice.
  42. return UINT64_MAX;
  43. }
  44. return ((goHere ^ 1) << log2ViaHere) ^ viaHere;
  45. }
  46. /**
  47. * Get the label for a particular destination from a given source.
  48. * This needs to be called before handing out a label because if a source interface is
  49. * represented using more bits than the destination interface, the destination interface
  50. * must be padded out so that the switch will find the source and destination labels compatable.
  51. *
  52. * @param target the label for the location to send to in host byte order.
  53. * @param whoIsAsking the label for the node which we are sending the target to in host byte order.
  54. * @return the modified target for that node in host byte order.
  55. */
  56. static inline uint64_t LabelSplicer_getLabelFor(uint64_t target, uint64_t whoIsAsking)
  57. {
  58. uint32_t targetBits = NumberCompress_bitsUsedForLabel(target);
  59. uint32_t whoIsAskingBits = NumberCompress_bitsUsedForLabel(whoIsAsking);
  60. if (targetBits >= whoIsAskingBits) {
  61. return target;
  62. }
  63. uint32_t targetIfaceNum = NumberCompress_getDecompressed(target, targetBits);
  64. return ((target & (UINT64_MAX << targetBits)) << (whoIsAskingBits - targetBits))
  65. | NumberCompress_getCompressed(targetIfaceNum, whoIsAskingBits);
  66. }
  67. /**
  68. * Determine if the node at the end of the given label is one hop away.
  69. *
  70. * @param label the label to test in host byte order.
  71. * @return true if the node is 1 hop away, false otherwise.
  72. */
  73. static inline bool LabelSplicer_isOneHop(uint64_t label)
  74. {
  75. return (int)NumberCompress_bitsUsedForLabel(label) == Bits_log2x64(label);
  76. }
  77. /**
  78. * Determine if the route to one node passes through another node.
  79. * Given:
  80. * 1. alice->bob->charlie->fred->bob
  81. * 2. alice->bob
  82. * 1 routes through 2.
  83. *
  84. * @param destination the node to route to.
  85. * @param midPath the node which might be in the middle of the route.
  86. * @return true if midPath is in the middle of the route to destination.
  87. */
  88. static inline bool LabelSplicer_routesThrough(uint64_t destination, uint64_t midPath)
  89. {
  90. if (midPath > destination) {
  91. return false;
  92. } if (midPath < 2) {
  93. return true;
  94. }
  95. uint64_t mask = UINT64_MAX >> (64 - Bits_log2x64(midPath));
  96. return (destination & mask) == (midPath & mask);
  97. }
  98. #endif