1 using System;
2
3 namespace cmsx.kernel
4 {
5 public const long maxSegmentDescriptors = 4096;
6
7 public class SegmentDescriptor
8 {
9 public nothrow SegmentDescriptor() : startAddress(0u), baseAddress(0u), length(0u), increment(0u), useCount(1u), next(null)
10 {
11 }
12 public nothrow SegmentDescriptor(ulong startAddress_, ulong baseAddress_, ulong length_, ulong maxLength_, ulong increment_) :
13 startAddress(startAddress_), baseAddress(baseAddress_), length(length_), maxLength(maxLength_), increment(increment_), useCount(1u), next(null)
14 {
15 }
16 public ulong startAddress;
17 public ulong baseAddress;
18 public ulong length;
19 public ulong maxLength;
20 public ulong increment;
21 public byte useCount;
22 public SegmentDescriptor* next;
23 }
24
25 public class SegmentTable
26 {
27 static SegmentTable() : instance(new SegmentTable())
28 {
29 }
30 public static nothrow SegmentTable& Instance()
31 {
32 return *instance;
33 }
34 public nothrow SegmentDescriptor* AllocateSegmentDescriptor()
35 {
36 if (freeSegmentDescriptor != null)
37 {
38 SegmentDescriptor* sd = freeSegmentDescriptor;
39 freeSegmentDescriptor = freeSegmentDescriptor->next;
40 return sd;
41 }
42 else if (unusedSegmentDescriptorIndex < maxSegmentDescriptors)
43 {
44 SegmentDescriptor* sd = &segmentDescriptors[unusedSegmentDescriptorIndex++];
45 return sd;
46 }
47 else
48 {
49 return null;
50 }
51 }
52 public nothrow void FreeSegmentDescriptor(SegmentDescriptor* sd)
53 {
54 *sd = SegmentDescriptor();
55 sd->next = freeSegmentDescriptor;
56 freeSegmentDescriptor = sd;
57 }
58 private static UniquePtr<SegmentTable> instance;
59 private SegmentDescriptor[maxSegmentDescriptors] segmentDescriptors;
60 private SegmentDescriptor* freeSegmentDescriptor;
61 private long unusedSegmentDescriptorIndex;
62 }
63
64 public nothrow SegmentDescriptor* CreateSegmentDescriptor(ulong startAddress, ulong baseAddress, ulong length)
65 {
66 return CreateSegmentDescriptor(startAddress, baseAddress, length, length, 0u);
67 }
68
69 public nothrow SegmentDescriptor* CreateSegmentDescriptor(ulong startAddress, ulong baseAddress, ulong minLength, ulong maxLength, ulong increment)
70 {
71 SegmentDescriptor* sd = SegmentTable.Instance().AllocateSegmentDescriptor();
72 if (sd != null)
73 {
74 sd->startAddress = startAddress;
75 sd->baseAddress = baseAddress;
76 sd->length = minLength;
77 sd->maxLength = maxLength;
78 sd->increment = increment;
79 sd->useCount = 1u;
80 sd->next = null;
81 return sd;
82 }
83 else
84 {
85 return null;
86 }
87 }
88
89 public nothrow void FreeSegmentDescriptor(SegmentDescriptor* sd)
90 {
91 #assert(sd->useCount == 0);
92 if (sd->useCount == 0u)
93 {
94 SegmentTable.Instance().FreeSegmentDescriptor(sd);
95 }
96 }
97 }