fs-fd-hash-inl.h
Go to the documentation of this file.
1 #ifndef UV_WIN_FS_FD_HASH_INL_H_
2 #define UV_WIN_FS_FD_HASH_INL_H_
3 
4 #include "uv.h"
5 #include "internal.h"
6 
7 /* Files are only inserted in uv__fd_hash when the UV_FS_O_FILEMAP flag is
8  * specified. Thus, when uv__fd_hash_get returns true, the file mapping in the
9  * info structure should be used for read/write operations.
10  *
11  * If the file is empty, the mapping field will be set to
12  * INVALID_HANDLE_VALUE. This is not an issue since the file mapping needs to
13  * be created anyway when the file size changes.
14  *
15  * Since file descriptors are sequential integers, the modulo operator is used
16  * as hashing function. For each bucket, a single linked list of arrays is
17  * kept to minimize allocations. A statically allocated memory buffer is kept
18  * for the first array in each bucket. */
19 
20 
21 #define UV__FD_HASH_SIZE 256
22 #define UV__FD_HASH_GROUP_SIZE 16
23 
24 struct uv__fd_info_s {
25  int flags;
26  BOOLEAN is_directory;
27  HANDLE mapping;
28  LARGE_INTEGER size;
29  LARGE_INTEGER current_pos;
30 };
31 
35 };
36 
40 };
41 
43  size_t size;
45 };
46 
47 
49 
53 
54 
55 INLINE static void uv__fd_hash_init(void) {
56  int i, err;
57 
59  if (err) {
60  uv_fatal_error(err, "uv_mutex_init");
61  }
62 
63  for (i = 0; i < ARRAY_SIZE(uv__fd_hash); ++i) {
64  uv__fd_hash[i].size = 0;
65  uv__fd_hash[i].data =
67  }
68 }
69 
70 #define FIND_COMMON_VARIABLES \
71  unsigned i; \
72  unsigned bucket = fd % ARRAY_SIZE(uv__fd_hash); \
73  struct uv__fd_hash_entry_s* entry_ptr = NULL; \
74  struct uv__fd_hash_entry_group_s* group_ptr; \
75  struct uv__fd_hash_bucket_s* bucket_ptr = &uv__fd_hash[bucket];
76 
77 #define FIND_IN_GROUP_PTR(group_size) \
78  do { \
79  for (i = 0; i < group_size; ++i) { \
80  if (group_ptr->entries[i].fd == fd) { \
81  entry_ptr = &group_ptr->entries[i]; \
82  break; \
83  } \
84  } \
85  } while (0)
86 
87 #define FIND_IN_BUCKET_PTR() \
88  do { \
89  size_t first_group_size = bucket_ptr->size % UV__FD_HASH_GROUP_SIZE; \
90  if (bucket_ptr->size != 0 && first_group_size == 0) \
91  first_group_size = UV__FD_HASH_GROUP_SIZE; \
92  group_ptr = bucket_ptr->data; \
93  FIND_IN_GROUP_PTR(first_group_size); \
94  for (group_ptr = group_ptr->next; \
95  group_ptr != NULL && entry_ptr == NULL; \
96  group_ptr = group_ptr->next) \
97  FIND_IN_GROUP_PTR(UV__FD_HASH_GROUP_SIZE); \
98  } while (0)
99 
100 INLINE static int uv__fd_hash_get(int fd, struct uv__fd_info_s* info) {
102 
104 
106 
107  if (entry_ptr != NULL) {
108  *info = entry_ptr->info;
109  }
110 
112  return entry_ptr != NULL;
113 }
114 
115 INLINE static void uv__fd_hash_add(int fd, struct uv__fd_info_s* info) {
117 
119 
121 
122  if (entry_ptr == NULL) {
123  i = bucket_ptr->size % UV__FD_HASH_GROUP_SIZE;
124 
125  if (bucket_ptr->size != 0 && i == 0) {
126  struct uv__fd_hash_entry_group_s* new_group_ptr =
127  uv__malloc(sizeof(*new_group_ptr));
128  if (new_group_ptr == NULL) {
129  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
130  }
131  new_group_ptr->next = bucket_ptr->data;
132  bucket_ptr->data = new_group_ptr;
133  }
134 
135  bucket_ptr->size += 1;
136  entry_ptr = &bucket_ptr->data->entries[i];
137  entry_ptr->fd = fd;
138  }
139 
140  entry_ptr->info = *info;
141 
143 }
144 
145 INLINE static int uv__fd_hash_remove(int fd, struct uv__fd_info_s* info) {
147 
149 
151 
152  if (entry_ptr != NULL) {
153  *info = entry_ptr->info;
154 
155  bucket_ptr->size -= 1;
156 
157  i = bucket_ptr->size % UV__FD_HASH_GROUP_SIZE;
158  if (entry_ptr != &bucket_ptr->data->entries[i]) {
159  *entry_ptr = bucket_ptr->data->entries[i];
160  }
161 
162  if (bucket_ptr->size != 0 &&
163  bucket_ptr->size % UV__FD_HASH_GROUP_SIZE == 0) {
164  struct uv__fd_hash_entry_group_s* old_group_ptr = bucket_ptr->data;
165  bucket_ptr->data = old_group_ptr->next;
166  uv__free(old_group_ptr);
167  }
168  }
169 
171  return entry_ptr != NULL;
172 }
173 
174 #undef FIND_COMMON_VARIABLES
175 #undef FIND_IN_GROUP_PTR
176 #undef FIND_IN_BUCKET_PTR
177 
178 #endif /* UV_WIN_FS_FD_HASH_INL_H_ */
uv__fd_info_s::current_pos
LARGE_INTEGER current_pos
Definition: fs-fd-hash-inl.h:29
uv__fd_hash_get
static INLINE int uv__fd_hash_get(int fd, struct uv__fd_info_s *info)
Definition: fs-fd-hash-inl.h:100
ARRAY_SIZE
#define ARRAY_SIZE(array)
Definition: bloaty.cc:101
uv__fd_hash_mutex
static uv_mutex_t uv__fd_hash_mutex
Definition: fs-fd-hash-inl.h:48
uv__fd_info_s::mapping
HANDLE mapping
Definition: fs-fd-hash-inl.h:27
uv__malloc
void * uv__malloc(size_t size)
Definition: uv-common.c:75
uv_mutex_init
UV_EXTERN int uv_mutex_init(uv_mutex_t *handle)
Definition: libuv/src/unix/thread.c:281
error_ref_leak.err
err
Definition: error_ref_leak.py:35
uv__fd_info_s::size
LARGE_INTEGER size
Definition: fs-fd-hash-inl.h:28
uv__fd_hash
static struct uv__fd_hash_bucket_s uv__fd_hash[UV__FD_HASH_SIZE]
Definition: fs-fd-hash-inl.h:52
FIND_COMMON_VARIABLES
#define FIND_COMMON_VARIABLES
Definition: fs-fd-hash-inl.h:70
uv__fd_info_s::is_directory
BOOLEAN is_directory
Definition: fs-fd-hash-inl.h:26
FIND_IN_BUCKET_PTR
#define FIND_IN_BUCKET_PTR()
Definition: fs-fd-hash-inl.h:87
uv__fd_hash_entry_s::fd
uv_file fd
Definition: fs-fd-hash-inl.h:33
uv__fd_info_s
Definition: fs-fd-hash-inl.h:24
uv__fd_hash_bucket_s
Definition: fs-fd-hash-inl.h:42
uv__free
void uv__free(void *ptr)
Definition: uv-common.c:81
uv_mutex_t
pthread_mutex_t uv_mutex_t
Definition: unix.h:135
INLINE
#define INLINE
Definition: third_party/libuv/src/win/internal.h:36
uv__fd_hash_entry_group_s::next
struct uv__fd_hash_entry_group_s * next
Definition: fs-fd-hash-inl.h:39
uv__fd_hash_bucket_s::data
struct uv__fd_hash_entry_group_s * data
Definition: fs-fd-hash-inl.h:44
uv__fd_hash_entry_group_s
Definition: fs-fd-hash-inl.h:37
uv_file
int uv_file
Definition: unix.h:126
uv_mutex_unlock
UV_EXTERN void uv_mutex_unlock(uv_mutex_t *handle)
Definition: libuv/src/unix/thread.c:349
uv__fd_hash_entry_s
Definition: fs-fd-hash-inl.h:32
uv_fatal_error
void uv_fatal_error(const int errorno, const char *syscall)
Definition: error.c:35
uv.h
uv__fd_hash_entry_initial
static struct uv__fd_hash_entry_group_s uv__fd_hash_entry_initial[UV__FD_HASH_SIZE *UV__FD_HASH_GROUP_SIZE]
Definition: fs-fd-hash-inl.h:50
uv__fd_hash_remove
static INLINE int uv__fd_hash_remove(int fd, struct uv__fd_info_s *info)
Definition: fs-fd-hash-inl.h:145
uv__fd_hash_bucket_s::size
size_t size
Definition: fs-fd-hash-inl.h:43
uv__fd_hash_add
static INLINE void uv__fd_hash_add(int fd, struct uv__fd_info_s *info)
Definition: fs-fd-hash-inl.h:115
uv_mutex_lock
UV_EXTERN void uv_mutex_lock(uv_mutex_t *handle)
Definition: libuv/src/unix/thread.c:329
UV__FD_HASH_GROUP_SIZE
#define UV__FD_HASH_GROUP_SIZE
Definition: fs-fd-hash-inl.h:22
UV__FD_HASH_SIZE
#define UV__FD_HASH_SIZE
Definition: fs-fd-hash-inl.h:21
uv__fd_hash_entry_group_s::entries
struct uv__fd_hash_entry_s entries[UV__FD_HASH_GROUP_SIZE]
Definition: fs-fd-hash-inl.h:38
uv__fd_info_s::flags
int flags
Definition: fs-fd-hash-inl.h:25
uv__fd_hash_entry_s::info
struct uv__fd_info_s info
Definition: fs-fd-hash-inl.h:34
internal.h
uv__fd_hash_init
static INLINE void uv__fd_hash_init(void)
Definition: fs-fd-hash-inl.h:55
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:59:22