Skip to content

Commit d52bf7d

Browse files
rshinrobertnishihara
authored andcommitted
Use dlmalloc to manage shared memory (#15)
* Use dlmalloc to manage shared memory * add stresstest
1 parent 04737f3 commit d52bf7d

File tree

12 files changed

+6496
-53
lines changed

12 files changed

+6496
-53
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
build/*
22
*~
3+
*.pyc

.travis/check-git-clang-format-output.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ else
77
base_commit="$TRAVIS_BRANCH"
88
echo "Running clang-format against branch $base_commit, with hash $(git rev-parse $base_commit)"
99
fi
10-
output="$(.travis/git-clang-format --binary clang-format-3.8 --commit $base_commit --diff)"
10+
output="$(.travis/git-clang-format --binary clang-format-3.8 --commit $base_commit --diff --exclude ^third_party/)"
1111
if [ "$output" == "no modified files to format" ] || [ "$output" == "clang-format did not modify any files" ] ; then
1212
echo "clang-format passed."
1313
exit 0

.travis/git-clang-format

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ def main():
9797
default_extensions),
9898
help=('comma-separated list of file extensions to format, '
9999
'excluding the period and case-insensitive')),
100+
p.add_argument('--exclude', help='Exclude files matching this regex.')
100101
p.add_argument('-f', '--force', action='store_true',
101102
help='allow changes to unstaged files')
102103
p.add_argument('-p', '--patch', action='store_true',
@@ -125,10 +126,14 @@ def main():
125126
if opts.verbose >= 1:
126127
ignored_files = set(changed_lines)
127128
filter_by_extension(changed_lines, opts.extensions.lower().split(','))
129+
if opts.exclude:
130+
for filename in changed_lines.keys():
131+
if re.match(opts.exclude, filename):
132+
del changed_lines[filename]
128133
if opts.verbose >= 1:
129134
ignored_files.difference_update(changed_lines)
130135
if ignored_files:
131-
print 'Ignoring changes in the following files (wrong extension):'
136+
print 'Ignoring changes in the following files:'
132137
for filename in ignored_files:
133138
print ' ', filename
134139
if changed_lines:

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
CC = gcc
2-
CFLAGS = -g -Wall --std=c99 -D_XOPEN_SOURCE=500
2+
CFLAGS = -g -Wall --std=c99 -D_XOPEN_SOURCE=500 -I.
33
BUILD = build
44

55
all: $(BUILD)/plasma_store $(BUILD)/plasma_manager $(BUILD)/plasma_client.so $(BUILD)/example
66

77
clean:
88
rm -r $(BUILD)/*
99

10-
$(BUILD)/plasma_store: src/plasma_store.c src/plasma.h src/event_loop.h src/event_loop.c src/fling.h src/fling.c
11-
$(CC) $(CFLAGS) src/plasma_store.c src/event_loop.c src/fling.c -o $(BUILD)/plasma_store
10+
$(BUILD)/plasma_store: src/plasma_store.c src/plasma.h src/event_loop.h src/event_loop.c src/fling.h src/fling.c src/malloc.c src/malloc.h third_party/dlmalloc.c
11+
$(CC) $(CFLAGS) src/plasma_store.c src/event_loop.c src/fling.c src/malloc.c -o $(BUILD)/plasma_store
1212

1313
$(BUILD)/plasma_manager: src/plasma_manager.c src/event_loop.h src/event_loop.c src/plasma.h src/plasma_client.c src/fling.h src/fling.c
1414
$(CC) $(CFLAGS) src/plasma_manager.c src/event_loop.c src/plasma_client.c src/fling.c -o $(BUILD)/plasma_manager

src/fling.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ int send_fd(int conn, int fd, const char *payload, int size) {
1919
struct msghdr msg;
2020
struct iovec iov;
2121
char buf[CMSG_SPACE(sizeof(int))];
22+
memset(&buf, 0, CMSG_SPACE(sizeof(int)));
2223

2324
init_msg(&msg, &iov, buf, sizeof(buf));
2425

src/malloc.c

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#include <assert.h>
2+
#include <stdlib.h>
3+
#include <stddef.h>
4+
#include <stdio.h>
5+
#include <string.h>
6+
#include <sys/mman.h>
7+
#include <unistd.h>
8+
9+
#include "plasma.h"
10+
#include "uthash.h"
11+
12+
void *fake_mmap(size_t);
13+
int fake_munmap(void *, size_t);
14+
15+
#define MMAP(s) fake_mmap(s)
16+
#define MUNMAP(a, s) fake_munmap(a, s)
17+
#define DIRECT_MMAP(s) fake_mmap(s)
18+
#define DIRECT_MUNMAP(a, s) fake_munmap(a, s)
19+
#define USE_DL_PREFIX
20+
#define HAVE_MORECORE 0
21+
22+
#include "third_party/dlmalloc.c"
23+
24+
#undef MMAP
25+
#undef MUNMAP
26+
#undef DIRECT_MMAP
27+
#undef DIRECT_MUNMAP
28+
#undef USE_DL_PREFIX
29+
#undef HAVE_MORECORE
30+
31+
struct mmap_record {
32+
int fd;
33+
void *pointer;
34+
int64_t size;
35+
UT_hash_handle hh_fd;
36+
UT_hash_handle hh_pointer;
37+
};
38+
39+
struct mmap_record *records_by_fd = NULL;
40+
struct mmap_record *records_by_pointer = NULL;
41+
42+
/* Create a buffer. This is creating a temporary file and then
43+
* immediately unlinking it so we do not leave traces in the system. */
44+
int create_buffer(int64_t size) {
45+
static char template[] = "/tmp/plasmaXXXXXX";
46+
char file_name[32];
47+
strncpy(file_name, template, 32);
48+
int fd = mkstemp(file_name);
49+
if (fd < 0)
50+
return -1;
51+
FILE *file = fdopen(fd, "a+");
52+
if (!file) {
53+
close(fd);
54+
return -1;
55+
}
56+
if (unlink(file_name) != 0) {
57+
LOG_ERR("unlink error");
58+
return -1;
59+
}
60+
if (ftruncate(fd, (off_t) size) != 0) {
61+
LOG_ERR("ftruncate error");
62+
return -1;
63+
}
64+
return fd;
65+
}
66+
67+
void *fake_mmap(size_t size) {
68+
// Add sizeof(size_t) so that the returned pointer is deliberately not
69+
// page-aligned. This ensures that the segments of memory returned by
70+
// fake_mmap are never contiguous.
71+
int fd = create_buffer(size + sizeof(size_t));
72+
void *pointer = mmap(NULL, size + sizeof(size_t), PROT_READ | PROT_WRITE,
73+
MAP_SHARED, fd, 0);
74+
if (pointer == MAP_FAILED) {
75+
return pointer;
76+
}
77+
pointer += sizeof(size_t);
78+
79+
struct mmap_record *record = malloc(sizeof(struct mmap_record));
80+
record->fd = fd;
81+
record->pointer = pointer;
82+
record->size = size;
83+
HASH_ADD(hh_fd, records_by_fd, fd, sizeof(fd), record);
84+
HASH_ADD(hh_pointer, records_by_pointer, pointer, sizeof(pointer), record);
85+
86+
LOG_DEBUG("%p = fake_mmap(%lu)", pointer, size);
87+
return pointer;
88+
}
89+
90+
int fake_munmap(void *addr, size_t size) {
91+
LOG_DEBUG("fake_munmap(%p, %lu)", addr, size);
92+
93+
struct mmap_record *record;
94+
95+
addr -= sizeof(size_t);
96+
HASH_FIND(hh_pointer, records_by_pointer, &addr, sizeof(addr), record);
97+
assert(record != NULL);
98+
close(record->fd);
99+
100+
HASH_DELETE(hh_fd, records_by_fd, record);
101+
HASH_DELETE(hh_pointer, records_by_pointer, record);
102+
103+
return munmap(addr, size + sizeof(size_t));
104+
}
105+
106+
void get_malloc_mapinfo(void *addr,
107+
int *fd,
108+
int64_t *map_size,
109+
ptrdiff_t *offset) {
110+
struct mmap_record *record;
111+
// TODO(rshin): Implement a more efficient search through records_by_fd.
112+
for (record = records_by_fd; record != NULL; record = record->hh_fd.next) {
113+
if (addr >= record->pointer && addr < record->pointer + record->size) {
114+
*fd = record->fd;
115+
*map_size = record->size;
116+
*offset = addr - record->pointer;
117+
return;
118+
}
119+
}
120+
*fd = -1;
121+
*map_size = 0;
122+
*offset = 0;
123+
}

src/malloc.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifndef MALLOC_H
2+
#define MALLOC_H
3+
4+
void get_malloc_mapinfo(void *addr,
5+
int *fd,
6+
int64_t *map_length,
7+
ptrdiff_t *offset);
8+
9+
#endif // MALLOC_H

src/plasma.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <inttypes.h>
55
#include <stdio.h>
66
#include <errno.h>
7+
#include <stddef.h>
78
#include <string.h>
89

910
#ifdef NDEBUG
@@ -13,13 +14,17 @@
1314
fprintf(stderr, "[DEBUG] (%s:%d) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__)
1415
#endif
1516

17+
#ifdef PLASMA_LOGGIN_ON
18+
#define LOG_INFO(M, ...) \
19+
fprintf(stderr, "[INFO] (%s:%d) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__)
20+
#else
21+
#define LOG_INFO(M, ...)
22+
#endif
23+
1624
#define LOG_ERR(M, ...) \
1725
fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, \
1826
errno == 0 ? "None" : strerror(errno), ##__VA_ARGS__)
1927

20-
#define LOG_INFO(M, ...) \
21-
fprintf(stderr, "[INFO] (%s:%d) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__)
22-
2328
typedef struct {
2429
int64_t size;
2530
int64_t create_time;
@@ -59,7 +64,9 @@ enum plasma_reply_type {
5964

6065
typedef struct {
6166
int type;
62-
int64_t size;
67+
ptrdiff_t offset;
68+
int64_t map_size;
69+
int64_t object_size;
6370
} plasma_reply;
6471

6572
typedef struct {

src/plasma_client.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,15 @@ void plasma_create(int conn, plasma_id object_id, int64_t size, void **data) {
3131
plasma_reply reply;
3232
int fd = recv_fd(conn, (char *) &reply, sizeof(plasma_reply));
3333
assert(reply.type == PLASMA_OBJECT);
34-
assert(reply.size == size);
35-
*data = mmap(NULL, reply.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
34+
assert(reply.object_size == size);
35+
*data =
36+
mmap(NULL, reply.map_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0) +
37+
reply.offset;
3638
if (*data == MAP_FAILED) {
3739
LOG_ERR("mmap failed");
3840
exit(-1);
3941
}
42+
close(fd);
4043
}
4144

4245
void plasma_get(int conn, plasma_id object_id, int64_t *size, void **data) {
@@ -51,12 +54,14 @@ void plasma_get(int conn, plasma_id object_id, int64_t *size, void **data) {
5154
fd = new_fd;
5255
}
5356
assert(reply.type == PLASMA_OBJECT);
54-
*data = mmap(NULL, reply.size, PROT_READ, MAP_SHARED, fd, 0);
57+
*data =
58+
mmap(NULL, reply.map_size, PROT_READ, MAP_SHARED, fd, 0) + reply.offset;
5559
if (*data == MAP_FAILED) {
5660
LOG_ERR("mmap failed");
5761
exit(-1);
5862
}
59-
*size = reply.size;
63+
close(fd);
64+
*size = reply.object_size;
6065
}
6166

6267
void plasma_seal(int fd, plasma_id object_id) {
@@ -116,8 +121,10 @@ int plasma_manager_connect(const char *ip_addr, int port) {
116121

117122
int r = connect(fd, (struct sockaddr *) &addr, sizeof(addr));
118123
if (r < 0) {
119-
LOG_ERR("could not establish connection to manager with id %s:%d",
120-
&ip_addr[0], port);
124+
LOG_ERR(
125+
"could not establish connection to manager with id %s:%d (probably ran "
126+
"out of ports)",
127+
&ip_addr[0], port);
121128
exit(-1);
122129
}
123130
return fd;

0 commit comments

Comments
 (0)