@k13engineering/linux-dmabuf-allocator 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,8 @@
1
+ declare const createDefaultAllocationSizeDeterminer: ({ pageSize }: {
2
+ pageSize: number;
3
+ }) => {
4
+ determineOptimalAllocationSize: ({ minimumSize }: {
5
+ minimumSize: number;
6
+ }) => number;
7
+ };
8
+ export { createDefaultAllocationSizeDeterminer };
@@ -0,0 +1,15 @@
1
+ const createDefaultAllocationSizeDeterminer = ({ pageSize }/*: { pageSize: number }*/) => {
2
+
3
+ const determineOptimalAllocationSize = ({ minimumSize }/*: { minimumSize: number }*/)/*: number*/ => {
4
+ const pagesNeeded = Math.ceil(minimumSize / pageSize);
5
+ return pagesNeeded * pageSize;
6
+ };
7
+
8
+ return {
9
+ determineOptimalAllocationSize
10
+ };
11
+ };
12
+
13
+ export {
14
+ createDefaultAllocationSizeDeterminer
15
+ };
@@ -0,0 +1,18 @@
1
+ type TDmabufAllocateArgs = {
2
+ size: number;
3
+ };
4
+ type TDmabufAllocateResult = {
5
+ error: Error;
6
+ dmabufFd: undefined;
7
+ } | {
8
+ error: undefined;
9
+ dmabufFd: number;
10
+ };
11
+ type TDmabufAllocator = {
12
+ allocate: (args: TDmabufAllocateArgs) => TDmabufAllocateResult;
13
+ pageSize: number;
14
+ determineOptimalAllocationSize: (args: {
15
+ minimumSize: number;
16
+ }) => number;
17
+ };
18
+ export type { TDmabufAllocator };
@@ -0,0 +1,23 @@
1
+ /* c8 ignore start */
2
+ /*type TDmabufAllocateArgs = {
3
+ size: number;
4
+ };*/
5
+
6
+ /*type TDmabufAllocateResult = {
7
+ error: Error;
8
+ dmabufFd: undefined;
9
+ } | {
10
+ error: undefined;
11
+ dmabufFd: number;
12
+ };*/
13
+
14
+ /*type TDmabufAllocator = {
15
+ allocate: (args: TDmabufAllocateArgs) => TDmabufAllocateResult;
16
+ pageSize: number;
17
+ determineOptimalAllocationSize: (args: { minimumSize: number }) => number;
18
+ };*/
19
+
20
+ /*export type {
21
+ TDmabufAllocator
22
+ };*/
23
+ /* c8 ignore end */
@@ -0,0 +1,19 @@
1
+ import type { TDmabufHeapIoctlKernelInterface } from "../kernel-interface.js";
2
+ type TDmabufHeapIoctlAllocateResult = {
3
+ errno: undefined;
4
+ dmabufFd: number;
5
+ } | {
6
+ errno: number;
7
+ dmabufFd: undefined;
8
+ };
9
+ declare const createDmabufHeapIoctls: ({ kernelIoctlInterface }: {
10
+ kernelIoctlInterface: TDmabufHeapIoctlKernelInterface;
11
+ }) => {
12
+ dmabufHeapIoctlAllocate: ({ dmabufHeapFd, size, fdFlags, heapFlags }: {
13
+ dmabufHeapFd: number;
14
+ size: number;
15
+ fdFlags: bigint;
16
+ heapFlags: bigint;
17
+ }) => TDmabufHeapIoctlAllocateResult;
18
+ };
19
+ export { createDmabufHeapIoctls };
@@ -0,0 +1,97 @@
1
+ import { endianBufferViewFor } from "../endian-buffer.js";
2
+ /*import type { TDmabufHeapIoctlKernelInterface } from "../kernel-interface.ts";*/
3
+
4
+ /*type TDmabufHeapIoctlAllocateResult = {
5
+ errno: undefined;
6
+ dmabufFd: number;
7
+ } | {
8
+ errno: number;
9
+ dmabufFd: undefined;
10
+ };*/
11
+
12
+ const formatAllocationData = ({
13
+ endianness,
14
+ len,
15
+ fdFlags,
16
+ heapFlags
17
+ }/*: {
18
+ endianness: TDmabufHeapIoctlKernelInterface["endianness"];
19
+ len: number;
20
+ fdFlags: bigint;
21
+ heapFlags: bigint;
22
+ }*/) => {
23
+
24
+ const allocationData = new Uint8Array(24);
25
+
26
+ const view = endianBufferViewFor({ buffer: allocationData, endianness });
27
+
28
+ // struct dma_heap_allocation_data {
29
+ // __u64 len
30
+ view.writeU64({ offset: 0, value: BigInt(len) });
31
+ // __u32 fd
32
+ view.writeU32({ offset: 8, value: 0 });
33
+ // __u32 fd_flags
34
+ view.writeU32({ offset: 12, value: Number(fdFlags) });
35
+ // __u64 heap_flags
36
+ view.writeU64({ offset: 16, value: heapFlags });
37
+ // }
38
+
39
+ return allocationData;
40
+ };
41
+
42
+ const DMA_HEAP_IOCTL_ALLOC = BigInt(0xc0184800);
43
+
44
+ const createDmabufHeapIoctls = ({
45
+ kernelIoctlInterface
46
+ }/*: {
47
+ kernelIoctlInterface: TDmabufHeapIoctlKernelInterface
48
+ }*/) => {
49
+ const dmabufHeapIoctlAllocate = ({
50
+ dmabufHeapFd,
51
+ size,
52
+ fdFlags,
53
+ heapFlags
54
+ }/*: {
55
+ dmabufHeapFd: number;
56
+ size: number;
57
+ fdFlags: bigint;
58
+ heapFlags: bigint;
59
+ }*/)/*: TDmabufHeapIoctlAllocateResult*/ => {
60
+
61
+ const allocationData = formatAllocationData({
62
+ endianness: kernelIoctlInterface.endianness,
63
+ len: size,
64
+ fdFlags,
65
+ heapFlags
66
+ });
67
+
68
+ const { errno } = kernelIoctlInterface.ioctl({
69
+ fd: dmabufHeapFd,
70
+ request: DMA_HEAP_IOCTL_ALLOC,
71
+ arg: allocationData
72
+ });
73
+
74
+ if (errno !== undefined) {
75
+ return {
76
+ errno,
77
+ dmabufFd: undefined
78
+ };
79
+ }
80
+
81
+ const view = endianBufferViewFor({ buffer: allocationData, endianness: kernelIoctlInterface.endianness });
82
+ const dmabufFd = view.readU32({ offset: 8 });
83
+
84
+ return {
85
+ errno: undefined,
86
+ dmabufFd
87
+ };
88
+ };
89
+
90
+ return {
91
+ dmabufHeapIoctlAllocate
92
+ };
93
+ };
94
+
95
+ export {
96
+ createDmabufHeapIoctls
97
+ };
@@ -0,0 +1,42 @@
1
+ import { type TDmabufHeap } from "./dmabuf-heap.js";
2
+ import type { TDmabufHeapKernelInterface } from "../kernel-interface.js";
3
+ declare const findDefaultDmabufHeapDevFolder: () => string;
4
+ type TDmabufHeapInfo = {
5
+ name: string;
6
+ properties: {
7
+ physicalMemory: {
8
+ contiguous: boolean | undefined;
9
+ };
10
+ cachable: boolean | undefined;
11
+ protected: boolean | undefined;
12
+ };
13
+ };
14
+ type TDmabufHeapPropertySpecification = "required" | "preferred" | "optional" | "forbidden";
15
+ type TDmabufHeapSpecification = {
16
+ physicalMemory: {
17
+ contiguous: TDmabufHeapPropertySpecification;
18
+ };
19
+ cachable: TDmabufHeapPropertySpecification;
20
+ protected: TDmabufHeapPropertySpecification;
21
+ };
22
+ declare const createDmabufHeapManager: ({ dmabufHeapDevFolder, kernelInterface }: {
23
+ dmabufHeapDevFolder: string;
24
+ kernelInterface: TDmabufHeapKernelInterface;
25
+ }) => {
26
+ findAvailableDmabufHeapInfos: () => TDmabufHeapInfo[];
27
+ findDmabufHeapInfosBySpecification: ({ specification }: {
28
+ specification: TDmabufHeapSpecification;
29
+ }) => any;
30
+ openDmabufHeapByName: ({ name }: {
31
+ name: string;
32
+ }) => {
33
+ error: Error;
34
+ dmabufHeap: undefined;
35
+ } | {
36
+ error: undefined;
37
+ dmabufHeap: TDmabufHeap;
38
+ };
39
+ };
40
+ type TDmabufHeapManager = ReturnType<typeof createDmabufHeapManager>;
41
+ export { findDefaultDmabufHeapDevFolder, createDmabufHeapManager };
42
+ export type { TDmabufHeapManager, };
@@ -0,0 +1,215 @@
1
+ import { createDmabufHeapFactory, /*type TDmabufHeap */} from "./dmabuf-heap.js";
2
+ /*import type { TDmabufHeapKernelInterface } from "../kernel-interface.ts";*/
3
+
4
+ const findDefaultDmabufHeapDevFolder = ()/*: string*/ => {
5
+ return "/dev/dma_heap";
6
+ };
7
+
8
+ /*type TDmabufHeapInfo = {
9
+ name: string;
10
+ properties: {
11
+ physicalMemory: {
12
+ contiguous: boolean | undefined;
13
+ },
14
+ cachable: boolean | undefined;
15
+ protected: boolean | undefined;
16
+ }
17
+ };*/
18
+
19
+ /*type TDmabufHeapPropertySpecification = "required" | "preferred" | "optional" | "forbidden";*/
20
+ /*type TDmabufHeapSpecification = {
21
+ physicalMemory: {
22
+ contiguous: TDmabufHeapPropertySpecification;
23
+ },
24
+ cachable: TDmabufHeapPropertySpecification;
25
+ protected: TDmabufHeapPropertySpecification;
26
+ };*/
27
+
28
+ const wellKnownHeapPropertiesByName/*: { [key: string]: TDmabufHeapInfo["properties"] }*/ = {
29
+ // eslint-disable-next-line quote-props
30
+ "system": {
31
+ physicalMemory: {
32
+ contiguous: false
33
+ },
34
+ cachable: true,
35
+ protected: false
36
+ },
37
+ // eslint-disable-next-line quote-props
38
+ "default_cma_region": {
39
+ physicalMemory: {
40
+ contiguous: true
41
+ },
42
+ cachable: true,
43
+ protected: false
44
+ }
45
+ };
46
+
47
+ const heapInfoByName = ({ name }/*: { name: string }*/)/*: TDmabufHeapInfo*/ => {
48
+ const wellKnownProperties = wellKnownHeapPropertiesByName[name];
49
+ if (wellKnownProperties === undefined) {
50
+ return {
51
+ name,
52
+ properties: {
53
+ physicalMemory: {
54
+ contiguous: undefined
55
+ },
56
+ cachable: undefined,
57
+ protected: undefined
58
+ }
59
+ };
60
+ }
61
+
62
+ return {
63
+ name,
64
+ properties: wellKnownProperties
65
+ };
66
+ };
67
+
68
+ const createDmabufHeapManager = ({
69
+ dmabufHeapDevFolder,
70
+ kernelInterface
71
+ }/*: {
72
+ dmabufHeapDevFolder: string,
73
+ kernelInterface: TDmabufHeapKernelInterface
74
+ }*/) => {
75
+
76
+ const heapFactory = createDmabufHeapFactory({ kernelInterface });
77
+
78
+ const findAvailableDmabufHeapInfos = ()/*: TDmabufHeapInfo[]*/ => {
79
+ const { errno, entries } = kernelInterface.readdir({ path: dmabufHeapDevFolder });
80
+ if (errno !== undefined) {
81
+ throw Error(`failed to read dmabuf heap dev folder ${dmabufHeapDevFolder}, errno ${errno}`);
82
+ }
83
+
84
+ const infos = entries.map((entryName) => {
85
+ return heapInfoByName({ name: entryName });
86
+ });
87
+
88
+ return infos;
89
+ };
90
+
91
+ try {
92
+ findAvailableDmabufHeapInfos();
93
+ } catch (ex) {
94
+ throw Error("valid dmabuf heap dev folder required to create dmabuf heap manager, look before you leap", { cause: ex });
95
+ }
96
+
97
+ const findDmabufHeapInfosBySpecification = ({
98
+ specification
99
+ }/*: {
100
+ specification: TDmabufHeapSpecification
101
+ }*/) => {
102
+ const availableHeaps = findAvailableDmabufHeapInfos();
103
+
104
+ // eslint-disable-next-line complexity, max-statements
105
+ const matchingHeaps = availableHeaps.filter((heapInfo) => {
106
+ const props = heapInfo.properties;
107
+
108
+ // physicalMemory.contiguous
109
+ const contiguousSpec = specification.physicalMemory.contiguous;
110
+ if (contiguousSpec === "required" && props.physicalMemory.contiguous !== true) {
111
+ return false;
112
+ }
113
+ if (contiguousSpec === "forbidden" && props.physicalMemory.contiguous === true) {
114
+ return false;
115
+ }
116
+
117
+ // cachable
118
+ const cachableSpec = specification.cachable;
119
+ if (cachableSpec === "required" && props.cachable !== true) {
120
+ return false;
121
+ }
122
+ if (cachableSpec === "forbidden" && props.cachable === true) {
123
+ return false;
124
+ }
125
+
126
+ // protected
127
+ const protectedSpec = specification.protected;
128
+ if (protectedSpec === "required" && props.protected !== true) {
129
+ return false;
130
+ }
131
+ if (protectedSpec === "forbidden" && props.protected === true) {
132
+ return false;
133
+ }
134
+
135
+ return true;
136
+ });
137
+
138
+ return matchingHeaps;
139
+ };
140
+
141
+ /*type TOpenByNameResult = {
142
+ error: Error,
143
+ dmabufHeap: undefined
144
+ } | {
145
+ error: undefined,
146
+ dmabufHeap: TDmabufHeap
147
+ };*/
148
+
149
+ const O_RDWR = 0x02;
150
+ const O_CLOEXEC = 0x80000;
151
+
152
+ const ENOENT = 2;
153
+ const EACCES = 13;
154
+
155
+ const createOpenErrorByErrno = ({ errno, dmabufHeapPath }/*: { errno: number, dmabufHeapPath: string }*/)/*: Error*/ => {
156
+
157
+ if (errno === ENOENT) {
158
+ return Error(`dmabuf heap at "${dmabufHeapPath}" does not exist`);
159
+ }
160
+
161
+ if (errno === EACCES) {
162
+ return Error(`permission denied opening dmabuf heap at "${dmabufHeapPath}", your process may lack required privileges`);
163
+ }
164
+
165
+ return Error(`open dmabuf heap at "${dmabufHeapPath}" failed, errno ${errno}`);
166
+ };
167
+
168
+ const openDmabufHeapByName = ({ name }/*: { name: string }*/)/*: TOpenByNameResult*/ => {
169
+
170
+ const dmabufHeapPath = `${dmabufHeapDevFolder}/${name}`;
171
+
172
+ const { errno: openErrno, fd: dmabufHeapFd } = kernelInterface.open({
173
+ path: dmabufHeapPath,
174
+ flags: O_RDWR | O_CLOEXEC
175
+ });
176
+
177
+ if (openErrno !== undefined) {
178
+ return {
179
+ error: createOpenErrorByErrno({ errno: openErrno, dmabufHeapPath }),
180
+ dmabufHeap: undefined
181
+ };
182
+ }
183
+
184
+ try {
185
+ const dmabufHeap = heapFactory.openDmabufHeapAllocatorByDuppingFd({
186
+ dmabufHeapFd
187
+ });
188
+
189
+ return {
190
+ error: undefined,
191
+ dmabufHeap
192
+ };
193
+ } finally {
194
+ kernelInterface.close({ fd: dmabufHeapFd });
195
+ }
196
+
197
+ };
198
+
199
+ return {
200
+ findAvailableDmabufHeapInfos,
201
+ findDmabufHeapInfosBySpecification,
202
+ openDmabufHeapByName
203
+ };
204
+ };
205
+
206
+ /*type TDmabufHeapManager = ReturnType<typeof createDmabufHeapManager>;*/
207
+
208
+ export {
209
+ findDefaultDmabufHeapDevFolder,
210
+ createDmabufHeapManager
211
+ };
212
+
213
+ /*export type {
214
+ TDmabufHeapManager,
215
+ };*/
@@ -0,0 +1,15 @@
1
+ import type { TDmabufAllocator } from "../dmabuf-allocator-interface.js";
2
+ import type { TDmabufHeapAllocatorKernelInterface } from "../kernel-interface.js";
3
+ type TDmabufHeap = TDmabufAllocator & {
4
+ dupHeapFd: () => number;
5
+ close: () => void;
6
+ };
7
+ declare const createDmabufHeapFactory: ({ kernelInterface }: {
8
+ kernelInterface: TDmabufHeapAllocatorKernelInterface;
9
+ }) => {
10
+ openDmabufHeapAllocatorByDuppingFd: ({ dmabufHeapFd: providedDmabufHeapFd }: {
11
+ dmabufHeapFd: number;
12
+ }) => TDmabufHeap;
13
+ };
14
+ export { createDmabufHeapFactory };
15
+ export type { TDmabufHeap };
@@ -0,0 +1,84 @@
1
+ /*import type { TDmabufAllocator } from "../dmabuf-allocator-interface.ts";*/
2
+ import { createDefaultAllocationSizeDeterminer } from "../allocation-size.js";
3
+ import { createDmabufHeapIoctls } from "./dmabuf-heap-ioctl.js";
4
+ /*import type { TDmabufHeapAllocatorKernelInterface } from "../kernel-interface.ts";*/
5
+ // import nodeFs from "node:fs";
6
+
7
+ /*type TDmabufHeap = TDmabufAllocator & {
8
+ dupHeapFd: () => number;
9
+ close: () => void;
10
+ };*/
11
+
12
+ const O_RDWR = BigInt(0x02);
13
+ const O_CLOEXEC = BigInt(0x80000);
14
+
15
+ const createDmabufHeapFactory = ({ kernelInterface }/*: { kernelInterface: TDmabufHeapAllocatorKernelInterface }*/) => {
16
+ const openDmabufHeapAllocatorByDuppingFd = ({
17
+ dmabufHeapFd: providedDmabufHeapFd
18
+ }/*: {
19
+ dmabufHeapFd: number
20
+ }*/)/*: TDmabufHeap*/ => {
21
+
22
+ const dmabufHeapFd = kernelInterface.dup({ fd: providedDmabufHeapFd });
23
+ const pageSize = kernelInterface.determinePageSize();
24
+
25
+ const allocationSizeDeterminer = createDefaultAllocationSizeDeterminer({ pageSize });
26
+
27
+ const { dmabufHeapIoctlAllocate } = createDmabufHeapIoctls({ kernelIoctlInterface: kernelInterface });
28
+
29
+ const determineOptimalAllocationSize/*: TDmabufHeap["determineOptimalAllocationSize"]*/ = ({ minimumSize }) => {
30
+ return allocationSizeDeterminer.determineOptimalAllocationSize({ minimumSize });
31
+ };
32
+
33
+ const allocate/*: TDmabufHeap["allocate"]*/ = ({ size }) => {
34
+
35
+ const { errno: allocateErrno, dmabufFd } = dmabufHeapIoctlAllocate({
36
+ dmabufHeapFd,
37
+ fdFlags: O_RDWR | O_CLOEXEC,
38
+ heapFlags: BigInt(0),
39
+ size
40
+ });
41
+
42
+ if (allocateErrno !== undefined) {
43
+ return {
44
+ // TODO: better
45
+ error: Error(`dmabuf heap allocation failed with errno ${allocateErrno}`),
46
+ handle: undefined
47
+ };
48
+ }
49
+
50
+ return {
51
+ error: undefined,
52
+ dmabufFd
53
+ };
54
+ };
55
+
56
+ const dupHeapFd/*: TDmabufHeap["dupHeapFd"]*/ = () => {
57
+ return kernelInterface.dup({ fd: dmabufHeapFd });
58
+ };
59
+
60
+ const close = () => {
61
+ kernelInterface.close({ fd: dmabufHeapFd });
62
+ };
63
+
64
+ return {
65
+ allocate,
66
+ pageSize,
67
+ determineOptimalAllocationSize,
68
+ dupHeapFd,
69
+ close
70
+ };
71
+ };
72
+
73
+ return {
74
+ openDmabufHeapAllocatorByDuppingFd
75
+ };
76
+ };
77
+
78
+ export {
79
+ createDmabufHeapFactory
80
+ };
81
+
82
+ /*export type {
83
+ TDmabufHeap
84
+ };*/
@@ -0,0 +1,3 @@
1
+ import { type TDmabufHeapManager } from "./dmabuf-heap-manager.js";
2
+ declare const createDefaultDmabufHeapManager: () => TDmabufHeapManager;
3
+ export { createDefaultDmabufHeapManager, };
@@ -0,0 +1,19 @@
1
+ import { createDmabufHeapManager, findDefaultDmabufHeapDevFolder, /*type TDmabufHeapManager */} from "./dmabuf-heap-manager.js";
2
+ import { createDefaultDmabufHeapAllocatorLinuxInterface } from "../kernel-interface-impl-linux.js";
3
+
4
+ const createDefaultDmabufHeapManager = ()/*: TDmabufHeapManager*/ => {
5
+ const dmabufHeapDevFolder = findDefaultDmabufHeapDevFolder();
6
+ const kernelInterface = createDefaultDmabufHeapAllocatorLinuxInterface();
7
+
8
+
9
+ const dmabufHeapManager = createDmabufHeapManager({
10
+ dmabufHeapDevFolder,
11
+ kernelInterface
12
+ });
13
+
14
+ return dmabufHeapManager;
15
+ };
16
+
17
+ export {
18
+ createDefaultDmabufHeapManager,
19
+ };
@@ -0,0 +1,54 @@
1
+ type TEndianness = "LE" | "BE";
2
+ declare const endianBufferViewFor: ({ buffer, endianness }: {
3
+ buffer: Uint8Array;
4
+ endianness: TEndianness;
5
+ }) => {
6
+ readU16: ({ offset }: {
7
+ offset: number;
8
+ }) => any;
9
+ readU32: ({ offset }: {
10
+ offset: number;
11
+ }) => any;
12
+ readU64: ({ offset }: {
13
+ offset: number;
14
+ }) => any;
15
+ writeU16: ({ offset, value }: {
16
+ offset: number;
17
+ value: number;
18
+ }) => void;
19
+ writeU32: ({ offset, value }: {
20
+ offset: number;
21
+ value: number;
22
+ }) => void;
23
+ writeU64: ({ offset, value }: {
24
+ offset: number;
25
+ value: bigint;
26
+ }) => void;
27
+ };
28
+ declare const hostEndianBufferViewFor: ({ buffer }: {
29
+ buffer: Uint8Array;
30
+ }) => {
31
+ readU16: ({ offset }: {
32
+ offset: number;
33
+ }) => any;
34
+ readU32: ({ offset }: {
35
+ offset: number;
36
+ }) => any;
37
+ readU64: ({ offset }: {
38
+ offset: number;
39
+ }) => any;
40
+ writeU16: ({ offset, value }: {
41
+ offset: number;
42
+ value: number;
43
+ }) => void;
44
+ writeU32: ({ offset, value }: {
45
+ offset: number;
46
+ value: number;
47
+ }) => void;
48
+ writeU64: ({ offset, value }: {
49
+ offset: number;
50
+ value: bigint;
51
+ }) => void;
52
+ };
53
+ export { endianBufferViewFor, hostEndianBufferViewFor };
54
+ export type { TEndianness };
@@ -0,0 +1,59 @@
1
+ import nodeOs from "node:os";
2
+
3
+ /*type TEndianness = "LE" | "BE";*/
4
+
5
+ const endianBufferViewFor = ({ buffer, endianness }/*: { buffer: Uint8Array, endianness: TEndianness }*/) => {
6
+ const dataView = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
7
+
8
+ const isLittleEndian = endianness === "LE";
9
+
10
+ const readU16 = ({ offset }/*: { offset: number }*/) => {
11
+ return dataView.getUint16(offset, isLittleEndian);
12
+ };
13
+
14
+ const readU32 = ({ offset }/*: { offset: number }*/) => {
15
+ return dataView.getUint32(offset, isLittleEndian);
16
+ };
17
+
18
+ const readU64 = ({ offset }/*: { offset: number }*/) => {
19
+ return dataView.getBigUint64(offset, isLittleEndian);
20
+ };
21
+
22
+ const writeU16 = ({ offset, value }/*: { offset: number, value: number }*/) => {
23
+ dataView.setUint16(offset, value, isLittleEndian);
24
+ };
25
+
26
+ const writeU32 = ({ offset, value }/*: { offset: number, value: number }*/) => {
27
+ dataView.setUint32(offset, value, isLittleEndian);
28
+ };
29
+
30
+ const writeU64 = ({ offset, value }/*: { offset: number, value: bigint }*/) => {
31
+ dataView.setBigUint64(offset, value, isLittleEndian);
32
+ };
33
+
34
+ return {
35
+ readU16,
36
+ readU32,
37
+ readU64,
38
+ writeU16,
39
+ writeU32,
40
+ writeU64
41
+ };
42
+ };
43
+
44
+ const determineSystemEndianness = ()/*: TEndianness*/ => {
45
+ return nodeOs.endianness();
46
+ };
47
+
48
+ const hostEndianBufferViewFor = ({ buffer }/*: { buffer: Uint8Array }*/) => {
49
+ return endianBufferViewFor({ buffer, endianness: determineSystemEndianness() });
50
+ };
51
+
52
+ export {
53
+ endianBufferViewFor,
54
+ hostEndianBufferViewFor
55
+ };
56
+
57
+ /*export type {
58
+ TEndianness
59
+ };*/
@@ -0,0 +1,2 @@
1
+ import { createDefaultDmabufHeapManager } from "./dmabuf-heap/index.js";
2
+ export { createDefaultDmabufHeapManager };
package/dist/lib/index.js CHANGED
@@ -0,0 +1,5 @@
1
+ import { createDefaultDmabufHeapManager } from "./dmabuf-heap/index.js";
2
+
3
+ export {
4
+ createDefaultDmabufHeapManager
5
+ };
@@ -0,0 +1,3 @@
1
+ import type { TDmabufHeapKernelInterface } from "./kernel-interface.js";
2
+ declare const createDefaultDmabufHeapAllocatorLinuxInterface: () => TDmabufHeapKernelInterface;
3
+ export { createDefaultDmabufHeapAllocatorLinuxInterface };
@@ -0,0 +1,75 @@
1
+ /*import type { TDmabufHeapKernelInterface } from "./kernel-interface.ts";*/
2
+ import { ioctl as nativeIoctl } from "@k13engineering/po6-ioctl";
3
+ import nodeFs from "node:fs";
4
+ import nodeOs from "node:os";
5
+ import { syscall, syscallNumbers } from "syscall-napi";
6
+
7
+ const createDefaultDmabufHeapAllocatorLinuxInterface = ()/*: TDmabufHeapKernelInterface*/ => {
8
+
9
+ /*type C = TDmabufHeapKernelInterface;*/
10
+
11
+ const endianness = nodeOs.endianness();
12
+
13
+ const determinePageSize/*: C["determinePageSize"]*/ = () => {
14
+ // TODO: get from system
15
+ return 4096;
16
+ };
17
+
18
+ const ioctl/*: C["ioctl"]*/ = ({ fd, request, arg }) => {
19
+ const { errno } = nativeIoctl({ fd, request, arg });
20
+ return { errno };
21
+ };
22
+
23
+ const dup = ({ fd }/*: { fd: number }*/)/*: number*/ => {
24
+ const { errno, ret: newFd } = syscall({
25
+ syscallNumber: syscallNumbers.dup,
26
+ args: [
27
+ BigInt(fd)
28
+ ]
29
+ });
30
+
31
+ if (errno !== undefined) {
32
+ throw Error(`dup failed with errno ${errno}`);
33
+ }
34
+
35
+ return Number(newFd);
36
+ };
37
+
38
+ const readdir/*: C["readdir"]*/ = ({ path }) => {
39
+ try {
40
+ const entries = nodeFs.readdirSync(path);
41
+ return { errno: undefined, entries };
42
+ } catch (ex) {
43
+ const err = ex /*as NodeJS.ErrnoException*/;
44
+ return { errno: -err.errno/*!*/, entries: undefined };
45
+ }
46
+ };
47
+
48
+ const open/*: C["open"]*/ = ({ path, flags }) => {
49
+ try {
50
+ const fd = nodeFs.openSync(path, flags);
51
+ return { errno: undefined, fd };
52
+ } catch (ex) {
53
+ const err = ex /*as NodeJS.ErrnoException*/;
54
+ return { errno: -err.errno/*!*/, fd: undefined };
55
+ }
56
+ };
57
+
58
+ const close/*: C["close"]*/ = ({ fd }) => {
59
+ nodeFs.closeSync(fd);
60
+ };
61
+
62
+ return {
63
+ endianness,
64
+ determinePageSize,
65
+ ioctl,
66
+ dup,
67
+ readdir,
68
+ open,
69
+ close
70
+ };
71
+ };
72
+
73
+ export {
74
+ createDefaultDmabufHeapAllocatorLinuxInterface
75
+ };
@@ -0,0 +1,39 @@
1
+ type TDmabufHeapKernelInterface = {
2
+ endianness: "LE" | "BE";
3
+ determinePageSize: () => number;
4
+ ioctl: (args: {
5
+ fd: number;
6
+ request: bigint;
7
+ arg: Uint8Array;
8
+ }) => {
9
+ errno: undefined | number;
10
+ };
11
+ dup: (args: {
12
+ fd: number;
13
+ }) => number;
14
+ close: (args: {
15
+ fd: number;
16
+ }) => void;
17
+ readdir: ({ path }: {
18
+ path: string;
19
+ }) => {
20
+ errno: undefined;
21
+ entries: string[];
22
+ } | {
23
+ errno: number;
24
+ entries: undefined;
25
+ };
26
+ open: (args: {
27
+ path: string;
28
+ flags: number;
29
+ }) => {
30
+ errno: undefined;
31
+ fd: number;
32
+ } | {
33
+ errno: number;
34
+ fd: undefined;
35
+ };
36
+ };
37
+ type TDmabufHeapAllocatorKernelInterface = Pick<TDmabufHeapKernelInterface, "endianness" | "determinePageSize" | "ioctl" | "dup" | "close">;
38
+ type TDmabufHeapIoctlKernelInterface = Pick<TDmabufHeapKernelInterface, "endianness" | "ioctl">;
39
+ export type { TDmabufHeapKernelInterface, TDmabufHeapAllocatorKernelInterface, TDmabufHeapIoctlKernelInterface };
@@ -0,0 +1,32 @@
1
+ /* c8 ignore start */
2
+ /*type TDmabufHeapKernelInterface = {
3
+ endianness: "LE" | "BE";
4
+ determinePageSize: () => number;
5
+ ioctl: (args: { fd: number; request: bigint, arg: Uint8Array }) => { errno: undefined | number };
6
+ dup: (args: { fd: number }) => number;
7
+ close: (args: { fd: number }) => void;
8
+
9
+ // dmabuf heap listing
10
+ readdir: ({ path }: { path: string }) => { errno: undefined, entries: string[] } | { errno: number, entries: undefined };
11
+ open: (args: { path: string, flags: number }) => { errno: undefined, fd: number } | { errno: number, fd: undefined };
12
+ };*/
13
+
14
+ /*type TDmabufHeapAllocatorKernelInterface = Pick<TDmabufHeapKernelInterface,
15
+ "endianness" |
16
+ "determinePageSize" |
17
+ "ioctl" |
18
+ "dup" |
19
+ "close"
20
+ >;*/
21
+
22
+ /*type TDmabufHeapIoctlKernelInterface = Pick<TDmabufHeapKernelInterface,
23
+ "endianness" |
24
+ "ioctl"
25
+ >;*/
26
+
27
+ /*export type {
28
+ TDmabufHeapKernelInterface,
29
+ TDmabufHeapAllocatorKernelInterface,
30
+ TDmabufHeapIoctlKernelInterface
31
+ };*/
32
+ /* c8 ignore stop */
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.0.1",
2
+ "version": "0.0.3",
3
3
  "name": "@k13engineering/linux-dmabuf-allocator",
4
4
  "type": "module",
5
5
  "description": "Linux dmabuf allocator module",