mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Merge pull request #4730 from laytan/os2-linux-loop-writes-and-cap-rw
os/os2: bring Linux to other impls standards by looping writes and maxing one shot RW sizes
This commit is contained in:
+41
-20
@@ -7,6 +7,13 @@ import "core:time"
|
|||||||
import "core:sync"
|
import "core:sync"
|
||||||
import "core:sys/linux"
|
import "core:sys/linux"
|
||||||
|
|
||||||
|
// Most implementations will EINVAL at some point when doing big writes.
|
||||||
|
// In practice a read/write call would probably never read/write these big buffers all at once,
|
||||||
|
// which is why the number of bytes is returned and why there are procs that will call this in a
|
||||||
|
// loop for you.
|
||||||
|
// We set a max of 1GB to keep alignment and to be safe.
|
||||||
|
MAX_RW :: 1 << 30
|
||||||
|
|
||||||
File_Impl :: struct {
|
File_Impl :: struct {
|
||||||
file: File,
|
file: File,
|
||||||
name: string,
|
name: string,
|
||||||
@@ -179,10 +186,11 @@ _seek :: proc(f: ^File_Impl, offset: i64, whence: io.Seek_From) -> (ret: i64, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
_read :: proc(f: ^File_Impl, p: []byte) -> (i64, Error) {
|
_read :: proc(f: ^File_Impl, p: []byte) -> (i64, Error) {
|
||||||
if len(p) == 0 {
|
if len(p) <= 0 {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
n, errno := linux.read(f.fd, p[:])
|
|
||||||
|
n, errno := linux.read(f.fd, p[:min(len(p), MAX_RW)])
|
||||||
if errno != .NONE {
|
if errno != .NONE {
|
||||||
return -1, _get_platform_error(errno)
|
return -1, _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
@@ -190,13 +198,13 @@ _read :: proc(f: ^File_Impl, p: []byte) -> (i64, Error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_read_at :: proc(f: ^File_Impl, p: []byte, offset: i64) -> (i64, Error) {
|
_read_at :: proc(f: ^File_Impl, p: []byte, offset: i64) -> (i64, Error) {
|
||||||
if len(p) == 0 {
|
if len(p) <= 0 {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
if offset < 0 {
|
if offset < 0 {
|
||||||
return 0, .Invalid_Offset
|
return 0, .Invalid_Offset
|
||||||
}
|
}
|
||||||
n, errno := linux.pread(f.fd, p[:], offset)
|
n, errno := linux.pread(f.fd, p[:min(len(p), MAX_RW)], offset)
|
||||||
if errno != .NONE {
|
if errno != .NONE {
|
||||||
return -1, _get_platform_error(errno)
|
return -1, _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
@@ -206,29 +214,42 @@ _read_at :: proc(f: ^File_Impl, p: []byte, offset: i64) -> (i64, Error) {
|
|||||||
return i64(n), nil
|
return i64(n), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_write :: proc(f: ^File_Impl, p: []byte) -> (i64, Error) {
|
_write :: proc(f: ^File_Impl, p: []byte) -> (nt: i64, err: Error) {
|
||||||
if len(p) == 0 {
|
p := p
|
||||||
return 0, nil
|
for len(p) > 0 {
|
||||||
|
n, errno := linux.write(f.fd, p[:min(len(p), MAX_RW)])
|
||||||
|
if errno != .NONE {
|
||||||
|
err = _get_platform_error(errno)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p = p[n:]
|
||||||
|
nt += i64(n)
|
||||||
}
|
}
|
||||||
n, errno := linux.write(f.fd, p[:])
|
|
||||||
if errno != .NONE {
|
return
|
||||||
return -1, _get_platform_error(errno)
|
|
||||||
}
|
|
||||||
return i64(n), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_write_at :: proc(f: ^File_Impl, p: []byte, offset: i64) -> (i64, Error) {
|
_write_at :: proc(f: ^File_Impl, p: []byte, offset: i64) -> (nt: i64, err: Error) {
|
||||||
if len(p) == 0 {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
if offset < 0 {
|
if offset < 0 {
|
||||||
return 0, .Invalid_Offset
|
return 0, .Invalid_Offset
|
||||||
}
|
}
|
||||||
n, errno := linux.pwrite(f.fd, p[:], offset)
|
|
||||||
if errno != .NONE {
|
p := p
|
||||||
return -1, _get_platform_error(errno)
|
offset := offset
|
||||||
|
for len(p) > 0 {
|
||||||
|
n, errno := linux.pwrite(f.fd, p[:min(len(p), MAX_RW)], offset)
|
||||||
|
if errno != .NONE {
|
||||||
|
err = _get_platform_error(errno)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p = p[n:]
|
||||||
|
nt += i64(n)
|
||||||
|
offset += i64(n)
|
||||||
}
|
}
|
||||||
return i64(n), nil
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_file_size :: proc(f: ^File_Impl) -> (n: i64, err: Error) {
|
_file_size :: proc(f: ^File_Impl) -> (n: i64, err: Error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user