node_t* new_node(val_t val, nxt_t next, int transactional) { node_t *node; node_t nd; nd.val = val; nd.next = next; if (transactional) { node = (node_t *) TX_SHMALLOC(sizeof (node_t)); TX_STORE(node, nd.to_int64, TYPE_INT); } else { node = (node_t *) sys_shmalloc(sizeof (node_t)); NONTX_STORE(node, nd.to_int64, TYPE_INT); } if (node == NULL) { perror("malloc"); EXIT(1); } return node; }
int set_remove(intset_t *set, val_t val, int transactional) { int result = 0; #ifdef DEBUG printf("++> set_remove(%d)\n", (int)val); IO_FLUSH; #endif #ifdef SEQUENTIAL /* Unprotected */ node_t *prev, *next; prev = set->head; next = prev->next; while (next->val < val) { prev = next; next = prev->next; } result = (next->val == val); if (result) { prev->next = next->next; free(next); } #elif defined STM node_t *prev, *next; val_t v; node_t *n; TX_START(EL); prev = set->head; next = (node_t *)TX_LOAD(&prev->next); while (1) { v = TX_LOAD((uintptr_t *) &next->val); if (v >= val) break; prev = next; next = (node_t *)TX_LOAD(&prev->next); } result = (v == val); if (result) { n = (node_t *)TX_LOAD(&next->next); TX_STORE(&prev->next, n); FREE(next, sizeof(node_t)); } TX_END; #elif defined LOCKFREE result = harris_delete(set, val); #endif return result; }
int set_add(intset_t* set, val_t val, int transactional) { int result = 0; if (!transactional) { return set_seq_add(set, val); } #ifdef SEQUENTIAL /* Unprotected */ return set_seq_add(set, val); #endif #ifdef EARLY_RELEASE return set_early_add(set, val); #endif #ifdef READ_VALIDATION return set_readval_add(set, val); #endif node_t prev, next; nxt_t to_store; TX_START; #ifdef DEBUG PRINT("++> set_add(%d)\tretry: %u", (int) val, tm2c_tx->retries); #endif to_store = OF(set->head); TX_LOAD_NODE(prev, set->head); TX_LOAD_NODE(next, ND(prev.next)); while (next.val < val) { to_store = prev.next; prev.val = next.val; prev.next = next.next; TX_LOAD_NODE(next, ND(prev.next)); } result = (next.val != val); if (result) { node_t* nn = new_node(val, prev.next, 1); prev.next = OF(nn); TX_STORE(ND(to_store), prev.to_int64, TYPE_INT); } TX_COMMIT_MEM; return result; }
static void write_node(node_t* node, val_t val, nxt_t next, int transactional) { node_t nd; nd.val = val; nd.next = next; if (transactional) { TX_STORE(node, nd.to_int64, TYPE_INT); } else { NONTX_STORE(node, nd.to_int64, TYPE_INT); } }
int set_add(intset_t *set, val_t val, int transactional) { int result = 0; #ifdef DEBUG printf("++> set_add(%d)\n", (int)val); IO_FLUSH; #endif if (!transactional) { result = set_seq_add(set, val); } else { #ifdef SEQUENTIAL /* Unprotected */ result = set_seq_add(set, val); #elif defined STM node_t *prev, *next; val_t v; TX_START(EL); prev = set->head; next = (node_t *)TX_LOAD(&prev->next); while (1) { v = TX_LOAD((uintptr_t *) &next->val); if (v >= val) break; prev = next; next = (node_t *)TX_LOAD(&prev->next); } result = (v != val); if (result) { TX_STORE(&prev->next, new_node(val, next, transactional)); } TX_END; #elif defined LOCKFREE result = harris_insert(set, val); #endif } return result; }
int set_remove(intset_t* set, val_t val, int transactional) { int result = 0; #ifdef DEBUG PRINT("++> set_remove(%d)", (int) val); #endif #ifdef SEQUENTIAL /* Unprotected */ return set_seq_remove(set, val); #endif #ifdef EARLY_RELEASE return set_early_remove(set, val); #endif #ifdef READ_VALIDATION return set_readval_remove(set, val); #endif node_t prev, next; TX_START; nxt_t to_store = OF(set->head); TX_LOAD_NODE(prev, set->head); TX_LOAD_NODE(next, ND(prev.next)); while (val > next.val) { to_store = prev.next; prev.val = next.val; prev.next = next.next; TX_LOAD_NODE(next, ND(prev.next)); } result = (next.val == val); if (result) { TX_SHFREE(ND(prev.next)); prev.next = next.next; TX_STORE(ND(to_store), prev.to_int64, TYPE_INT); } TX_COMMIT_MEM; return result; }
int main(int argc, char **argv) { TM2C_INIT; int *sis = (int *) sys_shmalloc(SIS_SIZE * sizeof (int)); if (sis == NULL) { perror("sys_shmalloc"); } int i; for (i = TM2C_ID; i < SIS_SIZE; i += NUM_UES) { sis[i] = -1; } PF_MSG(0, "write after read"); PF_MSG(1, "read after write"); BARRIER; PF_START(0); TX_START; int i; for (i = 0; i < SIS_SIZE; i++) { if (TM2C_ID == 1) { TX_LOAD(sis + i); } else { TX_STORE(sis + i, TM2C_ID, TYPE_INT); } } TX_COMMIT; PF_STOP(0); BARRIER; PF_START(1); TX_START; if(TM2C_ID == 1) { udelay(2500); } int i; for (i = 0; i < SIS_SIZE; i++) { if (TM2C_ID == 1) { TX_LOAD(sis + i); } else { TX_STORE(sis + i, TM2C_ID, TYPE_INT); } } TX_COMMIT; PF_STOP(1); sys_shfree((void*) sis); APP_EXEC_ORDER { PF_PRINT; } APP_EXEC_ORDER_END; TM_END; EXIT(0); }