Subversion Repositories Kolibri OS

Rev

Rev 886 | Rev 889 | 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
 
888 serge 9
10
 
859 serge 11
{
12
   link_t link;
13
   link_t adj;
14
   addr_t base;
15
   size_t size;
16
    void   *parent;
888 serge 17
   u32_t  state;
886 serge 18
}md_t;
859 serge 19
20
 
886 serge 21
#define   MD_USED    2
22
23
 
859 serge 24
    u32_t  av_mapped;
888 serge 25
    u32_t  av_unmapped;
26
859 serge 27
 
888 serge 28
    link_t unmapped[32];
29
886 serge 30
 
31
888 serge 32
 
33
}heap_t;
859 serge 34
35
 
886 serge 36
 
859 serge 37
slab_cache_t *phm_slab;
38
39
 
40
 
886 serge 41
heap_t        sheap;
42
43
 
44
 
888 serge 45
{ asm volatile ("bts %0, _lheap+4"::"r"(idx):"cc"); }
46
886 serge 47
 
888 serge 48
{ asm volatile ("btr %0, _lheap+4"::"r"(idx):"cc"); }
49
859 serge 50
 
888 serge 51
{ asm volatile ("bts %0, _sheap"::"r"(idx):"cc"); }
886 serge 52
859 serge 53
 
888 serge 54
{ asm volatile ("btr %0, _sheap"::"r"(idx):"cc"); }
886 serge 55
859 serge 56
 
888 serge 57
{ asm volatile ("bts %0, _sheap+4"::"r"(idx):"cc"); }
58
859 serge 59
 
888 serge 60
{ asm volatile ("btr %0, _sheap+4"::"r"(idx):"cc"); }
61
62
 
63
 
859 serge 64
{
65
   md_t *md;
66
   u32_t i;
67
68
 
69
   ASSERT(size != 0)
70
   ASSERT((base & 0x3FFFFF) == 0);
862 serge 71
   ASSERT((size & 0x3FFFFF) == 0);
72
859 serge 73
 
74
   {
75
        list_initialize(&lheap.mapped[i]);
888 serge 76
        list_initialize(&lheap.unmapped[i]);
77
78
 
79
        list_initialize(&sheap.unmapped[i]);
80
   };
859 serge 81
82
 
886 serge 83
   list_initialize(&sheap.used);
84
85
 
86
 
859 serge 87
88
 
89
90
 
91
   md->base = base;
92
   md->size = size;
93
   md->parent = NULL;
94
   md->state = MD_FREE;
886 serge 95
859 serge 96
 
888 serge 97
    lheap.av_mapped    = 0x00000000;
98
    lheap.av_unmapped  = 0x80000000;
99
    sheap.av_mapped    = 0x00000000;
100
    sheap.av_unmapped  = 0x00000000;
101
859 serge 102
 
103
};
104
105
 
106
{
107
   md_t *md = NULL;
108
109
 
110
   u32_t mask;
111
112
 
862 serge 113
859 serge 114
 
115
    mask = lheap.av_unmapped & ( -1<
888 serge 116
859 serge 117
 
118
   {
119
     if(idx0 == 31)
862 serge 120
     {
121
            md_t *tmp = (md_t*)lheap.unmapped[31].next;
888 serge 122
            while((link_t*)tmp != &lheap.unmapped[31])
123
        {
862 serge 124
          if(tmp->size >= size)
125
          {
126
            DBG("remove large tmp %x\n", tmp);
127
859 serge 128
 
862 serge 129
            break;
130
          };
131
        };
132
        tmp = (md_t*)tmp->link.next;
133
     }
134
     else
135
     {
136
       idx0 = _bsf(mask);
137
859 serge 138
 
888 serge 139
862 serge 140
 
888 serge 141
     };
862 serge 142
   }
859 serge 143
   else
144
     return NULL;
145
146
 
886 serge 147
148
 
859 serge 149
    if(list_empty(&lheap.unmapped[idx0]))
888 serge 150
        _reset_lavu(idx0);
151
859 serge 152
 
153
   {
154
     count_t idx1;
155
     md_t *new_md = (md_t*)slab_alloc(md_slab,0);         /* FIXME check */
886 serge 156
859 serge 157
 
158
     list_insert(&new_md->adj, &md->adj);
861 serge 159
859 serge 160
 
161
     new_md->size = size;
162
        new_md->parent = NULL;
888 serge 163
     new_md->state = MD_USED;
886 serge 164
859 serge 165
 
166
     md->size-= size;
167
168
 
169
170
 
888 serge 171
        _set_lavu(idx1);
172
859 serge 173
 
174
   };
886 serge 175
   md->state = MD_USED;
176
177
 
859 serge 178
}
179
180
 
888 serge 181
{
859 serge 182
    eflags_t efl;
886 serge 183
859 serge 184
 
886 serge 185
859 serge 186
 
886 serge 187
    u32_t mask;
188
859 serge 189
 
886 serge 190
859 serge 191
 
886 serge 192
859 serge 193
 
886 serge 194
    mask = sheap.av_unmapped & ( -1<
888 serge 195
859 serge 196
 
888 serge 197
861 serge 198
 
886 serge 199
    {
200
        if(idx0 == 31)
201
        {
862 serge 202
            ASSERT( !list_empty(&sheap.unmapped[31]));
888 serge 203
886 serge 204
 
888 serge 205
            while((link_t*)tmp != &sheap.unmapped[31])
206
            {
886 serge 207
                if(tmp->size >= size)
208
                {
209
                    md = tmp;
210
                    break;
211
                };
212
                tmp = (md_t*)tmp->link.next;
213
            };
214
        }
215
        else
216
        {
217
            idx0 = _bsf(mask);
218
219
 
888 serge 220
886 serge 221
 
888 serge 222
        }
886 serge 223
    };
224
225
 
226
    {
227
        DBG("remove md %x\n", md);
228
229
 
230
        ASSERT(md->parent != NULL);
888 serge 231
886 serge 232
 
233
        if(list_empty(&sheap.unmapped[idx0]))
888 serge 234
            _reset_savu(idx0);
235
    }
886 serge 236
    else
237
    {
238
        md_t *lmd;
239
        lmd = find_large_md((size+0x3FFFFF)&~0x3FFFFF);
240
241
 
242
243
 
244
        {
245
            safe_sti(efl);
246
            return NULL;
247
        };
862 serge 248
861 serge 249
 
888 serge 250
        ASSERT(lmd->base != 0);
251
        ASSERT((lmd->base & 0x3FFFFF) == 0);
252
        ASSERT(lmd->parent == NULL);
253
254
 
886 serge 255
862 serge 256
 
886 serge 257
        list_initialize(&md->adj);
258
        md->base = lmd->base;
259
        md->size = lmd->size;
260
        md->parent  = lmd;
261
        md->state = MD_USED;
262
    };
263
862 serge 264
 
886 serge 265
    {
266
        count_t idx1;
267
        md_t *new_md = (md_t*)slab_alloc(md_slab,0);    /* FIXME check */
268
862 serge 269
 
886 serge 270
        list_insert(&new_md->adj, &md->adj);
271
859 serge 272
 
886 serge 273
        new_md->size = size;
274
        new_md->parent = md->parent;
275
        new_md->state = MD_USED;
276
859 serge 277
 
886 serge 278
        md->size-= size;
279
        md->state = MD_FREE;
280
859 serge 281
 
886 serge 282
859 serge 283
 
886 serge 284
859 serge 285
 
886 serge 286
          list_prepend(&md->link, &sheap.unmapped[idx1]);
888 serge 287
        else
886 serge 288
        {
289
            if( list_empty(&sheap.unmapped[31]))
888 serge 290
                list_prepend(&md->link, &sheap.unmapped[31]);
291
            else
886 serge 292
            {
293
                md_t *tmp = (md_t*)sheap.unmapped[31].next;
888 serge 294
859 serge 295
 
888 serge 296
                {
886 serge 297
                    if(md->base < tmp->base)
298
                        break;
299
                    tmp = (md_t*)tmp->link.next;
300
                }
301
                list_insert(&md->link, &tmp->link);
302
            };
303
        };
304
859 serge 305
 
888 serge 306
861 serge 307
 
886 serge 308
861 serge 309
 
886 serge 310
    };
311
861 serge 312
 
886 serge 313
859 serge 314
 
886 serge 315
859 serge 316
 
886 serge 317
}
859 serge 318
319
 
888 serge 320
{
886 serge 321
    eflags_t efl;
888 serge 322
323
 
324
325
 
326
    u32_t mask;
327
328
 
329
330
 
331
332
 
333
    mask = sheap.av_mapped & ( -1<
334
335
 
336
         idx0, mask);
337
338
 
339
    {
340
        if(idx0 == 31)
341
        {
342
            ASSERT( !list_empty(&sheap.mapped[31]));
343
344
 
345
            while((link_t*)tmp != &sheap.mapped[31])
346
            {
347
                if(tmp->size >= size)
348
                {
349
                    md = tmp;
350
                    break;
351
                };
352
                tmp = (md_t*)tmp->link.next;
353
            };
354
        }
355
        else
356
        {
357
            idx0 = _bsf(mask);
358
359
 
360
361
 
362
        }
363
    };
364
365
 
366
    {
367
        DBG("remove md %x\n", md);
368
369
 
370
371
 
372
        if(list_empty(&sheap.mapped[idx0]))
373
            _reset_savm(idx0);
374
    }
375
    else
376
    {
377
        md_t    *lmd;
378
        addr_t  frame;
379
        addr_t  *pte;
380
        int i;
381
382
 
383
384
 
385
386
 
387
        {
388
            safe_sti(efl);
389
            return NULL;
390
        };
391
392
 
393
        ASSERT(lmd->base != 0);
394
        ASSERT((lmd->base & 0x3FFFFF) == 0);
395
        ASSERT(lmd->parent == NULL);
396
397
 
398
399
 
400
401
 
402
403
 
404
        {
405
           *pte++ = frame;
406
           frame+= 4096;
407
        }
408
409
 
410
411
 
412
        list_initialize(&md->adj);
413
        md->base = lmd->base;
414
        md->size = lmd->size;
415
        md->parent  = lmd;
416
        md->state = MD_USED;
417
    };
418
419
 
420
    {
421
        count_t idx1;
422
        md_t *new_md = (md_t*)slab_alloc(md_slab,0);    /* FIXME check */
423
424
 
425
        list_insert(&new_md->adj, &md->adj);
426
427
 
428
        new_md->size = size;
429
        new_md->parent = md->parent;
430
431
 
432
        md->size-= size;
433
        md->state = MD_FREE;
434
435
 
436
437
 
438
439
 
440
          list_prepend(&md->link, &sheap.mapped[idx1]);
441
        else
442
        {
443
            if( list_empty(&sheap.mapped[31]))
444
                list_prepend(&md->link, &sheap.mapped[31]);
445
            else
446
            {
447
                md_t *tmp = (md_t*)sheap.mapped[31].next;
448
449
 
450
                {
451
                    if(md->base < tmp->base)
452
                        break;
453
                    tmp = (md_t*)tmp->link.next;
454
                }
455
                list_insert(&md->link, &tmp->link);
456
            };
457
        };
458
459
 
460
461
 
462
    };
463
464
 
465
466
 
467
468
 
469
}
470
471
 
472
{
473
    eflags_t  efl ;
886 serge 474
    md_t     *fd;
475
    md_t     *bk;
476
    count_t   idx;
477
478
 
888 serge 479
480
 
886 serge 481
    spinlock_lock(&sheap.lock);
482
483
 
484
    {
485
        bk = (md_t*)md->adj.prev;
486
        fd = (md_t*)md->adj.next;
487
488
 
489
        {
490
            idx = (fd->size>>12) - 1 < 32 ? (fd->size>>12) - 1 : 31;
491
492
 
493
            if(list_empty(&sheap.unmapped[idx]))
888 serge 494
                _reset_savu(idx);
495
886 serge 496
 
497
            md->adj.next = fd->adj.next;
498
            md->adj.next->prev = (link_t*)md;
499
            slab_free(md_slab, fd);
500
        };
501
        if(bk->state == MD_FREE)
502
        {
503
            idx = (bk->size>>12) - 1 < 32 ? (bk->size>>12) - 1 : 31;
504
505
 
506
            if(list_empty(&sheap.unmapped[idx]))
888 serge 507
                _reset_savu(idx);
508
886 serge 509
 
510
            bk->adj.next = md->adj.next;
511
            bk->adj.next->prev = (link_t*)bk;
512
            slab_free(md_slab, md);
513
            md = fd;
514
        };
515
    };
516
517
 
518
519
 
520
521
 
888 serge 522
886 serge 523
 
524
        list_prepend(&md->link, &sheap.unmapped[idx]);
888 serge 525
    else
886 serge 526
    {
527
        if( list_empty(&sheap.unmapped[31]))
888 serge 528
            list_prepend(&md->link, &sheap.unmapped[31]);
529
        else
886 serge 530
        {
531
            md_t *tmp = (md_t*)sheap.unmapped[31].next;
888 serge 532
886 serge 533
 
888 serge 534
            {
886 serge 535
                if(md->base < tmp->base)
536
                    break;
537
                tmp = (md_t*)tmp->link.next;
538
            }
539
            list_insert(&md->link, &tmp->link);
540
        };
541
    };
542
    spinlock_unlock(&sheap.lock);
543
    safe_sti(efl);
544
545
 
546
547
 
888 serge 548
{
549
    eflags_t  efl ;
550
    md_t     *fd;
551
    md_t     *bk;
552
    count_t   idx;
553
886 serge 554
 
888 serge 555
    ASSERT( ((md_t*)(md->parent))->parent != NULL);
556
886 serge 557
 
888 serge 558
    spinlock_lock(&sheap.lock);
559
859 serge 560
 
888 serge 561
    {
562
        bk = (md_t*)md->adj.prev;
563
        fd = (md_t*)md->adj.next;
564
565
 
566
   {
859 serge 567
            idx = (fd->size>>12) - 1 < 32 ? (fd->size>>12) - 1 : 31;
888 serge 568
859 serge 569
 
888 serge 570
            if(list_empty(&sheap.mapped[idx]))
571
                _reset_savm(idx);
572
859 serge 573
 
888 serge 574
            md->adj.next = fd->adj.next;
575
            md->adj.next->prev = (link_t*)md;
576
            slab_free(md_slab, fd);
577
        };
578
        if(bk->state == MD_FREE)
579
        {
580
            idx = (bk->size>>12) - 1 < 32 ? (bk->size>>12) - 1 : 31;
581
859 serge 582
 
888 serge 583
            if(list_empty(&sheap.mapped[idx]))
584
                _reset_savm(idx);
585
586
 
587
            bk->adj.next = md->adj.next;
588
            bk->adj.next->prev = (link_t*)bk;
589
            slab_free(md_slab, md);
590
            md = fd;
591
        };
592
   };
859 serge 593
594
 
888 serge 595
859 serge 596
 
888 serge 597
859 serge 598
 
888 serge 599
859 serge 600
 
888 serge 601
        list_prepend(&md->link, &sheap.mapped[idx]);
602
    else
603
    {
604
        if( list_empty(&sheap.mapped[31]))
605
            list_prepend(&md->link, &sheap.mapped[31]);
606
        else
607
   {
859 serge 608
            md_t *tmp = (md_t*)sheap.mapped[31].next;
888 serge 609
859 serge 610
 
888 serge 611
     {
859 serge 612
                if(md->base < tmp->base)
888 serge 613
                    break;
614
                tmp = (md_t*)tmp->link.next;
615
   }
859 serge 616
            list_insert(&md->link, &tmp->link);
888 serge 617
        };
618
    };
619
    spinlock_unlock(&sheap.lock);
620
    safe_sti(efl);
621
};
859 serge 622
623
 
888 serge 624
 
886 serge 625
{
859 serge 626
    eflags_t efl;
886 serge 627
859 serge 628
 
886 serge 629
859 serge 630
 
886 serge 631
632
 
633
634
 
635
636
 
888 serge 637
    {
886 serge 638
        md = find_mapped_md(size);
888 serge 639
886 serge 640
 
888 serge 641
            return NULL;
642
886 serge 643
 
888 serge 644
886 serge 645
 
888 serge 646
        ASSERT( lmd->parent != NULL);
647
886 serge 648
 
888 serge 649
                         (flags & 0xFFF);
650
        DBG("frame %x\n", frame);
651
        ASSERT(frame != 0);
652
886 serge 653
 
888 serge 654
        addr_t  *pte = &((addr_t*)page_tabs)[md->base>>12];
655
656
 
657
                {
886 serge 658
                    *pte++ = frame;
659
                    frame+= 4096;
660
                };
661
    }
888 serge 662
    else
663
        md = find_unmapped_md(size);
664
886 serge 665
 
888 serge 666
        return NULL;
667
668
 
669
    ASSERT(md->state == MD_USED);
670
671
 
672
 
886 serge 673
        spinlock_lock(&sheap.lock);
674
675
 
676
            list_prepend(&md->link, &sheap.used);
677
        else
678
        {
679
            md_t *tmp = (md_t*)sheap.used.next;
680
681
 
682
            {
683
                if(md->base < tmp->base)
684
                    break;
685
                tmp = (md_t*)tmp->link.next;
686
            }
687
            list_insert(&md->link, &tmp->link);
688
        };
689
690
 
691
        safe_sti(efl);
692
693
 
694
        return (void*)md->base;
695
};
859 serge 696
697
 
886 serge 698
{
859 serge 699
    eflags_t efl;
886 serge 700
859 serge 701
 
886 serge 702
    md_t *md = NULL;
703
859 serge 704
 
886 serge 705
861 serge 706
 
886 serge 707
    ASSERT( ((addr_t)mem & 0xFFF) == 0 );
708
    ASSERT( ! list_empty(&sheap.used));
709
862 serge 710
 
886 serge 711
864 serge 712
 
886 serge 713
864 serge 714
 
886 serge 715
    {
716
        if( tmp->base == (addr_t)mem )
717
        {
718
            md = tmp;
719
            break;
720
        };
721
        tmp = (md_t*)tmp->link.next;
722
    }
723
864 serge 724
 
886 serge 725
    {
726
        md_t *lmd;
888 serge 727
728
 
886 serge 729
859 serge 730
 
886 serge 731
864 serge 732
 
888 serge 733
734
 
735
736
 
737
738
 
739
        {
740
        count_t tmp  = md->size >> 12;
886 serge 741
        addr_t  *pte = &((addr_t*)page_tabs)[md->base>>12];
742
743
 
744
        {
745
            *pte++ = 0;
746
            asm volatile (
747
                "invlpg (%0)"
748
                    ::"r" (mem) );
888 serge 749
            mem+= 4096;
886 serge 750
        };
751
888 serge 752
 
753
        }
754
        else
755
            free_unmapped_md( md );
756
    }
886 serge 757
    else
758
        DBG("\tERROR: invalid base address: %x\n", mem);
759
760
 
761
};
762