trafgen: icmpv4: Update csum at runtime if needed
[netsniff-ng-new.git] / cpusched.c
blob26c077176298ac9aa558973b164ea3582ab2eef2
1 #define _GNU_SOURCE
2 #include <search.h>
3 #include <limits.h>
4 #include <errno.h>
5 #include <string.h>
7 #include "locking.h"
8 #include "cpusched.h"
9 #include "xmalloc.h"
10 #include "hash.h"
12 struct map_entry {
13 int fd;
14 unsigned int cpu;
15 struct map_entry *next;
18 static struct hash_table mapper;
19 static unsigned int *cpu_work_map = NULL;
20 static unsigned int cpu_len = 0;
21 static struct rwlock map_lock;
23 static unsigned int get_appropriate_cpu(void)
25 unsigned int i, cpu = 0;
26 unsigned int work = UINT_MAX;
28 for (i = 0; i < cpu_len; ++i) {
29 if (cpu_work_map[i] < work) {
30 work = cpu_work_map[i];
31 cpu = i;
35 return cpu;
38 unsigned int socket_to_cpu(int fd)
40 int cpu = 0;
41 struct map_entry *entry;
43 rwlock_rd_lock(&map_lock);
45 entry = lookup_hash(fd, &mapper);
46 while (entry && fd != entry->fd)
47 entry = entry->next;
49 if (entry && fd == entry->fd)
50 cpu = entry->cpu;
52 rwlock_unlock(&map_lock);
53 return cpu;
56 unsigned int register_socket(int fd)
58 void **pos;
59 struct map_entry *entry;
61 rwlock_wr_lock(&map_lock);
63 entry = xzmalloc(sizeof(*entry));
64 entry->fd = fd;
65 entry->cpu = get_appropriate_cpu();
67 cpu_work_map[entry->cpu]++;
69 pos = insert_hash(entry->fd, entry, &mapper);
70 if (pos) {
71 entry->next = (*pos);
72 (*pos) = entry;
75 rwlock_unlock(&map_lock);
76 return entry->cpu;
79 static struct map_entry *socket_to_map_entry(int fd)
81 struct map_entry *entry, *ret = NULL;
83 rwlock_rd_lock(&map_lock);
85 entry = lookup_hash(fd, &mapper);
86 while (entry && fd != entry->fd)
87 entry = entry->next;
89 if (entry && fd == entry->fd)
90 ret = entry;
92 rwlock_unlock(&map_lock);
93 return ret;
96 void unregister_socket(int fd)
98 struct map_entry *pos;
99 struct map_entry *entry = socket_to_map_entry(fd);
101 if (entry == NULL)
102 return;
104 rwlock_wr_lock(&map_lock);
106 cpu_work_map[entry->cpu]--;
108 pos = remove_hash(entry->fd, entry, entry->next, &mapper);
109 while (pos && pos->next && pos->next != entry)
110 pos = pos->next;
112 if (pos && pos->next && pos->next == entry)
113 pos->next = entry->next;
115 entry->next = NULL;
116 xfree(entry);
118 rwlock_unlock(&map_lock);
121 static int cleanup_cpusched_batch(void *ptr)
123 struct map_entry *next;
124 struct map_entry *entry = ptr;
126 if (!entry)
127 return 0;
129 while ((next = entry->next)) {
130 entry->next = NULL;
132 xfree(entry);
133 entry = next;
136 xfree(entry);
137 return 0;
140 void init_cpusched(unsigned int cpus)
142 rwlock_init(&map_lock);
143 cpu_len = cpus;
144 cpu_work_map = xcalloc(cpu_len, sizeof(*cpu_work_map));
145 init_hash(&mapper);
148 void destroy_cpusched(void)
150 xfree(cpu_work_map);
151 for_each_hash(&mapper, cleanup_cpusched_batch);
152 free_hash(&mapper);
153 rwlock_destroy(&map_lock);