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 startAddressulong baseAddressulong length)
65     {
66         return CreateSegmentDescriptor(startAddressbaseAddresslengthlength0u);
67     }
68 
69     public nothrow SegmentDescriptor* CreateSegmentDescriptor(ulong startAddressulong baseAddressulong minLengthulong maxLengthulong 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 }