Skip to content

Commit d3a1b6c

Browse files
pasisgalnoam
authored andcommitted
issue: 3788369 Remove object pointer from the list_node
list_node is always inlined to a class and its offset is known. Therefore, we can find the object pointer with a single arithmetic operation and save 8 bytes per list_node. Remove the list iterator. It's mostly unused and requires special treatment of the head and tail. Replace it with next() and prev(). Signed-off-by: Dmytro Podgornyi <[email protected]>
1 parent b54f9ce commit d3a1b6c

File tree

5 files changed

+39
-144
lines changed

5 files changed

+39
-144
lines changed

src/core/iomux/epoll_wait_call.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,14 @@ int epoll_wait_call::get_current_events()
8686
}
8787

8888
xlio_list_t<sockinfo, sockinfo::socket_fd_list_node_offset> socket_fd_list;
89+
8990
lock();
90-
int i, ready_rfds = 0, ready_wfds = 0;
91-
i = m_n_all_ready_fds;
92-
sockinfo *p_socket_object;
93-
ep_ready_fd_list_t::iterator iter = m_epfd_info->m_ready_fds.begin();
94-
while (iter != m_epfd_info->m_ready_fds.end() && i < m_maxevents) {
95-
p_socket_object = *iter;
96-
++iter;
9791

92+
int i = m_n_all_ready_fds;
93+
int ready_rfds = 0;
94+
int ready_wfds = 0;
95+
sockinfo *p_socket_object = m_epfd_info->m_ready_fds.front();
96+
while (p_socket_object && i < m_maxevents) {
9897
m_events[i].events = 0; // initialize
9998

10099
bool got_event = false;
@@ -147,6 +146,8 @@ int epoll_wait_call::get_current_events()
147146
socket_fd_list.push_back(p_socket_object);
148147
++i;
149148
}
149+
150+
p_socket_object = m_epfd_info->m_ready_fds.next(p_socket_object);
150151
}
151152

152153
m_n_ready_rfds += ready_rfds;

src/core/sock/fd_collection.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -583,11 +583,9 @@ int fd_collection::del_socket(int fd, sockinfo **map_type)
583583

584584
void fd_collection::remove_from_all_epfds(int fd, bool passthrough)
585585
{
586-
epfd_info_list_t::iterator itr;
587-
588586
lock();
589-
for (itr = m_epfd_lst.begin(); itr != m_epfd_lst.end(); itr++) {
590-
itr->fd_closed(fd, passthrough);
587+
for (epfd_info *ep = m_epfd_lst.front(); ep; ep = m_epfd_lst.next(ep)) {
588+
ep->fd_closed(fd, passthrough);
591589
}
592590
unlock();
593591

src/core/sock/sockinfo_tcp.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,10 +1845,8 @@ int sockinfo_tcp::handle_child_FIN(sockinfo_tcp *child_conn)
18451845
{
18461846
lock_tcp_con();
18471847

1848-
sock_list_t::iterator conns_iter;
1849-
for (conns_iter = m_accepted_conns.begin(); conns_iter != m_accepted_conns.end();
1850-
conns_iter++) {
1851-
if (*(conns_iter) == child_conn) {
1848+
for (sockinfo_tcp *conn = m_accepted_conns.front(); conn; conn = m_accepted_conns.next(conn)) {
1849+
if (conn == child_conn) {
18521850
unlock_tcp_con();
18531851
return 0; // don't close conn, it can be accepted
18541852
}

src/core/sock/sockinfo_ulp.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,14 +1051,13 @@ void sockinfo_tcp_ops_tls::terminate_session_fatal(uint8_t alert_type)
10511051

10521052
void sockinfo_tcp_ops_tls::copy_by_offset(uint8_t *dst, uint32_t offset, uint32_t len)
10531053
{
1054-
auto iter = m_rx_bufs.begin();
1055-
mem_buf_desc_t *pdesc = *iter;
1054+
mem_buf_desc_t *pdesc = m_rx_bufs.front();
10561055

10571056
/* Skip leading buffers */
10581057
if (unlikely(pdesc->lwip_pbuf.len <= offset)) {
10591058
while (pdesc && pdesc->lwip_pbuf.len <= offset) {
10601059
offset -= pdesc->lwip_pbuf.len;
1061-
pdesc = *(++iter);
1060+
pdesc = m_rx_bufs.next(pdesc);
10621061
}
10631062
}
10641063

@@ -1071,22 +1070,21 @@ void sockinfo_tcp_ops_tls::copy_by_offset(uint8_t *dst, uint32_t offset, uint32_
10711070
dst += buflen;
10721071
offset = 0;
10731072

1074-
pdesc = *(++iter);
1073+
pdesc = m_rx_bufs.next(pdesc);
10751074
}
10761075
}
10771076

10781077
/* More efficient method to get 16bit value in the buffer list. */
10791078
uint16_t sockinfo_tcp_ops_tls::offset_to_host16(uint32_t offset)
10801079
{
1081-
auto iter = m_rx_bufs.begin();
1082-
mem_buf_desc_t *pdesc = *iter;
1080+
mem_buf_desc_t *pdesc = m_rx_bufs.front();
10831081
uint16_t res = 0;
10841082

10851083
/* Skip leading buffers */
10861084
if (unlikely(pdesc->lwip_pbuf.len <= offset)) {
10871085
while (pdesc && pdesc->lwip_pbuf.len <= offset) {
10881086
offset -= pdesc->lwip_pbuf.len;
1089-
pdesc = *(++iter);
1087+
pdesc = m_rx_bufs.next(pdesc);
10901088
}
10911089
}
10921090

@@ -1095,7 +1093,7 @@ uint16_t sockinfo_tcp_ops_tls::offset_to_host16(uint32_t offset)
10951093
++offset;
10961094
if (unlikely(offset >= pdesc->lwip_pbuf.len)) {
10971095
offset = 0;
1098-
pdesc = *(++iter);
1096+
pdesc = m_rx_bufs.next(pdesc);
10991097
if (unlikely(!pdesc)) {
11001098
return 0;
11011099
}
@@ -1339,7 +1337,6 @@ err_t sockinfo_tcp_ops_tls::recv(struct pbuf *p)
13391337

13401338
/* The first record is complete - push the payload to application. */
13411339

1342-
auto iter = m_rx_bufs.begin();
13431340
struct pbuf *pi;
13441341
struct pbuf *pres = nullptr;
13451342
struct pbuf *ptmp = nullptr;
@@ -1351,7 +1348,7 @@ err_t sockinfo_tcp_ops_tls::recv(struct pbuf *p)
13511348
uint8_t tls_type;
13521349
uint8_t tls_decrypted = 0;
13531350

1354-
mem_buf_desc_t *pdesc = *iter;
1351+
mem_buf_desc_t *pdesc = m_rx_bufs.front();
13551352
tls_type = ((uint8_t *)pdesc->lwip_pbuf.payload)[m_rx_offset];
13561353
if (is_rx_tls13()) {
13571354
/* TLS 1.3 sends record type as the last byte of the payload. */
@@ -1404,7 +1401,7 @@ err_t sockinfo_tcp_ops_tls::recv(struct pbuf *p)
14041401
offset = 0;
14051402

14061403
next_buffer:
1407-
pdesc = *(++iter);
1404+
pdesc = m_rx_bufs.next(pdesc);
14081405
}
14091406

14101407
int ret = 0;

src/core/util/xlio_list.h

Lines changed: 19 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ template <class T, size_t offset(void)> class list_node {
6565
public:
6666
/* head must be the first field! */
6767
struct list_head head;
68-
T *obj_ptr;
6968

7069
#if VLIST_DEBUG
7170
xlio_list_t<T, offset> *parent;
@@ -75,119 +74,23 @@ template <class T, size_t offset(void)> class list_node {
7574
#endif
7675

7776
list_node()
78-
: obj_ptr(NULL)
7977
{
8078
this->head.next = &this->head;
8179
this->head.prev = &this->head;
8280
VLIST_DEBUG_SET_PARENT(this, NULL);
8381
}
8482

83+
T *obj_ptr() { return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(this) - offset()); }
84+
8585
/* is_list_member - check if the node is already a member in a list. */
8686
bool is_list_member()
8787
{
8888
return this->head.next != &this->head || this->head.prev != &this->head;
8989
}
9090
};
9191

92-
template <typename T, size_t offset(void)>
93-
/* coverity[missing_move_assignment] */
94-
class list_iterator_t {
95-
public:
96-
using iterator_category = std::random_access_iterator_tag;
97-
using value_type = T;
98-
using difference_type = std::ptrdiff_t;
99-
using pointer = T *;
100-
using reference = T &;
101-
102-
list_iterator_t(T *ptr = NULL)
103-
: m_ptr(ptr)
104-
{
105-
}
106-
107-
list_iterator_t(const list_iterator_t<T, offset> &iter)
108-
: m_ptr(iter.m_ptr)
109-
{
110-
}
111-
112-
~list_iterator_t() {}
113-
114-
list_iterator_t<T, offset> &operator=(T *ptr)
115-
{
116-
m_ptr = ptr;
117-
return (*this);
118-
}
119-
120-
list_iterator_t<T, offset> &operator=(const list_iterator_t<T, offset> &iter)
121-
{
122-
m_ptr = iter.m_ptr;
123-
return (*this);
124-
}
125-
126-
operator bool() const { return m_ptr ? true : false; }
127-
128-
bool operator==(const list_iterator_t<T, offset> &iter) const
129-
{
130-
return m_ptr == iter.getConstPtr();
131-
}
132-
133-
bool operator!=(const list_iterator_t<T, offset> &iter) const
134-
{
135-
return m_ptr != iter.getConstPtr();
136-
}
137-
138-
list_iterator_t<T, offset> operator++(int)
139-
{
140-
list_iterator_t<T, offset> iter(*this);
141-
increment_ptr();
142-
return iter;
143-
}
144-
145-
list_iterator_t<T, offset> &operator++()
146-
{
147-
increment_ptr();
148-
return *this;
149-
}
150-
151-
list_iterator_t<T, offset> operator--(int)
152-
{
153-
list_iterator_t<T, offset> iter(*this);
154-
decrement_ptr();
155-
return iter;
156-
}
157-
158-
list_iterator_t<T, offset> &operator--()
159-
{
160-
decrement_ptr();
161-
return *this;
162-
}
163-
164-
T *operator*() { return m_ptr; }
165-
166-
const T *operator*() const { return m_ptr; }
167-
168-
T *operator->() { return m_ptr; }
169-
170-
T *getPtr() const { return m_ptr; }
171-
172-
const T *getConstPtr() const { return m_ptr; }
173-
174-
private:
175-
T *m_ptr;
176-
177-
inline void increment_ptr()
178-
{
179-
m_ptr = ((list_node<T, offset> *)GET_NODE(m_ptr, T, offset)->head.next)->obj_ptr;
180-
}
181-
182-
inline void decrement_ptr()
183-
{
184-
m_ptr = ((list_node<T, offset> *)GET_NODE(m_ptr, T, offset)->head.prev)->obj_ptr;
185-
}
186-
};
187-
18892
template <class T, size_t offset(void)> class xlio_list_t {
18993
public:
190-
typedef list_iterator_t<T, offset> iterator;
19194
xlio_list_t() { init_list(); }
19295

19396
void set_id(const char *format, ...)
@@ -241,23 +144,27 @@ template <class T, size_t offset(void)> class xlio_list_t {
241144
if (unlikely(empty())) {
242145
return NULL;
243146
}
244-
return ((list_node<T, offset> *)m_list.head.next)->obj_ptr;
147+
return ((list_node<T, offset> *)m_list.head.next)->obj_ptr();
245148
}
246149

247150
inline T *back() const
248151
{
249152
if (unlikely(empty())) {
250153
return NULL;
251154
}
252-
/* clang analyzer reports:
253-
* Use of memory after it is freed
254-
* This issue comes from ~chunk_list_t()
255-
* Root cause is unknown.
256-
* TODO: Fix based on root cause instead of supressing
257-
*/
258-
#ifndef __clang_analyzer__
259-
return ((list_node<T, offset> *)m_list.head.prev)->obj_ptr;
260-
#endif
155+
return ((list_node<T, offset> *)m_list.head.prev)->obj_ptr();
156+
}
157+
158+
inline T *next(T *obj) const
159+
{
160+
list_node<T, offset> *node = (list_node<T, offset> *)GET_NODE(obj, T, offset)->head.next;
161+
return node == &m_list ? NULL : node->obj_ptr();
162+
}
163+
164+
inline T *prev(T *obj) const
165+
{
166+
list_node<T, offset> *node = (list_node<T, offset> *)GET_NODE(obj, T, offset)->head.prev;
167+
return node == &m_list ? NULL : node->obj_ptr();
261168
}
262169

263170
inline void pop_front() { erase(front()); }
@@ -314,7 +221,6 @@ template <class T, size_t offset(void)> class xlio_list_t {
314221
}
315222

316223
VLIST_DEBUG_SET_PARENT(node_obj, this);
317-
node_obj->obj_ptr = obj;
318224
list_add_tail(&node_obj->head, &m_list.head);
319225
m_size++;
320226
}
@@ -332,7 +238,6 @@ template <class T, size_t offset(void)> class xlio_list_t {
332238
}
333239

334240
VLIST_DEBUG_SET_PARENT(node_obj, this);
335-
node_obj->obj_ptr = obj;
336241
list_add(&node_obj->head, &m_list.head);
337242
m_size++;
338243
}
@@ -346,7 +251,7 @@ template <class T, size_t offset(void)> class xlio_list_t {
346251
for (size_t i = 0; i < index; i++) {
347252
ans = ans->next;
348253
}
349-
return ((list_node<T, offset> *)ans)->obj_ptr;
254+
return ((list_node<T, offset> *)ans)->obj_ptr();
350255
}
351256
}
352257

@@ -375,8 +280,8 @@ template <class T, size_t offset(void)> class xlio_list_t {
375280
* type. Sizes may differ.
376281
*
377282
* After the call to this member function, the elements in this container are those which were
378-
* in x before the call, and the elements of x are those which were in this. All iterators,
379-
* references and pointers remain valid for the swapped objects.
283+
* in x before the call, and the elements of x are those which were in this. All references and
284+
* pointers remain valid for the swapped objects.
380285
*/
381286
void swap(xlio_list_t<T, offset> &x)
382287
{
@@ -386,10 +291,6 @@ template <class T, size_t offset(void)> class xlio_list_t {
386291
temp_list.move_to_empty(x);
387292
}
388293

389-
list_iterator_t<T, offset> begin() { return list_iterator_t<T, offset>(front()); }
390-
391-
list_iterator_t<T, offset> end() { return list_iterator_t<T, offset>(NULL); }
392-
393294
#if VLIST_DEBUG
394295
char *list_id() { return (char *)&id; }
395296
#endif

0 commit comments

Comments
 (0)