Subversion Repositories Kolibri OS

Rev

Rev 1066 | 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
7
 
1066 serge 8
888 serge 9
 
1066 serge 10
#define HF_SIZE     (1 << HF_WIDTH)
11
886 serge 12
 
1066 serge 13
859 serge 14
 
1066 serge 15
886 serge 16
 
1066 serge 17
888 serge 18
 
859 serge 19
 
1066 serge 20
	  (index_t)( (frame) - z_heap.frames)
21
886 serge 22
 
1066 serge 23
	  (index_t)( (frame) - z_heap.frames)
24
859 serge 25
 
26
 
1066 serge 27
{
28
	frame->refcount = 1;
29
	frame->buddy_order = 0;
30
}
31
886 serge 32
 
1066 serge 33
    ((frame_t*)(block))->buddy_order
34
886 serge 35
 
36
 
1066 serge 37
     ((frame_t*)(block))->buddy_order = (order)
38
859 serge 39
 
1066 serge 40
    ((frame_t*)(block))->refcount = 1
41
859 serge 42
 
43
 
1066 serge 44
{
45
    frame_t *frame_l, *frame_r;
46
859 serge 47
 
1066 serge 48
	frame_r = (frame_l + (1 << (frame_l->buddy_order - 1)));
49
888 serge 50
 
1066 serge 51
}
52
888 serge 53
 
1066 serge 54
{
859 serge 55
	frame_t *frame1, *frame2;
1066 serge 56
859 serge 57
 
1066 serge 58
    frame2 = (frame_t*)block_2;
59
859 serge 60
 
1066 serge 61
}
62
888 serge 63
 
859 serge 64
 
1066 serge 65
  (((heap_index_abs((frame)) >> (frame)->buddy_order) & 0x1) == 0)
66
886 serge 67
 
1066 serge 68
	(((heap_index_abs((frame)) >> (frame)->buddy_order) & 0x1) == 1)
69
886 serge 70
 
859 serge 71
 
1066 serge 72
{
73
	frame_t *frame;
74
	index_t index;
75
    u32_t is_left, is_right;
76
859 serge 77
 
1066 serge 78
 //   ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame),frame->buddy_order));
79
859 serge 80
 
1066 serge 81
	is_right = IS_BUDDY_RIGHT_BLOCK_ABS( frame);
82
859 serge 83
 
1066 serge 84
859 serge 85
 
1066 serge 86
        index = (heap_index(frame)) + (1 << frame->buddy_order);
87
    }
88
    else {    /* if (is_right) */
89
        index = (heap_index(frame)) - (1 << frame->buddy_order);
90
    };
91
859 serge 92
 
93
 
1066 serge 94
	{
95
		if (z_heap.frames[index].buddy_order == frame->buddy_order &&
96
		    z_heap.frames[index].refcount == 0) {
97
			return &z_heap.frames[index].buddy_link;
98
		}
99
	}
100
859 serge 101
 
1066 serge 102
}
103
889 serge 104
 
859 serge 105
 
1066 serge 106
{
107
    link_t *buddy, *hlp;
108
    u32_t i;
109
862 serge 110
 
1066 serge 111
	 * Determine block's order.
112
	 */
113
    i = buddy_get_order(block);
114
859 serge 115
 
1066 serge 116
886 serge 117
 
1066 serge 118
    {
889 serge 119
		/*
1066 serge 120
		 * See if there is any buddy in the list of order i.
121
		 */
122
        buddy = find_buddy( block );
123
		if (buddy)
124
		{
125
859 serge 126
 
1066 serge 127
			/*
128
			 * Remove buddy from the list of order i.
129
			 */
130
			list_remove(buddy);
131
859 serge 132
 
1066 serge 133
			 * Invalidate order of both block and buddy.
134
			 */
135
            buddy_set_order(block, BUDDY_SYSTEM_INNER_BLOCK);
136
            buddy_set_order(buddy, BUDDY_SYSTEM_INNER_BLOCK);
137
859 serge 138
 
1066 serge 139
			 * Coalesce block and buddy into one block.
140
			 */
141
            hlp = buddy_coalesce( block, buddy );
142
859 serge 143
 
1066 serge 144
			 * Set order of the coalesced block to i + 1.
145
			 */
146
            buddy_set_order(hlp, i + 1);
147
859 serge 148
 
1066 serge 149
			 * Recursively add the coalesced block to the list of order i + 1.
150
			 */
151
            buddy_system_free( hlp );
152
			return;
153
		}
154
	}
155
	/*
156
	 * Insert block into the list of order i.
157
	 */
158
    list_append(block, &z_heap.order[i]);
159
}
160
859 serge 161
 
886 serge 162
 
1066 serge 163
{
859 serge 164
	link_t *res, *hlp;
1066 serge 165
859 serge 166
 
1066 serge 167
859 serge 168
 
1066 serge 169
	 * If the list of order i is not empty,
170
	 * the request can be immediatelly satisfied.
171
	 */
172
	if (!list_empty(&z_heap.order[i])) {
173
		res = z_heap.order[i].next;
174
		list_remove(res);
175
		buddy_mark_busy(res);
176
		return res;
177
	}
178
	/*
179
	 * If order i is already the maximal order,
180
	 * the request cannot be satisfied.
181
	 */
182
	if (i == z_heap.max_order)
183
		return NULL;
184
859 serge 185
 
1066 serge 186
	 * Try to recursively satisfy the request from higher order lists.
187
	 */
188
	hlp = buddy_system_alloc( i + 1 );
189
859 serge 190
 
1066 serge 191
	 * The request could not be satisfied
192
	 * from higher order lists.
193
	 */
194
	if (!hlp)
195
		return NULL;
196
859 serge 197
 
1066 serge 198
859 serge 199
 
1066 serge 200
	 * Bisect the block and set order of both of its parts to i.
201
	 */
202
	hlp = buddy_bisect( res );
203
861 serge 204
 
1066 serge 205
	buddy_set_order(hlp, i);
206
886 serge 207
 
1066 serge 208
	 * Return the other half to buddy system. Mark the first part
209
	 * full, so that it won't coalesce again.
210
	 */
211
	buddy_mark_busy(res);
212
	buddy_system_free( hlp );
213
886 serge 214
 
1066 serge 215
}
216
886 serge 217
 
218
 
1066 serge 219
{
220
	count_t i;
221
    count_t count;
222
886 serge 223
 
1066 serge 224
886 serge 225
 
1066 serge 226
    ASSERT( count != 0);
227
886 serge 228
 
1066 serge 229
886 serge 230
 
1066 serge 231
	z_heap.count = count;
232
	z_heap.free_count = count;
233
	z_heap.busy_count = 0;
234
861 serge 235
 
1066 serge 236
888 serge 237
 
1066 serge 238
862 serge 239
 
1066 serge 240
862 serge 241
 
1066 serge 242
        list_initialize(&z_heap.order[i]);
243
862 serge 244
 
859 serge 245
 
1066 serge 246
               count, sizeof(frame_t), PAGE_SIZE);
247
859 serge 248
 
1066 serge 249
859 serge 250
 
251
 
1066 serge 252
        return 0;
253
859 serge 254
 
255
 
1066 serge 256
		z_heap.frames[i].buddy_order=0;
257
		z_heap.frames[i].parent = NULL;
258
		z_heap.frames[i].refcount=1;
259
	}
260
859 serge 261
 
1066 serge 262
    {
263
        z_heap.frames[i].refcount = 0;
264
        buddy_system_free(&z_heap.frames[i].buddy_link);
265
    }
266
861 serge 267
 
1066 serge 268
861 serge 269
 
1066 serge 270
}
859 serge 271
272
 
1066 serge 273
{
886 serge 274
    eflags_t  efl;
1066 serge 275
    addr_t    heap = 0;
276
888 serge 277
 
1066 serge 278
    frame_t  *frame;
279
    index_t   v;
280
    int i;
281
    mmap_t   *map;
282
    count_t   pages;
283
888 serge 284
 
1066 serge 285
888 serge 286
 
1066 serge 287
888 serge 288
 
1066 serge 289
888 serge 290
 
1066 serge 291
//                           sizeof(addr_t) * pages);
292
888 serge 293
 
1066 serge 294
                           sizeof(addr_t) * pages) >> PAGE_WIDTH));
295
888 serge 296
 
1066 serge 297
298
 
299
    {
888 serge 300
        order = size >> HF_WIDTH;
1066 serge 301
888 serge 302
 
1066 serge 303
            order = fnzb(order - 1) + 1;
304
888 serge 305
 
1066 serge 306
888 serge 307
 
1066 serge 308
888 serge 309
 
1066 serge 310
888 serge 311
 
1066 serge 312
888 serge 313
 
1066 serge 314
        {
888 serge 315
            addr_t  page = 0;
1066 serge 316
            addr_t  mem;
317
888 serge 318
 
1066 serge 319
            z_heap.busy_count += (1 << order);
320
888 serge 321
 
1066 serge 322
888 serge 323
 
1066 serge 324
888 serge 325
 
1066 serge 326
888 serge 327
 
1066 serge 328
888 serge 329
 
1066 serge 330
                frame[i].parent = map;
331
888 serge 332
 
1066 serge 333
888 serge 334
 
1066 serge 335
888 serge 336
 
337
 
1066 serge 338
            addr_t  *mpte = &map->pte[0];
339
888 serge 340
 
1313 serge 341
342
 
1066 serge 343
            {
888 serge 344
345
 
1313 serge 346
347
 
348
                {
349
                    u32_t   order;
350
                    addr_t  page_frame;
351
352
 
353
                    asm volatile ("btr %0, %1" :"=r"(tmp):"r"(order):"cc");
354
355
 
356
357
 
358
                    {
359
                        *pte++  = 0; //page;
360
                        *mpte++ = page;
361
362
 
363
                        mem+=  4096;
364
                    };
365
                }
366
#else
1066 serge 367
888 serge 368
 
1313 serge 369
370
 
371
                {
372
                    *pte++  = 0;
373
                    *mpte++ = page;
374
                    asm volatile ( "invlpg (%0)" ::"r" (mem) );
375
                    mem+=  4096;
376
                };
377
#endif
378
            }
379
            else
380
            {
1066 serge 381
                while(pages--)
1313 serge 382
                {
383
                    *pte++  = 0; //page;
384
                    *mpte++ = 0;
385
888 serge 386
 
1313 serge 387
                    mem+=  4096;
388
                };
389
            }
390
888 serge 391
 
1066 serge 392
            DBG("%s %x size %d order %d\n", __FUNCTION__, heap, size, order);
393
888 serge 394
 
1066 serge 395
        }
396
886 serge 397
 
1066 serge 398
888 serge 399
 
1066 serge 400
886 serge 401
 
1066 serge 402
    };
403
886 serge 404
 
1066 serge 405
}
406
886 serge 407
 
1066 serge 408
{
409
    eflags_t     efl;
410
    frame_t     *frame;
411
    count_t      idx;
412
886 serge 413
 
1066 serge 414
886 serge 415
 
1066 serge 416
        (idx >= z_heap.base+z_heap.count)) {
417
        DBG("invalid address %x\n", addr);
418
        return;
419
    }
420
886 serge 421
 
1066 serge 422
886 serge 423
 
1066 serge 424
886 serge 425
 
1066 serge 426
886 serge 427
 
1066 serge 428
886 serge 429
 
1066 serge 430
886 serge 431
 
1066 serge 432
886 serge 433
 
1066 serge 434
    {
888 serge 435
        mmap_t  *map;
1066 serge 436
        count_t  i;
437
888 serge 438
 
1066 serge 439
859 serge 440
 
1066 serge 441
                frame[i].parent = NULL;
442
859 serge 443
 
1066 serge 444
859 serge 445
 
1066 serge 446
        z_heap.free_count += (1 << order);
447
        z_heap.busy_count -= (1 << order);
448
888 serge 449
 
1066 serge 450
        safe_sti(efl);
451
859 serge 452
 
1313 serge 453
        {
454
           i+= frame_free(map->pte[i]);
455
        }
456
859 serge 457
 
1066 serge 458
    }
459
    else
888 serge 460
    {
461
        spinlock_unlock(&z_heap.lock);
1066 serge 462
        safe_sti(efl);
463
    };
888 serge 464
};
859 serge 465
466
 
1066 serge 467
{
859 serge 468
    index_t   idx;
1066 serge 469
    frame_t  *frame;
470
    mmap_t   *map;
471
859 serge 472
 
1066 serge 473
859 serge 474
 
1066 serge 475
886 serge 476
 
1066 serge 477
886 serge 478
 
1066 serge 479
886 serge 480
 
1066 serge 481
    {
889 serge 482
        addr_t page;
1066 serge 483
886 serge 484
 
1066 serge 485
889 serge 486
 
1066 serge 487
889 serge 488
 
1066 serge 489
        {
892 serge 490
            if( page & PG_DEMAND)
1066 serge 491
            {
492
                page &= ~PG_DEMAND;
493
                page = alloc_page() | (page & 0xFFF);
494
892 serge 495
 
1066 serge 496
            };
892 serge 497
            ((addr_t*)page_tabs)[faddr >> PAGE_WIDTH] = page;
1066 serge 498
        };
499
    };
889 serge 500
};
859 serge 501
502
 
1066 serge 503