Beispiel #1
0
static void * critbit_delete_inplace(critbit_root *root, const char *key, int keylen) {
    if(!root->head) return NULL;

    const uint8_t *bytes = (void *)key;
    uint8_t *p = root->head;
    void **wherep = &root->head, **whereq = 0;
    critbit_node *q = NULL;
    int dir = 0;

    while(IS_INTERNAL(p)) {
        whereq = wherep;
        q = TO_NODE(p);
        dir = get_direction(q, bytes, keylen);
        wherep = q->child + dir;
        p = *wherep;
    }

    if(strcmp(key, (const char *)p) != 0) {
        return NULL;
    }

    if(!whereq) {
        root->head = NULL;
        return p;
    }

    *whereq = q->child[1 - dir];
    __sync_synchronize();
    return FROM_NODE(q);
}
Beispiel #2
0
static void clear_node(void *p) {
    if(IS_INTERNAL(p)) {
        // Internal node
        critbit_node *node = TO_NODE(p);
        clear_node(node->child[0]);
        clear_node(node->child[1]);
        free(node);
    } else {
        free_string(p);
    }
}
Beispiel #3
0
int critbit_delete(critbit_root *root, const char *key) {
    const size_t len = strlen(key);

    // begin critical section
    pthread_mutex_lock(&root->wlock);

    void * p = critbit_delete_inplace(root, key, len);

    pthread_rwlock_t *lock = root->cur_rwlock;
    pthread_rwlock_t *newlock = root->prev_rwlock;

    // swap two locks
    if(!__sync_val_compare_and_swap(&root->cur_rwlock, lock, newlock)) {
        printf("!!!\n");
    }
    if(!__sync_val_compare_and_swap(&root->prev_rwlock, newlock, lock)) {
        printf("!!!\n");
    }

    // wait until all readers are out
    pthread_rwlock_wrlock(lock);
    pthread_rwlock_unlock(lock);

    // end critical section
    pthread_mutex_unlock(&root->wlock);

    if(!p)
        return 1;

    if(!IS_INTERNAL(p)) {
        free_string(p);
    } else {
        critbit_node *node = TO_NODE(p);
        if(!IS_INTERNAL(node->child[0]) && strcmp(key, (const char *)node->child[0]) == 0) {
            free_string(node->child[0]);
            free_node(root, node);
        } else {
            free_string(node->child[1]);
            free_node(root, node);
        }
    }

    return 0;
}
Beispiel #4
0
/*
 * Locate a nasid which doesn't exist.  Perform a bte_copy from that
 * node to our local node.
 */
static int
brt_tst_invalid_xfers(void)
{
	int i;
	int free_nasid = -1;
	int cpu;
	int error_cnt;

	u64 ret_code;

	if (ix_srcnasid != -1) {
		free_nasid = ix_srcnasid;
	} else {
		/* Only looking for nasids from C-Nodes. */
		for (i = 0; i < PLAT_MAX_NODE_NUMBER; i += 2) {
			if (local_node_data->physical_node_map[i] == -1) {
				free_nasid = i;
				break;
			}
		}
	}

	if (free_nasid == -1) {
		printk("tst_invalid_xfers: No free nodes found. "
		       "Exiting.\n");
		return (0);
	}

	printk("tst_invalid_xfers: Using source nasid of %d\n",
	       free_nasid);

	error_cnt = 0;

	for (i = 0; i < ix_iterations; i++) {
		if (verbose >= 1) {
			printk("-------------------------------"
			       "-------------------------------"
			       "--------------\n");
		}
		if ((verbose >= 1) || !(i % 10)) {
			printk("  Loop %d\n", i);
		}

		for (cpu = 0; cpu < smp_num_cpus; cpu++) {
			set_cpus_allowed(current, (1UL << cpu));

			if (verbose > 1) {
				printk("Testing with CPU %d\n",
				       smp_processor_id());
			}

			/* >>> Need a better means of calculating a
			 * remote addr. */
			ret_code = bte_copy(TO_NODE(free_nasid, 0),
					    __pa(nodepda->bte_if[0].
						 bte_test_buf),
					    4 * L1_CACHE_BYTES,
					    BTE_NOTIFY,
					    NULL);
			error_cnt += (ret_code ? 1 : 0);
		}
	}

	ret_code = ((error_cnt != (ix_iterations * smp_num_cpus)) ?
		    1 : 0);
	return (ret_code);
}
Beispiel #5
0
static int critbit_insert_inplace(critbit_root *root,
        const char *key, int keylen, const void* value) {
    const uint8_t *bytes = (void *)key;

    uint8_t *p = root->head;
    if(!p) {
        p = alloc_string(key, keylen, value);
        if(!p)
            return 1;

        root->head = p;
        return 0;
    }

    p = find_nearest(root->head, bytes, keylen);

    uint32_t newbyte;
    uint8_t newotherbits;
    for(newbyte = 0; newbyte < keylen; ++newbyte) {
        if(p[newbyte] != bytes[newbyte]) {
            newotherbits = p[newbyte] ^ bytes[newbyte];
            goto found;
        }
    }
    if(p[newbyte]) {
        newotherbits = p[newbyte];
        goto found;
    }
    return 1;

found:
    while(newotherbits & (newotherbits - 1)) {
        newotherbits &= newotherbits - 1;
    }
    newotherbits ^= 0xFF;
    uint8_t c = p[newbyte];
    int newdirection = (1 + (newotherbits | c)) >> 8;

    struct critbit_node *node = alloc_aligned(sizeof(struct critbit_node));
    if(!node)
        return 1;

    char *x = alloc_string(key, keylen, value);
    if(!x) {
        free(node);
        return 1;
    }

    node->byte = newbyte;
    node->otherbits = newotherbits;
    node->child[1 - newdirection] = x;

    void **wherep = &root->head;
    for(;;) {
        uint8_t *p = *wherep;
        if(!IS_INTERNAL(p))
            break;

        struct critbit_node *q = TO_NODE(p);
        if(q->byte > newbyte)
            break;
        if(q->byte == newbyte && q->otherbits > newotherbits)
            break;

        wherep = q->child + get_direction(q, bytes, keylen);
    }
    node->child[newdirection] = *wherep;
    __sync_synchronize();
    *wherep = FROM_NODE(node);
    __sync_synchronize();

    return 0;
}