Subversion Repositories Kolibri OS

Rev

Rev 862 | Rev 886 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
859 serge 1
 
2
#include 
3
#include 
4
#include 
5
#include 
6
#include 
7
8
 
9
{
10
   link_t link;
11
   link_t adj;
12
   addr_t base;
13
   size_t size;
14
   void*  parent;
15
   u32_t  reserved;
16
}md_t;
17
18
 
19
   SPINLOCK_DECLARE(lock);   /**< this lock protects everything below */
20
21
 
22
   link_t list[32];
23
}heap_t;
24
25
 
26
slab_cache_t *phm_slab;
27
28
 
29
heap_t sheap;
30
31
 
32
{ asm volatile ("bts DWORD PTR [_lheap], %0"::"r"(idx):"cc"); }
33
34
 
35
{ asm volatile ("btr DWORD PTR [_lheap], %0"::"r"(idx):"cc"); }
36
37
 
38
{ asm volatile ("bts DWORD PTR [_sheap], %0"::"r"(idx):"cc"); }
39
40
 
41
{ asm volatile ("btr DWORD PTR [_sheap], %0"::"r"(idx):"cc"); }
42
43
 
44
 
45
{
46
   md_t *md;
47
   u32_t i;
48
49
 
50
   ASSERT(size != 0)
51
   ASSERT((base & 0x3FFFFF) == 0);
862 serge 52
   ASSERT((size & 0x3FFFFF) == 0);
53
859 serge 54
 
55
   {
56
     list_initialize(&lheap.list[i]);
57
     list_initialize(&sheap.list[i]);
58
   };
59
60
 
61
62
 
63
64
 
65
   md->base = base;
66
   md->size = size;
67
   md->parent = NULL;
68
   md->reserved = 0;
69
70
 
71
   lheap.availmask = 0x80000000;
72
   sheap.availmask = 0x00000000;
73
74
 
75
76
 
77
};
78
79
 
80
{
81
   md_t *md = NULL;
82
83
 
84
   u32_t mask;
85
86
 
862 serge 87
859 serge 88
 
89
   mask = lheap.availmask & ( -1<
90
91
 
92
   {
93
     if(idx0 == 31)
862 serge 94
     {
95
        md_t *tmp = (md_t*)lheap.list[31].next;
96
        while((link_t*)tmp != &lheap.list[31])
97
        {
98
          if(tmp->size >= size)
99
          {
100
            DBG("remove large tmp %x\n", tmp);
101
859 serge 102
 
862 serge 103
            break;
104
          };
105
        };
106
        tmp = (md_t*)tmp->link.next;
107
     }
108
     else
109
     {
110
       idx0 = _bsf(mask);
111
859 serge 112
 
862 serge 113
114
 
115
     };
116
   }
859 serge 117
   else
118
     return NULL;
119
120
 
121
   if(list_empty(&lheap.list[idx0]))
122
     _reset_lmask(idx0);
123
124
 
125
   {
126
     count_t idx1;
127
     md_t *new_md = (md_t*)slab_alloc(md_slab,0);
128
129
 
130
     list_insert(&new_md->adj, &md->adj);
861 serge 131
859 serge 132
 
133
     new_md->size = size;
134
135
 
136
     md->size-= size;
137
138
 
139
140
 
141
     _set_lmask(idx1);
142
143
 
144
   }
145
   return md;
146
}
147
148
 
149
{
150
   eflags_t efl;
151
152
 
153
154
 
155
   u32_t mask;
156
157
 
862 serge 158
859 serge 159
 
160
161
 
162
   mask = sheap.availmask & ( -1<
163
164
 
862 serge 165
861 serge 166
 
859 serge 167
   {
168
     if(idx0 == 31)
862 serge 169
     {
861 serge 170
        md_t *tmp = (md_t*)sheap.list[31].next;
862 serge 171
        while((link_t*)tmp != &sheap.list[31])
172
        {
173
          if(tmp->size >= size)
174
          {
175
             md = tmp;
176
             break;
177
          };
178
          tmp = (md_t*)tmp->link.next;
179
        };
180
     }
181
     else
182
     {
183
       idx0 = _bsf(mask);
184
       ASSERT( !list_empty(&sheap.list[idx0]))
185
       md = (md_t*)sheap.list[idx0].next;
186
     }
187
   };
861 serge 188
189
 
862 serge 190
   {
859 serge 191
     DBG("remove md %x\n", md);
862 serge 192
193
 
194
     if(list_empty(&sheap.list[idx0]))
195
       _reset_smask(idx0);
196
   }
197
   else
198
   {
199
     md_t *lmd;
859 serge 200
     lmd = find_large_md((size+0x3FFFFF)&~0x3FFFFF);
201
862 serge 202
 
203
204
 
859 serge 205
     {
206
       safe_sti(efl);
207
       return NULL;
208
     };
209
210
 
211
     link_initialize(&md->link);
212
     list_initialize(&md->adj);
213
     md->base = lmd->base;
214
     md->size = lmd->size;
215
     md->parent  = lmd;
216
     md->reserved = 0;
217
   };
218
219
 
220
   {
221
     count_t idx1;
222
     md_t *new_md = (md_t*)slab_alloc(md_slab,0);
223
224
 
225
     list_insert(&new_md->adj, &md->adj);
861 serge 226
859 serge 227
 
228
     new_md->size = size;
229
     new_md->parent = md->parent;
230
     new_md->reserved = 0;
231
232
 
233
     md->size-= size;
234
235
 
861 serge 236
859 serge 237
 
862 serge 238
861 serge 239
 
240
       list_prepend(&md->link, &sheap.list[idx1]);
241
     else
242
     {
243
       if( list_empty(&sheap.list[31]))
244
         list_prepend(&md->link, &sheap.list[31]);
245
       else
246
       {
247
         md_t *tmp = (md_t*)sheap.list[31].next;
248
249
 
250
         {
251
           if(md->base < tmp->base)
252
             break;
253
           tmp = (md_t*)tmp->link.next;
254
         }
255
         list_insert(&md->link, &tmp->link);
256
       };
257
     };
258
259
 
859 serge 260
261
 
262
263
 
264
   }
265
   safe_sti(efl);
266
   return md;
267
}
268
269
 
270
{
271
   phismem_t *phm;
272
   count_t tmp;
273
   phm = (phismem_t*)slab_alloc(phm_slab, 0);
274
275
 
276
   tmp = count;
277
   while(tmp)
278
   {
279
      u32_t order;
280
281
 
282
      asm volatile ("btr %0, %1" :"=r"(tmp):"r"(order):"cc");
283
284
 
285
286
 
287
288
 
289
}
290
291
 
292
293
 
294
{
295
   count_t count;
296
   addr_t  *pte;
297
298
 
299
   pte = &((addr_t*)page_tabs)[base>>12];
300
301
 
302
   {
303
     u32_t order;
304
     addr_t frame;
305
     count_t size;
306
307
 
308
     asm volatile ("btr %0, %1" :"=r"(count):"r"(order):"cc");
309
310
 
311
     size = (1 << order);
312
     while(size--)
313
     {
314
       *pte++ = frame;
315
       frame+= 4096;
316
     }
317
   }
318
};
319
320
 
321
{
322
   md_t *md;
323
   phismem_t *phm;
324
325
 
326
327
 
328
   if( md )
329
   {
330
     phm = phis_alloc(size>>12);
331
     map_phm(md->base , phm, flags);
862 serge 332
     return (void*)md->base;
859 serge 333
   }
334
   return NULL;
335
};
336
337
 
864 serge 338
{
859 serge 339
   md_t *md;
340
341
 
342
343
 
344
861 serge 345
 
864 serge 346
   {
347
     if( flags & PG_MAP )
348
     {
349
       count_t tmp = size >> 12;
350
       addr_t  *pte = &((addr_t*)page_tabs)[md->base>>12];
351
862 serge 352
 
864 serge 353
       {
354
         u32_t  order;
355
         addr_t frame;
356
         size_t size;
357
358
 
359
         asm volatile ("btr %0, %1" :"=r"(tmp):"r"(order):"cc");
360
361
 
362
363
 
364
         while(size--)
365
         {
366
           *pte++ = frame;
367
           frame+= 4096;
368
         };
369
       };
370
     };
371
     DBG("alloc_heap: %x size %x\n\n",md->base, size);
372
     return (void*)md->base;
859 serge 373
   };
864 serge 374
   return NULL;
859 serge 375
};
864 serge 376