Skip to content

Commit e193abf

Browse files
committed
Implement __collfs_mmap, add more comprehensive test, clarify documentation
1 parent a79596e commit e193abf

File tree

7 files changed

+212
-63
lines changed

7 files changed

+212
-63
lines changed

alphabet.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
abcdefghijklmnopqrstuvwxyz

collfs.c

Lines changed: 138 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#define _GNU_SOURCE 1 /* feature test macro so that RTLD_NEXT will be available */
44
#endif
55

6+
#include "collfs.h"
67
// start dl-load
78

89
#if COLLFS_IN_LIBC
@@ -61,6 +62,7 @@ static void set_errno(int e) { errno = e; }
6162
struct FileLink {
6263
MPI_Comm comm;
6364
int fd;
65+
int refct;
6466
char fname[MAXPATHLEN];
6567
void *mem;
6668
size_t len;
@@ -71,13 +73,21 @@ static struct FileLink *DLOpenFiles;
7173
static const int BaseFD = 10000;
7274
static int NextFD = 10001;
7375

76+
struct MMapLink {
77+
void *addr;
78+
size_t len;
79+
int fd;
80+
struct MMapLink *next;
81+
};
82+
static struct MMapLink *MMapRegions;
83+
7484
struct CommLink {
7585
MPI_Comm comm;
7686
struct CommLink *next;
7787
};
7888
static struct CommLink *CommStack;
7989

80-
/* Not collective, but changes the communicator on which future IO is collective */
90+
/* Logically collective, changes the communicator on which future IO is collective */
8191
int __collfs_comm_push(MPI_Comm comm)
8292
{
8393
struct CommLink *link;
@@ -86,14 +96,20 @@ int __collfs_comm_push(MPI_Comm comm)
8696
link->comm = comm;
8797
link->next = CommStack;
8898
CommStack = link;
99+
#if DEBUG
100+
MPI_Barrier(link->comm);
101+
#endif
89102
return 0;
90103
}
91-
/* Not collective, but changes the communicator on which future IO is collective */
104+
/* Logically collective, changes the communicator on which future IO is collective */
92105
int __collfs_comm_pop(void)
93106
{
94107
struct CommLink *link = CommStack;
95108
if (!link) return -1;
96109
CommStack = link->next;
110+
#if DEBUG
111+
MPI_Barrier(link->comm);
112+
#endif
97113
free(link);
98114
return 0;
99115
}
@@ -179,65 +195,125 @@ int __collfs_xstat64(int vers, const char *file, struct stat64 *buf)
179195
void *__collfs_mmap(void *addr, size_t len, int prot, int flags,
180196
int fildes, off_t off)
181197
{
182-
int rank = 0;
183-
if (MPI_Initialized) {
198+
struct FileLink *link;
199+
for (link=DLOpenFiles; link; link=link->next) {
200+
if (link->fd == fildes) {
201+
int err;
184202
#if DEBUG
185-
stderr_printf("[%x] mmap(fd:%x @%x,%x,%x,%x,%x)\n", rank, fildes, (int)(intptr_t)addr, (int)len, prot, flags, (int)off);
186-
#endif
187-
stderr_printf("__collfs_mmap has not been implemented yet! (passing through)\n");
188-
return mmap(addr, len, prot, flags, fildes, off);
203+
int rank;
204+
err = MPI_Comm_rank(link->comm, &rank);
205+
if (err) {
206+
set_errno(EPROTO);
207+
return MAP_FAILED;
208+
}
209+
stderr_printf("[%x] mmap(fd:%x @%x,%x,%x,%x,%x)\n", rank, fildes, (int)(intptr_t)addr, (int)len, prot, flags, (int)off);
210+
#endif
211+
struct MMapLink *mlink;
212+
213+
if (prot != PROT_READ && prot != (PROT_READ | PROT_EXEC)) {
214+
set_errno(EACCES);
215+
return MAP_FAILED;
216+
}
217+
if (flags & MAP_FIXED) { /* Not implemented due to laziness */
218+
set_errno(ENOTSUP);
219+
return MAP_FAILED;
220+
}
221+
if (flags != MAP_PRIVATE) { /* Cannot do MAP_SHARED for a collective fd */
222+
set_errno(ENOTSUP);
223+
return MAP_FAILED;
224+
}
225+
if (off < 0) {
226+
set_errno(ENXIO);
227+
return MAP_FAILED;
228+
}
229+
if (off + len > link->len) {
230+
set_errno(EOVERFLOW);
231+
return MAP_FAILED;
232+
}
233+
mlink = malloc(sizeof *mlink);
234+
mlink->addr = (char*)link->mem + off;
235+
mlink->len = len;
236+
mlink->fd = fildes;
237+
mlink->next = MMapRegions;
238+
MMapRegions = mlink;
239+
link->refct++;
240+
return mlink->addr;
241+
}
189242
}
190-
else {
191243
#if DEBUG
192-
stderr_printf("[NO_MPI] mmap(fd:%x @%x,%x,%x,%x,%x)\n", fildes, (int)(intptr_t)addr, (int)len, prot, flags, (int)off);
193-
#endif
194-
return mmap(addr, len, prot, flags, fildes, off);
195-
}
244+
stderr_printf("[NO_MPI] mmap(fd:%x @%x,%x,%x,%x,%x)\n", fildes, (int)(intptr_t)addr, (int)len, prot, flags, (int)off);
245+
#endif
246+
return mmap(addr, len, prot, flags, fildes, off);
196247
}
197248

198249
/* Not collective */
199250
int __collfs_munmap (__ptr_t addr, size_t len)
200251
{
201-
int rank = 0;
202-
if (MPI_Initialized) {
252+
if (CommStack) {
203253
#if DEBUG
254+
int rank;
255+
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
204256
stderr_printf("[%x] munmap(@%x,%x)\n", rank, (int)(intptr_t)addr, (int)len);
205-
#endif
206-
stderr_printf("__collfs_munmap has not been implemented yet! (passing through)\n");
207-
return munmap(addr, len);
208-
}
209-
else {
257+
#endif
258+
struct MMapLink *mlink;
259+
for (mlink=MMapRegions; mlink; mlink=mlink->next) {
260+
if (mlink->addr == addr) {
261+
int fd = mlink->fd;
262+
if (mlink->len != len) {
210263
#if DEBUG
211-
stderr_printf("[NO_MPI] munmap(@%x,%x)\n", (int)(intptr_t)addr, (int)len);
212-
#endif
213-
return munmap(addr, len);
264+
stderr_printf("[%x) Attempt to unmap region of length %x when %x was mapped\n", rank, (int)len, (int)mlink->len);
265+
#endif
266+
set_errno(EINVAL);
267+
return -1;
268+
}
269+
free(mlink);
270+
return __collfs_close(fd);
271+
}
272+
}
214273
}
274+
#if DEBUG
275+
stderr_printf("[NO_MPI] munmap(@%x,%x)\n", (int)(intptr_t)addr, (int)len);
276+
#endif
277+
return munmap(addr, len);
215278
}
216279

217280

218281
off_t __collfs_lseek(int fildes, off_t offset, int whence)
219282
{
220-
int rank = 0;
221-
if (MPI_Initialized) {
283+
struct FileLink *link;
284+
285+
for (link=DLOpenFiles; link; link=link->next) {
286+
if (link->fd == fildes) {
287+
int rank = 0;
288+
MPI_Comm_rank(link->comm,&rank);
222289
#if DEBUG
223-
stderr_printf("[%x] lseek(fd:%x,%x,%x)\n",rank,fildes,(int)offset,whence);
224-
#endif
225-
stderr_printf("__collfs_lseek has not been implemented yet! (passing through)\n");
226-
return __lseek(fildes, offset, whence);
290+
stderr_printf("[%x] lseek(fd:%x,%x,%x)\n",rank,fildes,(int)offset,whence);
291+
#endif
292+
if (!rank) return __lseek(fildes, offset, whence); /* Rank 0 has a normal fd */
293+
switch (whence) {
294+
case SEEK_SET:
295+
link->offset = offset;
296+
break;
297+
case SEEK_CUR:
298+
link->offset += offset;
299+
break;
300+
case SEEK_END:
301+
link->offset = link->len + offset;
302+
break;
303+
}
304+
return link->offset;
305+
}
227306
}
228-
else {
229307
#if DEBUG
230-
stderr_printf("[NO_MPI] lseek(fd:%x,%x,%x)\n",fildes,(int)offset,whence);
231-
#endif
232-
return __lseek(fildes, offset, whence);
233-
}
308+
stderr_printf("[NO_MPI] lseek(fd:%x,%x,%x)\n",fildes,(int)offset,whence);
309+
#endif
310+
return __lseek(fildes, offset, whence);
234311
}
235312

236-
237313
int __collfs_open(const char *pathname, int flags,...)
238314
{
239315
mode_t mode = 0;
240-
int err,rank = 0,initialized;
316+
int err, rank, initialized;
241317

242318
if (flags & O_CREAT) {
243319
va_list ap;
@@ -270,6 +346,11 @@ int __collfs_open(const char *pathname, int flags,...)
270346
return -1;
271347
}
272348

349+
err = MPI_Comm_rank(CommStack->comm, &rank);
350+
if (err) {
351+
set_errno(ECOLLFS);
352+
return -1;
353+
}
273354
#if DEBUG
274355
fprintf(stderr, "[%d] open(\"%s\",%d,%d)\n", rank, pathname, flags, mode);
275356
#endif
@@ -287,6 +368,7 @@ int __collfs_open(const char *pathname, int flags,...)
287368
else len = (int)fdst.st_size; /* Cast prevents using large files, but MPI would need workarounds too */
288369
}
289370
}
371+
MPI_Barrier(CommStack->comm);
290372
err = MPI_Bcast(&len, 1,MPI_INT, 0, CommStack->comm); if (err) return -1;
291373
if (len < 0) return -1;
292374
mem = NULL;
@@ -299,8 +381,7 @@ int __collfs_open(const char *pathname, int flags,...)
299381
#if DEBUG
300382
if (fd < 0) stderr_printf("could not shm_open because of \n");
301383
#endif
302-
if (fd >= 0)
303-
384+
if (fd >= 0)
304385
/* Make sure everyone found memory */
305386
gotmem = !!mem;
306387
err = MPI_Allreduce(MPI_IN_PLACE, &gotmem, 1, MPI_INT, MPI_LAND, CommStack->comm);
@@ -318,6 +399,7 @@ int __collfs_open(const char *pathname, int flags,...)
318399
link = malloc(sizeof *link);
319400
link->comm = CommStack->comm;
320401
link->fd = fd;
402+
link->refct = 1;
321403
strcpy(link->fname, pathname);
322404
link->mem = mem;
323405
link->len = len;
@@ -337,37 +419,27 @@ int __collfs_open(const char *pathname, int flags,...)
337419
int __collfs_close(int fd)
338420
{
339421
struct FileLink **linkp;
340-
int err,initialized;
341-
int rank = 0;
342-
343-
// pass through to libc __close if MPI has not been loaded yet
344-
if (MPI_Initialized) {
345-
err = MPI_Initialized(&initialized); if (err) return -1;
346-
#if DEBUG
347-
if (initialized) {err = MPI_Comm_rank(MPI_COMM_WORLD,&rank); if (err) return -1;}
348-
stderr_printf("[%x] close(fd:%x)\n",rank,fd);
349-
#endif
350-
}
351-
else {
352-
#if DEBUG
353-
stderr_printf("[NO_MPI] close(fd:%x)\n",fd);
354-
#endif
355-
return __close(fd);
356-
}
422+
int err;
357423

358424
for (linkp=&DLOpenFiles; linkp && *linkp; linkp=&(*linkp)->next) {
359425
struct FileLink *link = *linkp;
360426
if (link->fd == fd) { /* remove it from the list */
361-
int rank = 0, xerr = 0;
427+
int rank = 0, xerr = 0, initialized;
362428

429+
#if DEBUG
430+
err = MPI_Comm_rank(MPI_COMM_WORLD,&rank); if (err) return -1;
431+
stderr_printf("[%x] close(fd:%x)\n",rank,fd);
432+
#endif
433+
if (--link->refct > 0) return 0;
434+
err = MPI_Initialized(&initialized); if (err) return -1;
363435
if (!initialized) {
364436
#if DEBUG
365437
stderr_printf("Attempt to close open collective fd, but MPI is not initialized. Perhaps it was finalized early?\n");
366438
#endif
367439
set_errno(ECOLLFS);
368440
return -1;
369441
}
370-
err = MPI_Comm_rank(CommStack->comm, &rank); if (err) return -1;
442+
err = MPI_Comm_rank(CommStack ? CommStack->comm : MPI_COMM_WORLD, &rank); if (err) return -1;
371443
if (!rank) {
372444
munmap(link->mem, link->len);
373445
xerr = __close(fd);
@@ -379,6 +451,9 @@ int __collfs_close(int fd)
379451
return xerr;
380452
}
381453
}
454+
#if DEBUG
455+
stderr_printf("[NO_MPI] close(fd:%x)\n",fd);
456+
#endif
382457
return __close(fd);
383458
}
384459

@@ -394,6 +469,9 @@ ssize_t __collfs_read(int fd, void *buf, size_t count)
394469
err = MPI_Initialized(&initialized); if (err) return -1;
395470
if (initialized) {err = MPI_Comm_rank(link->comm, &rank); if (err) return -1;}
396471
if (fd == link->fd) {
472+
#if DEBUG > 1
473+
stderr_printf("[%x] read(%x,%x,%x)\n", rank, fd, (unsigned)(uintptr_t)buf, (unsigned)count);
474+
#endif
397475
if (!rank) return __read(fd, buf, count);
398476
else {
399477
if ((link->len - link->offset) < count) count = link->len - link->offset;
@@ -403,6 +481,9 @@ ssize_t __collfs_read(int fd, void *buf, size_t count)
403481
}
404482
}
405483
}
484+
#if DEBUG > 1
485+
stderr_printf("[NO_MPI] read(%x,%x,%x)\n", fd, (unsigned)(uintptr_t)buf, (unsigned)count);
486+
#endif
406487
return __read(fd, buf, count);
407488
}
408489

collfs.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
#ifndef _collfs_h
22
#define _collfs_h
33

4-
#define _GNU_SOURCE
4+
#ifndef _GNU_SOURCE
5+
# define _GNU_SOURCE
6+
#endif
7+
58
#include <sys/param.h>
69
#include <sys/stat.h>
710
#include <sys/types.h>
811
#include <unistd.h>
912
#include <mpi.h>
1013

14+
int __collfs_comm_push(MPI_Comm comm);
15+
int __collfs_comm_pop(void);
16+
17+
1118
int __collfs_fxstat64(int vers, int fd, struct stat64 *buf);
1219
int __collfs_xstat64(int vers, const char *file, struct stat64 *buf);
1320
int __collfs_open(const char *pathname, int flags,...);
1421
int __collfs_close(int fd);
15-
int __collfs_read(int fd, void *buf, size_t count);
22+
ssize_t __collfs_read(int fd, void *buf, size_t count);
1623
int __collfs_fxstat64(int vers, int fd, struct stat64 *buf);
1724
void* __collfs_mmap(void *addr, size_t len, int prot, int flags,
1825
int fildes, off_t off);

errmacros.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@
55

66
int PrintFrame(int frame,const char *func,const char *file,int line) {fprintf(stderr,"Stack frame %d in %s() at %s:%d\n",frame,func,file,line); return 0;}
77
#define CHK(err) do { if (err) {PrintFrame(err,__func__,__FILE__,__LINE__); return err+1;} } while (0)
8+
int HandleError(const char *func,const char *file,int line,const char *msg)
9+
{
10+
fprintf(stderr,"ERROR: %s\n",msg);
11+
PrintFrame(0,func,file,line);
12+
return 1;
13+
}
814
#define ERR(...) do { \
915
char _buf[512]; \
1016
snprintf(_buf,sizeof _buf,__VA_ARGS__); \
11-
fprintf(stderr,"ERROR: %s\n",_buf); \
12-
PrintFrame(0,__func__,__FILE__,__LINE__); \
13-
return 1; \
17+
return HandleError(__func__,__FILE__,__LINE__,_buf); \
1418
} while (0)
1519

1620
#endif

0 commit comments

Comments
 (0)