Skip to content

Commit facf548

Browse files
authored
Merge pull request #113 from shwestrick/fast-file-io
Primitives for reading a file in parallel
2 parents aad75db + 4138280 commit facf548

File tree

17 files changed

+213
-2
lines changed

17 files changed

+213
-2
lines changed

basis-library/build/sources.mlb

+5
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,11 @@ in
393393
../mlton/mlton.sig
394394
../mlton/mlton.sml
395395

396+
../mpl/file.sig
397+
../mpl/file.sml
398+
../mpl/mpl.sig
399+
../mpl/mpl.sml
400+
396401
../sml-nj/sml-nj.sig
397402
../sml-nj/sml-nj.sml
398403
../sml-nj/unsafe.sig

basis-library/libs/all.mlb

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ local
1212
../basis-1997.mlb
1313
../basis-none.mlb
1414
../mlton.mlb
15+
../mpl.mlb
1516
../sml-nj.mlb
1617
../unsafe.mlb
1718
../c-types.mlb

basis-library/libs/basis-extra/top-level/basis-sigs.sml

+3
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,6 @@ signature MLTON_WORD = MLTON_WORD
116116
signature MLTON_WORLD = MLTON_WORLD
117117
signature SML_OF_NJ = SML_OF_NJ
118118
signature UNSAFE = UNSAFE
119+
120+
signature MPL = MPL
121+
signature MPL_FILE = MPL_FILE

basis-library/libs/basis-extra/top-level/basis.sig

+1
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ signature BASIS_EXTRA =
327327
structure MLton: MLTON
328328
structure SMLofNJ: SML_OF_NJ
329329
structure Unsafe: UNSAFE
330+
structure MPL: MPL
330331

331332
sharing type MLton.IntInf.t = IntInf.int
332333
sharing type MLton.Process.pid = Posix.Process.pid

basis-library/libs/basis-extra/top-level/basis.sml

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* See the file MLton-LICENSE for details.
66
*)
77

8-
structure BasisExtra :> BASIS_EXTRA =
8+
structure BasisExtra :> BASIS_EXTRA =
99
struct
1010
(* Required structures *)
1111
structure Array = Array
@@ -256,6 +256,7 @@ structure BasisExtra :> BASIS_EXTRA =
256256
structure MLton = MLton
257257
structure SMLofNJ = SMLofNJ
258258
structure Unsafe = Unsafe
259+
structure MPL = MPL
259260

260261
open ArrayGlobal
261262
BoolGlobal

basis-library/libs/basis-extra/top-level/top-level.sml

+1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ in
1212
structure MLton = MLton
1313
structure SMLofNJ = SMLofNJ
1414
structure Unsafe = Unsafe
15+
structure MPL = MPL
1516
end

basis-library/mpl.mlb

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
(* Copyright (C) 2020 Sam Westrick.
2+
*
3+
* MLton is released under a HPND-style license.
4+
* See the file MLton-LICENSE for details.
5+
*)
6+
7+
ann
8+
"deadCode true"
9+
"nonexhaustiveBind warn" "nonexhaustiveMatch warn"
10+
"redundantBind warn" "redundantMatch warn"
11+
"sequenceNonUnit warn"
12+
"warnUnused true" "forceUsed"
13+
in
14+
local
15+
libs/basis-extra/basis-extra.mlb
16+
in
17+
signature MPL_FILE
18+
signature MPL
19+
structure MPL
20+
end
21+
end

basis-library/mpl/file.sig

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
(* Copyright (C) 2020 Sam Westrick.
2+
*
3+
* MLton is released under a HPND-style license.
4+
* See the file MLton-LICENSE for details.
5+
*)
6+
7+
signature MPL_FILE =
8+
sig
9+
type t
10+
11+
exception Closed
12+
13+
val openFile: string -> t
14+
val closeFile: t -> unit
15+
val size: t -> int
16+
17+
val readChar: t -> int -> char
18+
val readWord8: t -> int -> Word8.word
19+
val unsafeReadChar: t -> int -> char
20+
val unsafeReadWord8: t -> int -> Word8.word
21+
22+
val readChars: t -> int -> char ArraySlice.slice -> unit
23+
val readWord8s: t -> int -> Word8.word ArraySlice.slice -> unit
24+
end

basis-library/mpl/file.sml

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
(* Copyright (C) 2020 Sam Westrick.
2+
*
3+
* MLton is released under a HPND-style license.
4+
* See the file MLton-LICENSE for details.
5+
*)
6+
7+
structure MPLFile :> MPL_FILE =
8+
struct
9+
local
10+
open Primitive.MLton.Pointer
11+
in
12+
structure C_Size = C_Size
13+
structure C_Int = C_Int
14+
end
15+
16+
type t = MLton.Pointer.t * int * bool ref
17+
18+
exception Closed
19+
20+
open Primitive.MPL.File
21+
22+
fun size (ptr, sz, stillOpen) =
23+
if !stillOpen then sz else raise Closed
24+
25+
fun openFile path =
26+
let
27+
open Posix.FileSys
28+
val file = openf (path, O_RDONLY, O.fromWord 0w0)
29+
val size = Position.toInt (ST.size (fstat file))
30+
val fd = C_Int.fromInt (SysWord.toInt (fdToWord file))
31+
val ptr = mmapFileReadable (fd, C_Size.fromInt size)
32+
in
33+
Posix.IO.close file;
34+
(ptr, size, ref true)
35+
end
36+
37+
fun closeFile (ptr, size, stillOpen) =
38+
if !stillOpen then
39+
(release (ptr, C_Size.fromInt size); stillOpen := false)
40+
else
41+
raise Closed
42+
43+
fun unsafeReadWord8 (ptr, _, _) i =
44+
MLton.Pointer.getWord8 (ptr, i)
45+
46+
fun unsafeReadChar (ptr, _, _) i =
47+
Char.chr (Word8.toInt (MLton.Pointer.getWord8 (ptr, i)))
48+
49+
fun readChar (ptr, size, stillOpen) (i: int) =
50+
if !stillOpen andalso i >= 0 andalso i < size then
51+
unsafeReadChar (ptr, size, stillOpen) i
52+
else if i < 0 orelse i >= size then
53+
raise Subscript
54+
else
55+
raise Closed
56+
57+
fun readWord8 (ptr, size, stillOpen) (i: int) =
58+
if !stillOpen andalso i >= 0 andalso i < size then
59+
unsafeReadWord8 (ptr, size, stillOpen) i
60+
else if i < 0 orelse i >= size then
61+
raise Subscript
62+
else
63+
raise Closed
64+
65+
fun readChars (ptr, size, stillOpen) i slice =
66+
let
67+
val (arr, j, n) = ArraySlice.base slice
68+
val start = MLtonPointer.add (ptr, Word.fromInt i)
69+
in
70+
if !stillOpen andalso i >= 0 andalso i+n <= size then
71+
copyCharsToBuffer (start, arr, C_Size.fromInt j, C_Size.fromInt n)
72+
else if i < 0 orelse i+n > size then
73+
raise Subscript
74+
else
75+
raise Closed
76+
end
77+
78+
fun readWord8s (ptr, size, stillOpen) i slice =
79+
let
80+
val (arr, j, n) = ArraySlice.base slice
81+
val start = MLtonPointer.add (ptr, Word.fromInt i)
82+
in
83+
if !stillOpen andalso i >= 0 andalso i+n <= size then
84+
copyWord8sToBuffer (start, arr, C_Size.fromInt j, C_Size.fromInt n)
85+
else if i < 0 orelse i+n > size then
86+
raise Subscript
87+
else
88+
raise Closed
89+
end
90+
91+
end

basis-library/mpl/mpl.sig

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
(* Copyright (C) 2020 Sam Westrick.
2+
*
3+
* MLton is released under a HPND-style license.
4+
* See the file MLton-LICENSE for details.
5+
*)
6+
7+
signature MPL =
8+
sig
9+
structure File: MPL_FILE
10+
end

basis-library/mpl/mpl.sml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
(* Copyright (C) 2020 Sam Westrick.
2+
*
3+
* MLton is released under a HPND-style license.
4+
* See the file MLton-LICENSE for details.
5+
*)
6+
7+
structure MPL :> MPL =
8+
struct
9+
structure File = MPLFile
10+
end

basis-library/primitive/prim-mpl.sml

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
(* Copyright (C) 2020 Sam Westrick.
2+
*
3+
* MLton is released under a HPND-style license.
4+
* See the file MLton-LICENSE for details.
5+
*)
6+
7+
structure Primitive = struct
8+
open Primitive
9+
10+
structure MPL =
11+
struct
12+
13+
structure File =
14+
struct
15+
val copyCharsToBuffer = _import "GC_memcpyToBuffer" runtime private:
16+
Pointer.t * Char8.t array * C_Size.word * C_Size.word -> unit;
17+
val copyWord8sToBuffer = _import "GC_memcpyToBuffer" runtime private:
18+
Pointer.t * Word8.word array * C_Size.word * C_Size.word -> unit;
19+
val mmapFileReadable = _import "GC_mmapFileReadable" runtime private:
20+
C_Int.int * C_Size.word -> Pointer.t;
21+
val release = _import "GC_release" runtime private:
22+
Pointer.t * C_Size.word -> unit;
23+
end
24+
25+
end
26+
27+
end

basis-library/primitive/primitive.mlb

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ in
7070
prim-pack-real.sml
7171

7272
prim-mlton.sml
73+
prim-mpl.sml
7374

7475
basis-ffi.sml
7576
prim2.sml

runtime/gc/virtual-memory.c

+4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ static inline void GC_memcpy (pointer src, pointer dst, size_t size) {
3232
memcpy (dst, src, size);
3333
}
3434

35+
void GC_memcpyToBuffer(pointer src, pointer buffer, size_t offset, size_t length) {
36+
GC_memcpy(src, buffer + offset, length);
37+
}
38+
3539
static inline void GC_memmove (pointer src, pointer dst, size_t size) {
3640
if (DEBUG_DETAILED)
3741
fprintf (stderr, "GC_memmove ("FMTPTR", "FMTPTR", %"PRIuMAX")\n",

runtime/platform.h

+3
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ PRIVATE __attribute__ ((noreturn)) void MLton_heapCheckTooLarge (void);
122122
*/
123123
PRIVATE void GC_displayMem (void);
124124

125+
PRIVATE void GC_memcpyToBuffer(pointer src, pointer buffer, size_t offset, size_t length);
126+
127+
PRIVATE void *GC_mmapFileReadable (int fd, size_t size);
125128
PRIVATE void *GC_mmapAnon (void *start, size_t length);
126129
PRIVATE void *GC_mmapAnonFlags (void *start, size_t length, int flags);
127130
PRIVATE void *GC_mmapAnon_safe (void *start, size_t length);

runtime/platform/mmap.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
static inline void *mmapFileReadable (int fd, size_t size) {
2+
return mmap (0, size, PROT_READ, MAP_PRIVATE, fd, 0);
3+
}
4+
15
static inline void *mmapAnonFlags (void *start, size_t length, int flags) {
2-
return mmap (start, length, PROT_READ | PROT_WRITE,
6+
return mmap (start, length, PROT_READ | PROT_WRITE,
37
MAP_PRIVATE | MAP_ANON | flags, -1, 0);
48
}
59

runtime/platform/use-mmap.c

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ void GC_release (void *base, size_t length) {
44
munmap_safe (base, length);
55
}
66

7+
void *GC_mmapFileReadable (int fd, size_t size) {
8+
return mmapFileReadable(fd, size);
9+
}
10+
711
void *GC_mmapAnon (void *start, size_t length) {
812
return mmapAnon (start, length);
913
}

0 commit comments

Comments
 (0)