1 #include <string.h> 2 3 #include "memory_mgt.h" 4 #include "debug.h" 5 #include "tcp_send_buffer.h" 6 #include "tcp_sb_queue.h" 7 8 #define MAX(a, b) ((a)>(b)?(a):(b)) 9 #define MIN(a, b) ((a)<(b)?(a):(b)) 10 11 /*----------------------------------------------------------------------------*/ 12 struct sb_manager 13 { 14 size_t chunk_size; 15 uint32_t cur_num; 16 uint32_t cnum; 17 mem_pool_t mp; 18 sb_queue_t freeq; 19 20 } sb_manager; 21 /*----------------------------------------------------------------------------*/ 22 uint32_t 23 SBGetCurnum(sb_manager_t sbm) 24 { 25 return sbm->cur_num; 26 } 27 /*----------------------------------------------------------------------------*/ 28 sb_manager_t 29 SBManagerCreate(size_t chunk_size, uint8_t disable_rings, uint32_t concurrency) 30 { 31 sb_manager_t sbm = (sb_manager_t)calloc(1, sizeof(sb_manager)); 32 if (!sbm) { 33 TRACE_ERROR("SBManagerCreate() failed. %s\n", strerror(errno)); 34 return NULL; 35 } 36 37 sbm->chunk_size = chunk_size; 38 sbm->cnum = concurrency; 39 sbm->mp = (mem_pool_t)MPCreate(chunk_size, 40 (uint64_t)chunk_size * (!disable_rings * concurrency), 41 0); 42 if (!sbm->mp) { 43 TRACE_ERROR("Failed to create mem pool for sb.\n"); 44 free(sbm); 45 return NULL; 46 } 47 48 sbm->freeq = CreateSBQueue(concurrency); 49 if (!sbm->freeq) { 50 TRACE_ERROR("Failed to create free buffer queue.\n"); 51 MPDestroy(sbm->mp); 52 free(sbm); 53 return NULL; 54 } 55 56 return sbm; 57 } 58 /*----------------------------------------------------------------------------*/ 59 struct tcp_send_buffer * 60 SBInit(sb_manager_t sbm, uint32_t init_seq) 61 { 62 struct tcp_send_buffer *buf; 63 64 /* first try dequeue from free buffer queue */ 65 buf = SBDequeue(sbm->freeq); 66 if (!buf) { 67 buf = (struct tcp_send_buffer *)malloc(sizeof(struct tcp_send_buffer)); 68 if (!buf) { 69 perror("calloc() for buf"); 70 return NULL; 71 } 72 buf->data = MPAllocateChunk(sbm->mp); 73 if (!buf->data) { 74 TRACE_ERROR("Failed to fetch memory chunk for data.\n"); 75 free(buf); 76 return NULL; 77 } 78 sbm->cur_num++; 79 } 80 81 buf->head = buf->data; 82 83 buf->head_off = buf->tail_off = 0; 84 buf->len = buf->cum_len = 0; 85 buf->size = sbm->chunk_size; 86 87 buf->init_seq = buf->head_seq = init_seq; 88 89 return buf; 90 } 91 /*----------------------------------------------------------------------------*/ 92 void 93 SBFree(sb_manager_t sbm, struct tcp_send_buffer *buf) 94 { 95 if (!buf) 96 return; 97 98 SBEnqueue(sbm->freeq, buf); 99 } 100 /*----------------------------------------------------------------------------*/ 101 size_t 102 SBPut(sb_manager_t sbm, struct tcp_send_buffer *buf, const void *data, size_t len) 103 { 104 size_t to_put; 105 106 if (len <= 0) 107 return 0; 108 109 /* if no space, return -2 */ 110 to_put = MIN(len, buf->size - buf->len); 111 if (to_put <= 0) { 112 return -2; 113 } 114 115 if (buf->tail_off + to_put < buf->size) { 116 /* if the data fit into the buffer, copy it */ 117 memcpy(buf->data + buf->tail_off, data, to_put); 118 buf->tail_off += to_put; 119 } else { 120 /* if buffer overflows, move the existing payload and merge */ 121 memmove(buf->data, buf->head, buf->len); 122 buf->head = buf->data; 123 buf->head_off = 0; 124 memcpy(buf->head + buf->len, data, to_put); 125 buf->tail_off = buf->len + to_put; 126 } 127 buf->len += to_put; 128 buf->cum_len += to_put; 129 130 return to_put; 131 } 132 /*----------------------------------------------------------------------------*/ 133 size_t 134 SBRemove(sb_manager_t sbm, struct tcp_send_buffer *buf, size_t len) 135 { 136 size_t to_remove; 137 138 if (len <= 0) 139 return 0; 140 141 to_remove = MIN(len, buf->len); 142 if (to_remove <= 0) { 143 return -2; 144 } 145 146 buf->head_off += to_remove; 147 buf->head = buf->data + buf->head_off; 148 buf->head_seq += to_remove; 149 buf->len -= to_remove; 150 151 /* if buffer is empty, move the head to 0 */ 152 if (buf->len == 0 && buf->head_off > 0) { 153 buf->head = buf->data; 154 buf->head_off = buf->tail_off = 0; 155 } 156 157 return to_remove; 158 } 159 /*---------------------------------------------------------------------------*/ 160