Subversion Repositories HelenOS-historic

Rev

Rev 1387 | Rev 1409 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1387 Rev 1403
Line 90... Line 90...
90
 
90
 
91
static int area_flags_to_page_flags(int aflags);
91
static int area_flags_to_page_flags(int aflags);
92
static int get_area_flags(as_area_t *a);
92
static int get_area_flags(as_area_t *a);
93
static as_area_t *find_area_and_lock(as_t *as, __address va);
93
static as_area_t *find_area_and_lock(as_t *as, __address va);
94
static bool check_area_conflicts(as_t *as, __address va, size_t size, as_area_t *avoid_area);
94
static bool check_area_conflicts(as_t *as, __address va, size_t size, as_area_t *avoid_area);
95
int used_space_insert(as_area_t *a, __address page, count_t count);
95
static int used_space_insert(as_area_t *a, __address page, count_t count);
96
int used_space_remove(as_area_t *a, __address page, count_t count);
96
static int used_space_remove(as_area_t *a, __address page, count_t count);
97
 
97
 
98
/** Initialize address space subsystem. */
98
/** Initialize address space subsystem. */
99
void as_init(void)
99
void as_init(void)
100
{
100
{
101
    as_arch_init();
101
    as_arch_init();
Line 242... Line 242...
242
        interrupts_restore(ipl);
242
        interrupts_restore(ipl);
243
        return EPERM;
243
        return EPERM;
244
    }
244
    }
245
   
245
   
246
    if (pages < area->pages) {
246
    if (pages < area->pages) {
247
        int i;
247
        bool cond;
-
 
248
        __address start_free = area->base + pages*PAGE_SIZE;
248
 
249
 
249
        /*
250
        /*
250
         * Shrinking the area.
251
         * Shrinking the area.
251
         * No need to check for overlaps.
252
         * No need to check for overlaps.
252
         */
253
         */
253
        for (i = pages; i < area->pages; i++) {
-
 
254
            pte_t *pte;
-
 
255
           
-
 
256
            /*
-
 
257
             * Releasing physical memory.
-
 
258
             * This depends on the fact that the memory was allocated using frame_alloc().
-
 
259
             */
-
 
260
            page_table_lock(as, false);
-
 
261
            pte = page_mapping_find(as, area->base + i*PAGE_SIZE);
-
 
262
            if (pte && PTE_VALID(pte)) {
-
 
263
                __address frame;
-
 
264
 
-
 
265
                ASSERT(PTE_PRESENT(pte));
-
 
266
                frame = PTE_GET_FRAME(pte);
-
 
267
                page_mapping_remove(as, area->base + i*PAGE_SIZE);
-
 
268
                page_table_unlock(as, false);
-
 
269
 
254
 
-
 
255
        /*
-
 
256
         * Remove frames belonging to used space starting from
-
 
257
         * the highest addresses downwards until an overlap with
-
 
258
         * the resized address space area is found. Note that this
-
 
259
         * is also the right way to remove part of the used_space
-
 
260
         * B+tree leaf list.
-
 
261
         */    
-
 
262
        for (cond = true; cond;) {
-
 
263
            btree_node_t *node;
-
 
264
       
-
 
265
            ASSERT(!list_empty(&area->used_space.leaf_head));
-
 
266
            node = list_get_instance(area->used_space.leaf_head.prev, btree_node_t, leaf_link);
-
 
267
            if ((cond = (bool) node->keys)) {
-
 
268
                __address b = node->key[node->keys - 1];
-
 
269
                count_t c = (count_t) node->value[node->keys - 1];
-
 
270
                int i = 0;
-
 
271
           
-
 
272
                if (overlaps(b, c*PAGE_SIZE, area->base, pages*PAGE_SIZE)) {
-
 
273
                   
-
 
274
                    if (b + c*PAGE_SIZE <= start_free) {
-
 
275
                        /*
-
 
276
                         * The whole interval fits completely
-
 
277
                         * in the resized address space area.
-
 
278
                         */
-
 
279
                        break;
-
 
280
                    }
-
 
281
       
-
 
282
                    /*
-
 
283
                     * Part of the interval corresponding to b and c
-
 
284
                     * overlaps with the resized address space area.
-
 
285
                     */
-
 
286
       
-
 
287
                    cond = false;   /* we are almost done */
270
                frame_free(ADDR2PFN(frame));
288
                    i = (start_free - b) >> PAGE_WIDTH;
-
 
289
                    if (!used_space_remove(area, start_free, c - i))
-
 
290
                        panic("Could not remove used space.");
271
            } else {
291
                } else {
-
 
292
                    /*
-
 
293
                     * The interval of used space can be completely removed.
-
 
294
                     */
-
 
295
                    if (!used_space_remove(area, b, c))
-
 
296
                        panic("Could not remove used space.\n");
-
 
297
                }
-
 
298
           
-
 
299
                for (; i < c; i++) {
-
 
300
                    pte_t *pte;
-
 
301
           
-
 
302
                    page_table_lock(as, false);
-
 
303
                    pte = page_mapping_find(as, b + i*PAGE_SIZE);
-
 
304
                    ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte));
-
 
305
                    frame_free(ADDR2PFN(PTE_GET_FRAME(pte)));
-
 
306
                    page_mapping_remove(as, b + i*PAGE_SIZE);
272
                page_table_unlock(as, false);
307
                    page_table_unlock(as, false);
-
 
308
                }
273
            }
309
            }
274
        }
310
        }
275
        /*
311
        /*
276
         * Invalidate TLB's.
312
         * Invalidate TLB's.
277
         */
313
         */
Line 310... Line 346...
310
int as_area_destroy(as_t *as, __address address)
346
int as_area_destroy(as_t *as, __address address)
311
{
347
{
312
    as_area_t *area;
348
    as_area_t *area;
313
    __address base;
349
    __address base;
314
    ipl_t ipl;
350
    ipl_t ipl;
315
    int i;
-
 
316
 
351
 
317
    ipl = interrupts_disable();
352
    ipl = interrupts_disable();
318
    mutex_lock(&as->lock);
353
    mutex_lock(&as->lock);
319
 
354
 
320
    area = find_area_and_lock(as, address);
355
    area = find_area_and_lock(as, address);
Line 322... Line 357...
322
        mutex_unlock(&as->lock);
357
        mutex_unlock(&as->lock);
323
        interrupts_restore(ipl);
358
        interrupts_restore(ipl);
324
        return ENOENT;
359
        return ENOENT;
325
    }
360
    }
326
 
361
 
327
    base = area->base; 
362
    base = area->base;
328
    for (i = 0; i < area->pages; i++) {
363
    if (!(area->flags & AS_AREA_DEVICE)) {
329
        pte_t *pte;
364
        bool cond; 
330
 
365
   
331
        /*
366
        /*
332
         * Releasing physical memory.
367
         * Releasing physical memory.
333
         * Areas mapping memory-mapped devices are treated differently than
368
         * Areas mapping memory-mapped devices are treated differently than
334
         * areas backing frame_alloc()'ed memory.
369
         * areas backing frame_alloc()'ed memory.
335
         */
370
         */
-
 
371
 
-
 
372
        /*
-
 
373
         * Visit only the pages mapped by used_space B+tree.
-
 
374
         * Note that we must be very careful when walking the tree
-
 
375
         * leaf list and removing used space as the leaf list changes
-
 
376
         * unpredictibly after each remove. The solution is to actually
-
 
377
         * not walk the tree at all, but to remove items from the head
-
 
378
         * of the leaf list until there are some keys left.
-
 
379
         */
-
 
380
        for (cond = true; cond;) {
-
 
381
            btree_node_t *node;
-
 
382
       
-
 
383
            ASSERT(!list_empty(&area->used_space.leaf_head));
-
 
384
            node = list_get_instance(area->used_space.leaf_head.next, btree_node_t, leaf_link);
-
 
385
            if ((cond = (bool) node->keys)) {
-
 
386
                __address b = node->key[0];
-
 
387
                count_t i;
-
 
388
                pte_t *pte;
-
 
389
           
-
 
390
                for (i = 0; i < (count_t) node->value[0]; i++) {
336
        page_table_lock(as, false);
391
                    page_table_lock(as, false);
337
        pte = page_mapping_find(as, area->base + i*PAGE_SIZE);
392
                    pte = page_mapping_find(as, b + i*PAGE_SIZE);
338
        if (pte && PTE_VALID(pte)) {
393
                    ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte));
339
            ASSERT(PTE_PRESENT(pte));
394
                    frame_free(ADDR2PFN(PTE_GET_FRAME(pte)));
340
            page_mapping_remove(as, area->base + i*PAGE_SIZE);
395
                    page_mapping_remove(as, b + i*PAGE_SIZE);
341
            if (area->flags & AS_AREA_DEVICE) {
396
                    page_table_unlock(as, false);
342
                __address frame;
397
                }
343
                frame = PTE_GET_FRAME(pte);
398
                if (!used_space_remove(area, b, i))
344
                frame_free(ADDR2PFN(frame));
399
                    panic("Could not remove used space.\n");
345
            }
400
            }
346
            page_table_unlock(as, false);
-
 
347
        } else {
-
 
348
            page_table_unlock(as, false);
-
 
349
        }
401
        }
350
    }
402
    }
-
 
403
    btree_destroy(&area->used_space);
-
 
404
 
351
    /*
405
    /*
352
     * Invalidate TLB's.
406
     * Invalidate TLB's.
353
     */
407
     */
354
    tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base, area->pages);
408
    tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base, area->pages);
355
    tlb_invalidate_pages(AS->asid, area->base, area->pages);
409
    tlb_invalidate_pages(AS->asid, area->base, area->pages);
Line 417... Line 471...
417
    src_size = src_area->pages * PAGE_SIZE;
471
    src_size = src_area->pages * PAGE_SIZE;
418
    src_flags = src_area->flags;
472
    src_flags = src_area->flags;
419
    mutex_unlock(&src_area->lock);
473
    mutex_unlock(&src_area->lock);
420
    mutex_unlock(&src_as->lock);
474
    mutex_unlock(&src_as->lock);
421
 
475
 
422
 
-
 
423
    if (src_size != acc_size) {
476
    if (src_size != acc_size) {
424
        spinlock_unlock(&src_task->lock);
477
        spinlock_unlock(&src_task->lock);
425
        interrupts_restore(ipl);
478
        interrupts_restore(ipl);
426
        return EPERM;
479
        return EPERM;
427
    }
480
    }
Line 510... Line 563...
510
    ipl = interrupts_disable();
563
    ipl = interrupts_disable();
511
    page_table_lock(as, true);
564
    page_table_lock(as, true);
512
   
565
   
513
    area = find_area_and_lock(as, page);
566
    area = find_area_and_lock(as, page);
514
    if (!area) {
567
    if (!area) {
515
        panic("page not part of any as_area\n");
568
        panic("Page not part of any as_area.\n");
516
    }
569
    }
517
 
570
 
518
    page_mapping_insert(as, page, frame, get_area_flags(area));
571
    page_mapping_insert(as, page, frame, get_area_flags(area));
-
 
572
    if (!used_space_insert(area, page, 1))
-
 
573
        panic("Could not insert used space.\n");
519
   
574
   
520
    mutex_unlock(&area->lock);
575
    mutex_unlock(&area->lock);
521
    page_table_unlock(as, true);
576
    page_table_unlock(as, true);
522
    interrupts_restore(ipl);
577
    interrupts_restore(ipl);
523
}
578
}
Line 603... Line 658...
603
     * Map 'page' to 'frame'.
658
     * Map 'page' to 'frame'.
604
     * Note that TLB shootdown is not attempted as only new information is being
659
     * Note that TLB shootdown is not attempted as only new information is being
605
     * inserted into page tables.
660
     * inserted into page tables.
606
     */
661
     */
607
    page_mapping_insert(AS, page, frame, get_area_flags(area));
662
    page_mapping_insert(AS, page, frame, get_area_flags(area));
-
 
663
    if (!used_space_insert(area, ALIGN_DOWN(page, PAGE_SIZE), 1))
-
 
664
        panic("Could not insert used space.\n");
608
    page_table_unlock(AS, false);
665
    page_table_unlock(AS, false);
609
   
666
   
610
    mutex_unlock(&area->lock);
667
    mutex_unlock(&area->lock);
611
    mutex_unlock(&AS->lock);
668
    mutex_unlock(&AS->lock);
612
    return AS_PF_OK;
669
    return AS_PF_OK;
Line 994... Line 1051...
994
        } else if (overlaps(page, count*PAGE_SIZE, right_pg, right_cnt*PAGE_SIZE)) {
1051
        } else if (overlaps(page, count*PAGE_SIZE, right_pg, right_cnt*PAGE_SIZE)) {
995
            /* The interval intersects with the right interval. */
1052
            /* The interval intersects with the right interval. */
996
            return 0;          
1053
            return 0;          
997
        } else if ((page == left_pg + left_cnt*PAGE_SIZE) && (page + count*PAGE_SIZE == right_pg)) {
1054
        } else if ((page == left_pg + left_cnt*PAGE_SIZE) && (page + count*PAGE_SIZE == right_pg)) {
998
            /* The interval can be added by merging the two already present intervals. */
1055
            /* The interval can be added by merging the two already present intervals. */
999
            node->value[node->keys - 1] += (count_t) count + right_cnt;
1056
            node->value[node->keys - 1] += count + right_cnt;
1000
            btree_remove(&a->used_space, right_pg, leaf);
1057
            btree_remove(&a->used_space, right_pg, leaf);
1001
            return 1;
1058
            return 1;
1002
        } else if (page == left_pg + left_cnt*PAGE_SIZE) {
1059
        } else if (page == left_pg + left_cnt*PAGE_SIZE) {
1003
            /* The interval can be added by simply growing the left interval. */
1060
            /* The interval can be added by simply growing the left interval. */
1004
            node->value[node->keys - 1] += (count_t) count;
1061
            node->value[node->keys - 1] += count;
1005
            return 1;
1062
            return 1;
1006
        } else if (page + count*PAGE_SIZE == right_pg) {
1063
        } else if (page + count*PAGE_SIZE == right_pg) {
1007
            /*
1064
            /*
1008
             * The interval can be addded by simply moving base of the right
1065
             * The interval can be addded by simply moving base of the right
1009
             * interval down and increasing its size accordingly.
1066
             * interval down and increasing its size accordingly.
1010
             */
1067
             */
1011
            leaf->value[0] += (count_t) count;
1068
            leaf->value[0] += count;
1012
            leaf->key[0] = page;
1069
            leaf->key[0] = page;
1013
            return 1;
1070
            return 1;
1014
        } else {
1071
        } else {
1015
            /*
1072
            /*
1016
             * The interval is between both neigbouring intervals,
1073
             * The interval is between both neigbouring intervals,
Line 1035... Line 1092...
1035
            /*
1092
            /*
1036
             * The interval can be added by moving the base of the right interval down
1093
             * The interval can be added by moving the base of the right interval down
1037
             * and increasing its size accordingly.
1094
             * and increasing its size accordingly.
1038
             */
1095
             */
1039
            leaf->key[0] = page;
1096
            leaf->key[0] = page;
1040
            leaf->value[0] += (count_t) count;
1097
            leaf->value[0] += count;
1041
            return 1;
1098
            return 1;
1042
        } else {
1099
        } else {
1043
            /*
1100
            /*
1044
             * The interval doesn't adjoin with the right interval.
1101
             * The interval doesn't adjoin with the right interval.
1045
             * It must be added individually.
1102
             * It must be added individually.
Line 1068... Line 1125...
1068
        } else if (overlaps(page, count*PAGE_SIZE, right_pg, right_cnt*PAGE_SIZE)) {
1125
        } else if (overlaps(page, count*PAGE_SIZE, right_pg, right_cnt*PAGE_SIZE)) {
1069
            /* The interval intersects with the right interval. */
1126
            /* The interval intersects with the right interval. */
1070
            return 0;          
1127
            return 0;          
1071
        } else if ((page == left_pg + left_cnt*PAGE_SIZE) && (page + count*PAGE_SIZE == right_pg)) {
1128
        } else if ((page == left_pg + left_cnt*PAGE_SIZE) && (page + count*PAGE_SIZE == right_pg)) {
1072
            /* The interval can be added by merging the two already present intervals. */
1129
            /* The interval can be added by merging the two already present intervals. */
1073
            leaf->value[leaf->keys - 1] += (count_t) count + right_cnt;
1130
            leaf->value[leaf->keys - 1] += count + right_cnt;
1074
            btree_remove(&a->used_space, right_pg, node);
1131
            btree_remove(&a->used_space, right_pg, node);
1075
            return 1;
1132
            return 1;
1076
        } else if (page == left_pg + left_cnt*PAGE_SIZE) {
1133
        } else if (page == left_pg + left_cnt*PAGE_SIZE) {
1077
            /* The interval can be added by simply growing the left interval. */
1134
            /* The interval can be added by simply growing the left interval. */
1078
            leaf->value[leaf->keys - 1] += (count_t) count;
1135
            leaf->value[leaf->keys - 1] +=  count;
1079
            return 1;
1136
            return 1;
1080
        } else if (page + count*PAGE_SIZE == right_pg) {
1137
        } else if (page + count*PAGE_SIZE == right_pg) {
1081
            /*
1138
            /*
1082
             * The interval can be addded by simply moving base of the right
1139
             * The interval can be addded by simply moving base of the right
1083
             * interval down and increasing its size accordingly.
1140
             * interval down and increasing its size accordingly.
1084
             */
1141
             */
1085
            node->value[0] += (count_t) count;
1142
            node->value[0] += count;
1086
            node->key[0] = page;
1143
            node->key[0] = page;
1087
            return 1;
1144
            return 1;
1088
        } else {
1145
        } else {
1089
            /*
1146
            /*
1090
             * The interval is between both neigbouring intervals,
1147
             * The interval is between both neigbouring intervals,
Line 1101... Line 1158...
1101
         * Investigate the border case in which the right neighbour does not
1158
         * Investigate the border case in which the right neighbour does not
1102
         * exist but the interval fits from the right.
1159
         * exist but the interval fits from the right.
1103
         */
1160
         */
1104
         
1161
         
1105
        if (overlaps(page, count*PAGE_SIZE, left_pg, left_cnt*PAGE_SIZE)) {
1162
        if (overlaps(page, count*PAGE_SIZE, left_pg, left_cnt*PAGE_SIZE)) {
1106
            /* The interval intersects with the right interval. */
1163
            /* The interval intersects with the left interval. */
1107
            return 0;
1164
            return 0;
1108
        } else if (left_pg + left_cnt*PAGE_SIZE == page) {
1165
        } else if (left_pg + left_cnt*PAGE_SIZE == page) {
1109
            /* The interval can be added by growing the left interval. */
1166
            /* The interval can be added by growing the left interval. */
1110
            leaf->value[leaf->keys - 1] += (count_t) count;
1167
            leaf->value[leaf->keys - 1] += count;
1111
            return 1;
1168
            return 1;
1112
        } else {
1169
        } else {
1113
            /*
1170
            /*
1114
             * The interval doesn't adjoin with the left interval.
1171
             * The interval doesn't adjoin with the left interval.
1115
             * It must be added individually.
1172
             * It must be added individually.
Line 1139... Line 1196...
1139
            } else if (overlaps(page, count*PAGE_SIZE, right_pg, right_cnt*PAGE_SIZE)) {
1196
            } else if (overlaps(page, count*PAGE_SIZE, right_pg, right_cnt*PAGE_SIZE)) {
1140
                /* The interval intersects with the right interval. */
1197
                /* The interval intersects with the right interval. */
1141
                return 0;          
1198
                return 0;          
1142
            } else if ((page == left_pg + left_cnt*PAGE_SIZE) && (page + count*PAGE_SIZE == right_pg)) {
1199
            } else if ((page == left_pg + left_cnt*PAGE_SIZE) && (page + count*PAGE_SIZE == right_pg)) {
1143
                /* The interval can be added by merging the two already present intervals. */
1200
                /* The interval can be added by merging the two already present intervals. */
1144
                leaf->value[i - 1] += (count_t) count + right_cnt;
1201
                leaf->value[i - 1] += count + right_cnt;
1145
                btree_remove(&a->used_space, right_pg, leaf);
1202
                btree_remove(&a->used_space, right_pg, leaf);
1146
                return 1;
1203
                return 1;
1147
            } else if (page == left_pg + left_cnt*PAGE_SIZE) {
1204
            } else if (page == left_pg + left_cnt*PAGE_SIZE) {
1148
                /* The interval can be added by simply growing the left interval. */
1205
                /* The interval can be added by simply growing the left interval. */
1149
                leaf->value[i - 1] += (count_t) count;
1206
                leaf->value[i - 1] += count;
1150
                return 1;
1207
                return 1;
1151
            } else if (page + count*PAGE_SIZE == right_pg) {
1208
            } else if (page + count*PAGE_SIZE == right_pg) {
1152
                /*
1209
                /*
1153
                     * The interval can be addded by simply moving base of the right
1210
                     * The interval can be addded by simply moving base of the right
1154
                 * interval down and increasing its size accordingly.
1211
                 * interval down and increasing its size accordingly.
1155
                 */
1212
                 */
1156
                leaf->value[i] += (count_t) count;
1213
                leaf->value[i] += count;
1157
                leaf->key[i] = page;
1214
                leaf->key[i] = page;
1158
                return 1;
1215
                return 1;
1159
            } else {
1216
            } else {
1160
                /*
1217
                /*
1161
                 * The interval is between both neigbouring intervals,
1218
                 * The interval is between both neigbouring intervals,
Line 1196... Line 1253...
1196
         */
1253
         */
1197
        if (count > pages) {
1254
        if (count > pages) {
1198
            return 0;
1255
            return 0;
1199
        } else if (count == pages) {
1256
        } else if (count == pages) {
1200
            btree_remove(&a->used_space, page, leaf);
1257
            btree_remove(&a->used_space, page, leaf);
-
 
1258
            return 1;
1201
        } else {
1259
        } else {
1202
            /*
1260
            /*
1203
             * Find the respective interval.
1261
             * Find the respective interval.
1204
             * Decrease its size and relocate its start address.
1262
             * Decrease its size and relocate its start address.
1205
             */
1263
             */
1206
            for (i = 0; i < leaf->keys; i++) {
1264
            for (i = 0; i < leaf->keys; i++) {
1207
                if (leaf->key[i] == page) {
1265
                if (leaf->key[i] == page) {
1208
                    leaf->key[i] += count*PAGE_SIZE;
1266
                    leaf->key[i] += count*PAGE_SIZE;
1209
                    leaf->value[i] -= (count_t) count;
1267
                    leaf->value[i] -= count;
1210
                    return 1;
1268
                    return 1;
1211
                }
1269
                }
1212
            }
1270
            }
1213
            goto error;
1271
            goto error;
1214
        }
1272
        }
Line 1224... Line 1282...
1224
                /*
1282
                /*
1225
                 * The interval is contained in the rightmost interval
1283
                 * The interval is contained in the rightmost interval
1226
                 * of the left neighbour and can be removed by
1284
                 * of the left neighbour and can be removed by
1227
                 * updating the size of the bigger interval.
1285
                 * updating the size of the bigger interval.
1228
                 */
1286
                 */
1229
                node->value[node->keys - 1] -= (count_t) count;
1287
                node->value[node->keys - 1] -= count;
1230
                return 1;
1288
                return 1;
1231
            } else if (page + count*PAGE_SIZE < left_pg + left_cnt*PAGE_SIZE) {
1289
            } else if (page + count*PAGE_SIZE < left_pg + left_cnt*PAGE_SIZE) {
1232
                count_t new_cnt = (left_pg + left_cnt*PAGE_SIZE) - (page + count*PAGE_SIZE);
1290
                count_t new_cnt;
1233
               
1291
               
1234
                /*
1292
                /*
1235
                 * The interval is contained in the rightmost interval
1293
                 * The interval is contained in the rightmost interval
1236
                 * of the left neighbour but its removal requires
1294
                 * of the left neighbour but its removal requires
1237
                 * both updating the size of the original interval and
1295
                 * both updating the size of the original interval and
1238
                 * also inserting a new interval.
1296
                 * also inserting a new interval.
1239
                 */
1297
                 */
-
 
1298
                new_cnt = ((left_pg + left_cnt*PAGE_SIZE) - (page + count*PAGE_SIZE)) >> PAGE_WIDTH;
1240
                node->value[node->keys - 1] -= (count_t) count + new_cnt;
1299
                node->value[node->keys - 1] -= count + new_cnt;
1241
                btree_insert(&a->used_space, page + count*PAGE_SIZE, (void *) new_cnt, leaf);
1300
                btree_insert(&a->used_space, page + count*PAGE_SIZE, (void *) new_cnt, leaf);
1242
                return 1;
1301
                return 1;
1243
            }
1302
            }
1244
        }
1303
        }
1245
        return 0;
1304
        return 0;
Line 1256... Line 1315...
1256
                /*
1315
                /*
1257
                 * The interval is contained in the rightmost interval
1316
                 * The interval is contained in the rightmost interval
1258
                 * of the leaf and can be removed by updating the size
1317
                 * of the leaf and can be removed by updating the size
1259
                 * of the bigger interval.
1318
                 * of the bigger interval.
1260
                 */
1319
                 */
1261
                leaf->value[leaf->keys - 1] -= (count_t) count;
1320
                leaf->value[leaf->keys - 1] -= count;
1262
                return 1;
1321
                return 1;
1263
            } else if (page + count*PAGE_SIZE < left_pg + left_cnt*PAGE_SIZE) {
1322
            } else if (page + count*PAGE_SIZE < left_pg + left_cnt*PAGE_SIZE) {
1264
                count_t new_cnt = (left_pg + left_cnt*PAGE_SIZE) - (page + count*PAGE_SIZE);
1323
                count_t new_cnt;
1265
               
1324
               
1266
                /*
1325
                /*
1267
                 * The interval is contained in the rightmost interval
1326
                 * The interval is contained in the rightmost interval
1268
                 * of the leaf but its removal requires both updating
1327
                 * of the leaf but its removal requires both updating
1269
                 * the size of the original interval and
1328
                 * the size of the original interval and
1270
                 * also inserting a new interval.
1329
                 * also inserting a new interval.
1271
                 */
1330
                 */
-
 
1331
                new_cnt = ((left_pg + left_cnt*PAGE_SIZE) - (page + count*PAGE_SIZE)) >> PAGE_WIDTH;
1272
                leaf->value[leaf->keys - 1] -= (count_t) count + new_cnt;
1332
                leaf->value[leaf->keys - 1] -= count + new_cnt;
1273
                btree_insert(&a->used_space, page + count*PAGE_SIZE, (void *) new_cnt, leaf);
1333
                btree_insert(&a->used_space, page + count*PAGE_SIZE, (void *) new_cnt, leaf);
1274
                return 1;
1334
                return 1;
1275
            }
1335
            }
1276
        }
1336
        }
1277
        return 0;
1337
        return 0;
Line 1294... Line 1354...
1294
                    /*
1354
                    /*
1295
                    * The interval is contained in the interval (i - 1)
1355
                    * The interval is contained in the interval (i - 1)
1296
                     * of the leaf and can be removed by updating the size
1356
                     * of the leaf and can be removed by updating the size
1297
                     * of the bigger interval.
1357
                     * of the bigger interval.
1298
                     */
1358
                     */
1299
                    leaf->value[i - 1] -= (count_t) count;
1359
                    leaf->value[i - 1] -= count;
1300
                    return 1;
1360
                    return 1;
1301
                } else if (page + count*PAGE_SIZE < left_pg + left_cnt*PAGE_SIZE) {
1361
                } else if (page + count*PAGE_SIZE < left_pg + left_cnt*PAGE_SIZE) {
1302
                    count_t new_cnt = (left_pg + left_cnt*PAGE_SIZE) - (page + count*PAGE_SIZE);
1362
                    count_t new_cnt;
1303
               
1363
               
1304
                    /*
1364
                    /*
1305
                     * The interval is contained in the interval (i - 1)
1365
                     * The interval is contained in the interval (i - 1)
1306
                     * of the leaf but its removal requires both updating
1366
                     * of the leaf but its removal requires both updating
1307
                     * the size of the original interval and
1367
                     * the size of the original interval and
1308
                     * also inserting a new interval.
1368
                     * also inserting a new interval.
1309
                     */
1369
                     */
-
 
1370
                    new_cnt = ((left_pg + left_cnt*PAGE_SIZE) - (page + count*PAGE_SIZE)) >> PAGE_WIDTH;
1310
                    leaf->value[i - 1] -= (count_t) count + new_cnt;
1371
                    leaf->value[i - 1] -= count + new_cnt;
1311
                    btree_insert(&a->used_space, page + count*PAGE_SIZE, (void *) new_cnt, leaf);
1372
                    btree_insert(&a->used_space, page + count*PAGE_SIZE, (void *) new_cnt, leaf);
1312
                    return 1;
1373
                    return 1;
1313
                }
1374
                }
1314
            }
1375
            }
1315
            return 0;
1376
            return 0;