intset_l_t *set_new_l() { intset_l_t *set; node_l_t *min, *max; if ((set = (intset_l_t *)ssalloc_aligned(CACHE_LINE_SIZE, sizeof(intset_l_t))) == NULL) { perror("malloc"); exit(1); } max = new_node_l(KEY_MAX, 0, NULL, 1); /* ssalloc_align_alloc(0); */ min = new_node_l(KEY_MIN, 0, max, 1); set->head = min; #if defined(LL_GLOBAL_LOCK) set->lock = (volatile ptlock_t*) ssalloc_aligned(CACHE_LINE_SIZE, sizeof(ptlock_t)); if (set->lock == NULL) { perror("malloc"); exit(1); } GL_INIT_LOCK(set->lock); #endif MEM_BARRIER; return set; }
int lockc_insert(intset_l_t *set, val_t val) { node_l_t *curr, *next, *newnode; int found; LOCK(&set->head->lock); curr = set->head; LOCK(&curr->next->lock); next = curr->next; while (next->val < val) { UNLOCK(&curr->lock); curr = next; LOCK(&curr->next->lock); next = curr->next; } found = (val == next->val); if (!found) { newnode = new_node_l(val, next, 0); curr->next = newnode; } UNLOCK(&curr->lock); UNLOCK(&next->lock); return !found; }
/* * File: optik.c * Author: Vasileios Trigonakis <*****@*****.**> * Description: * * Copyright (c) 2014 Vasileios Trigonakis <*****@*****.**>, * Distributed Programming Lab (LPD), EPFL * * ASCYLIB is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, version 2 * of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #include "linkedlist-optik.h" RETRY_STATS_VARS; sval_t optik_find(intset_l_t *set, skey_t key) { PARSE_TRY(); node_l_t* curr = set->head; while (curr != NULL && curr->key < key) { curr = curr->next; } sval_t res = 0; if (curr != NULL && curr->key == key) { res = curr->val; } return res; } #if !defined(LL_GLOBAL_LOCK) int optik_insert(intset_l_t *set, skey_t key, sval_t val) { restart: PARSE_TRY(); volatile node_l_t *curr, *pred = NULL; COMPILER_NO_REORDER(optik_t pred_ver = set->lock); curr = set->head; while (curr != NULL && (curr->key < key)) { pred = curr; curr = curr->next; } UPDATE_TRY(); if (curr != NULL && curr->key == key) { return false; } if (!optik_trylock_version(&set->lock, pred_ver)) { goto restart; } node_l_t* newnode = new_node_l(key, val, curr, 0); #ifdef __tile__ MEM_BARRIER; #endif if (pred != NULL) { pred->next = newnode; } else { set->head = newnode; } optik_unlock(&set->lock); return true; } #else /* LL_GLOBAL_LOCK == 1 :: pessimistic */ int optik_insert(intset_l_t *set, skey_t key, sval_t val) { volatile node_l_t *curr, *pred; COMPILER_NO_REORDER(optik_t pred_ver = set->lock); int r; for (r = 0; r < 2; r++) { PARSE_TRY(); pred = NULL; curr = set->head; while (curr != NULL && curr->key < key) { pred = curr; curr = curr->next; } UPDATE_TRY(); if (curr != NULL && curr->key == key) { if (r) { optik_unlock(&set->lock); } return false; } if (!r && optik_lock_version(&set->lock, pred_ver)) { break; } } node_l_t* newnode = new_node_l(key, val, curr, 0); #ifdef __tile__ MEM_BARRIER; #endif if (pred != NULL) { pred->next = newnode; } else { set->head = newnode; } optik_unlock(&set->lock); return true; }
void bucket_set_init_l(intset_l_t* set, ptlock_t* lock) { node_l_t *min; min = new_node_l(KEY_MIN, 0, NULL, 1); set->head = min; #if defined(LL_GLOBAL_LOCK) // set->lock = lock; GL_INIT_LOCK(&set->lock); #endif MEM_BARRIER; }
int optik_insert(intset_l_t *set, skey_t key, sval_t val) { restart: PARSE_TRY(); volatile node_l_t *curr, *pred = NULL; COMPILER_NO_REORDER(optik_t pred_ver = set->lock); curr = set->head; while (curr != NULL && (curr->key < key)) { pred = curr; curr = curr->next; } UPDATE_TRY(); if (curr != NULL && curr->key == key) { return false; } if (!optik_trylock_version(&set->lock, pred_ver)) { goto restart; } node_l_t* newnode = new_node_l(key, val, curr, 0); #ifdef __tile__ MEM_BARRIER; #endif if (pred != NULL) { pred->next = newnode; } else { set->head = newnode; } optik_unlock(&set->lock); return true; }
int parse_insert(intset_l_t *set, skey_t key, sval_t val) { node_l_t *curr, *pred, *newnode; int result = -1; do { PARSE_TRY(); pred = set->head; curr = pred->next; while (likely(curr->key < key)) { pred = curr; curr = curr->next; } UPDATE_TRY(); GL_LOCK(set->lock); /* when GL_[UN]LOCK is defined the [UN]LOCK is not ;-) */ LOCK(ND_GET_LOCK(pred)); LOCK(ND_GET_LOCK(curr)); if (parse_validate(pred, curr)) { result = (curr->key != key); if (result) { newnode = new_node_l(key, val, curr, 0); #ifdef __tile__ MEM_BARRIER; #endif pred->next = newnode; } } GL_UNLOCK(set->lock); UNLOCK(ND_GET_LOCK(curr)); UNLOCK(ND_GET_LOCK(pred)); } while (result < 0); return result; }
int lockc_insert(intset_l_t *set, skey_t key, sval_t val) { PARSE_TRY(); UPDATE_TRY(); node_l_t *curr, *next, *newnode; int found; GL_LOCK(set->lock); /* when GL_[UN]LOCK is defined the [UN]LOCK is not ;-) */ LOCK(ND_GET_LOCK(set->head)); curr = set->head; LOCK(ND_GET_LOCK(curr->next)); next = curr->next; while (next->key < key) { UNLOCK(ND_GET_LOCK(curr)); curr = next; LOCK(ND_GET_LOCK(next->next)); next = curr->next; } found = (key == next->key); if (!found) { newnode = new_node_l(key, val, next, 1); #ifdef __tile__ MEM_BARRIER; #endif curr->next = newnode; } GL_UNLOCK(set->lock); UNLOCK(ND_GET_LOCK(curr)); UNLOCK(ND_GET_LOCK(next)); return !found; }