Line data Source code
1 : /* 2 : * Copyright (c) 2015 Cisco and/or its affiliates. 3 : * Licensed under the Apache License, Version 2.0 (the "License"); 4 : * you may not use this file except in compliance with the License. 5 : * You may obtain a copy of the License at: 6 : * 7 : * http://www.apache.org/licenses/LICENSE-2.0 8 : * 9 : * Unless required by applicable law or agreed to in writing, software 10 : * distributed under the License is distributed on an "AS IS" BASIS, 11 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : * See the License for the specific language governing permissions and 13 : * limitations under the License. 14 : */ 15 : /* 16 : Copyright (c) 2005 Eliot Dresselhaus 17 : 18 : Permission is hereby granted, free of charge, to any person obtaining 19 : a copy of this software and associated documentation files (the 20 : "Software"), to deal in the Software without restriction, including 21 : without limitation the rights to use, copy, modify, merge, publish, 22 : distribute, sublicense, and/or sell copies of the Software, and to 23 : permit persons to whom the Software is furnished to do so, subject to 24 : the following conditions: 25 : 26 : The above copyright notice and this permission notice shall be 27 : included in all copies or substantial portions of the Software. 28 : 29 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 30 : EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 31 : MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 32 : NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 33 : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 34 : OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 35 : WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 36 : */ 37 : 38 : #ifndef included_clib_random_buffer_h 39 : #define included_clib_random_buffer_h 40 : 41 : #include <vppinfra/clib.h> 42 : #include <vppinfra/random_isaac.h> 43 : #include <vppinfra/warnings.h> 44 : 45 : /* *INDENT-OFF* */ 46 : WARN_OFF(array-bounds) 47 : /* *INDENT-ON* */ 48 : 49 : typedef struct 50 : { 51 : /* Two parallel ISAAC contexts for speed. */ 52 : isaac_t ctx[2]; 53 : 54 : /* Random buffer. */ 55 : uword *buffer; 56 : 57 : /* An actual length to be applied before using the buffer. */ 58 : uword next_read_len; 59 : 60 : /* Cache up to 1 word worth of bytes for random data 61 : less than one word at a time. */ 62 : uword n_cached_bytes; 63 : 64 : union 65 : { 66 : u8 cached_bytes[sizeof (uword)]; 67 : uword cached_word; 68 : }; 69 : } 70 : clib_random_buffer_t; 71 : 72 : always_inline void 73 1 : clib_random_buffer_free (clib_random_buffer_t * b) 74 : { 75 1 : vec_free (b->buffer); 76 1 : } 77 : 78 : /* Fill random buffer. */ 79 : void clib_random_buffer_fill (clib_random_buffer_t * b, uword n_words); 80 : 81 : /* Initialize random buffer. */ 82 : void clib_random_buffer_init (clib_random_buffer_t * b, uword seed); 83 : 84 : /* Returns word aligned random data, possibly filling buffer. */ 85 : always_inline void * 86 10255 : clib_random_buffer_get_data (clib_random_buffer_t * b, uword n_bytes) 87 : { 88 : uword n_words, i, l; 89 : 90 10255 : if (b->buffer) 91 10084 : vec_set_len (b->buffer, b->next_read_len); 92 : else 93 171 : ASSERT (b->next_read_len == 0); 94 : 95 10255 : l = b->n_cached_bytes; 96 10255 : if (n_bytes <= l) 97 : { 98 2883 : b->n_cached_bytes = l - n_bytes; 99 2883 : return &b->cached_bytes[l - n_bytes]; 100 : } 101 : 102 7372 : n_words = n_bytes / sizeof (uword); 103 7372 : if (n_bytes % sizeof (uword)) 104 6377 : n_words++; 105 : 106 : /* Enough random words left? */ 107 7372 : if (PREDICT_FALSE (n_words > vec_len (b->buffer))) 108 1724 : clib_random_buffer_fill (b, n_words); 109 : 110 7372 : i = vec_len (b->buffer) - n_words; 111 7372 : b->next_read_len = i; 112 : 113 7372 : if (n_bytes < sizeof (uword)) 114 : { 115 2388 : b->cached_word = b->buffer[i]; 116 2388 : b->n_cached_bytes = sizeof (uword) - n_bytes; 117 2388 : return &b->cached_bytes[sizeof (uword) - n_bytes]; 118 : } 119 : else 120 4984 : return b->buffer + i; 121 : } 122 : 123 : /* *INDENT-OFF* */ 124 : WARN_ON(array-bounds) 125 : /* *INDENT-ON* */ 126 : 127 : #endif /* included_clib_random_buffer_h */ 128 : 129 : /* 130 : * fd.io coding-style-patch-verification: ON 131 : * 132 : * Local Variables: 133 : * eval: (c-set-style "gnu") 134 : * End: 135 : */