Triton Repository branch, master, updated. 62218dc0feba70252ae2dbdfb4c07238100f90d8
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Triton Repository". The branch, master has been updated via 62218dc0feba70252ae2dbdfb4c07238100f90d8 (commit) from 662361693c4537a90d3dc0cd9b5aaa08588e6cb2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 62218dc0feba70252ae2dbdfb4c07238100f90d8 Author: Phil Carns <[email protected]> Date: Mon Apr 26 10:56:31 2010 -0400 remove stale COSD code ----------------------------------------------------------------------- Summary of changes: code/configure | 3 +- code/configure.ac | 6 - code/src/cosd/prototype/README | 2 - code/src/cosd/prototype/cosd-prototype.c | 1994 -------------------- code/src/cosd/prototype/cosd-prototype.hae | 116 -- code/src/cosd/prototype/module.mk.in | 6 - code/src/cosd/prototype/test/4M-w-serial.txt | 7 - code/src/cosd/prototype/test/README | 1 - .../cosd/prototype/test/cosd-bench-concurrent.ae | 235 --- code/src/cosd/prototype/test/cosd1.ae | 236 --- code/src/cosd/prototype/test/module.mk.in | 8 - code/src/cosd/prototype/test/workload-gen.ae | 122 -- 12 files changed, 1 insertions(+), 2735 deletions(-) delete mode 100644 code/src/cosd/prototype/README delete mode 100644 code/src/cosd/prototype/cosd-prototype.c delete mode 100644 code/src/cosd/prototype/cosd-prototype.hae delete mode 100644 code/src/cosd/prototype/module.mk.in delete mode 100644 code/src/cosd/prototype/test/4M-w-serial.txt delete mode 100644 code/src/cosd/prototype/test/README delete mode 100644 code/src/cosd/prototype/test/cosd-bench-concurrent.ae delete mode 100644 code/src/cosd/prototype/test/cosd1.ae delete mode 100644 code/src/cosd/prototype/test/module.mk.in delete mode 100644 code/src/cosd/prototype/test/workload-gen.ae Diff of changes: diff --git a/code/configure b/code/configure index a03c0ff..3030fd1 100755 --- a/code/configure +++ b/code/configure @@ -1304,7 +1304,7 @@ Optional Features: --enable-verbose Enables verbose output during build process --enable-warnings Do not generate compiler error on warnings (not -Werror) --enable-strict Turn on strict compiler warnings - --enable-aesop-debug Turn on debugging of the gs-parser + --enable-aesop-debug Turn on debugging of the aesop-parser --enable-coverage Enable coverage analysis (disables optimizations) --disable-thread-safety Disables thread safety in the client library @@ -5115,7 +5115,6 @@ fi - ac_config_files="$ac_config_files Makefile src/common/module.mk src/common/tests/module.mk src/common/resources/timer/test/module.mk src/common/resources/timer/module.mk src/common/resources/scheduling/module.mk src/common/resources/scheduling/test/module.mk src/net/module.mk src/net/mpi/module.mk src/net/mpi/test/module.mk src/remote/module.mk src/aesop/module.mk src/aesop/parser/module.mk src/aesop/examples/module.mk src/aesop/parser/tests/remote/module.mk src/aesop/parser/tests/blocking/module.mk src/versioned-osd/prototype/module.mk src/versioned-osd/prototype/tests/module.mk src/versioned-osd/prototype/bdb-resource/module.mk src/versioned-osd/prototype/file-resource/module.mk src/fakess/module.mk src/fakess/test/module.mk" cat >confcache <<\_ACEOF diff --git a/code/configure.ac b/code/configure.ac index e67ed94..0dc22f0 100644 --- a/code/configure.ac +++ b/code/configure.ac @@ -135,12 +135,6 @@ AC_SUBST(THREAD_LIB) TRITON_LIB_SQLITE(3.0.0) -dnl src/cosd/prototype/test/module.mk -dnl src/cosd/prototype/module.mk -dnl src/cosd/storage/osd-target/module.mk -dnl src/cosd/storage/test/module.mk -dnl src/cosd/storage/module.mk - AC_OUTPUT(Makefile src/common/module.mk src/common/tests/module.mk diff --git a/code/src/cosd/prototype/README b/code/src/cosd/prototype/README deleted file mode 100644 index 71b5f71..0000000 --- a/code/src/cosd/prototype/README +++ /dev/null @@ -1,2 +0,0 @@ -This resource is a prototype of the COSD object layer, intended for use as a -replication building block. diff --git a/code/src/cosd/prototype/cosd-prototype.c b/code/src/cosd/prototype/cosd-prototype.c deleted file mode 100644 index ff7c456..0000000 --- a/code/src/cosd/prototype/cosd-prototype.c +++ /dev/null @@ -1,1994 +0,0 @@ -#define _GNU_SOURCE -#define _XOPEN_SOURCE 600 - -#include <time.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include <unistd.h> -#include <pthread.h> -#include <stdio.h> -#include <limits.h> -#include <db.h> -#include <stdlib.h> -#include "triton-config.h" - -/**************************************************************/ -/* TODO: general stuff: - * - deadlock detection and avoidance - * - consider non-durable transactions in order to coalesce commits - * - use txn_checkpoint to flush when coalescing - * - consider rmw locks where appropriate - * - long term: consider fallocate hint for logs to keep them linear - * - try computing cksum along the way, store in db - * - either in log map itself or db that matches its keys - */ -/**************************************************************/ - -/* TODO: this needs to be in a header somewhere */ -#ifndef llu -#if SIZEOF_LONG_INT == 4 -# define llu(x) (x) -# define lld(x) (x) -# define SCANF_lld "%lld" -#elif SIZEOF_LONG_INT == 8 -# define llu(x) (unsigned long long)(x) -# define lld(x) (long long)(x) -# define SCANF_lld "%ld" -#else -# error Unexpected sizeof(long int) -#endif -#endif - -#include "src/aesop/aesop.h" -#include "src/aesop/op.h" -#include "src/aesop/opcache.h" -#include "src/common/triton-hash.h" -#include "src/cosd/prototype/cosd-prototype.h" - -#define STORAGE_DEFAULT_OPCACHE_SIZE 1024 -#define COSD_LOG_SUBDIR "logs" -#define COSD_MIN(__a, __b) ((__a) < (__b) ? (__a) : (__b)) -#define COSD_MAX(__a, __b) ((__a) > (__b) ? (__a) : (__b)) -/* TODO: find this programmatically? */ -#define DIRECT_ALIGN 512 -#define COSD_INIT_DBT(__dbt, __data) \ - do { \ - memset(&(__dbt), 0, sizeof(__dbt)); \ - (__dbt).data = &(__data); \ - (__dbt).size = sizeof(__data); \ - (__dbt).ulen = sizeof(__data); \ - (__dbt).flags = DB_DBT_USERMEM; \ - }while(0) -#define COSD_INIT_DBT_EMPTY(__dbt) \ - do { \ - memset(&(__dbt), 0, sizeof(__dbt)); \ - (__dbt).flags = DB_DBT_USERMEM; \ - }while(0) - - -static ae_opcache_t cosd_opcache; -static ae_ops_t cosd_oplist; -static triton_mutex_t cosd_mutex = TRITON_MUTEX_INITIALIZER; -static char* cosd_path = NULL; -static char* cosd_log_path = NULL; -static struct triton_hash_table *txn_table = NULL; -static triton_mutex_t txn_mutex = TRITON_MUTEX_INITIALIZER; - -static DB *log_map_dbp = NULL; -static DB *missing_ver_dbp = NULL; -static DB *ver_dbp = NULL; -static DB *log_offset_dbp = NULL; -DB_ENV *envp = NULL; - -/* temporary: a global fd and log offset used to access object */ -static int global_fd = -1; -static int64_t global_log_offset = -1; -static triton_mutex_t global_log_mutex = TRITON_MUTEX_INITIALIZER; - -static int cosd_resource_id; -static enum progress_mode triton_cosd_progress_mode = TRITON_PROG_NONE; - -static int merge_logical_map(triton_list_t* list1_in, int - list1_count, triton_list_t* list2_in, int list2_count, - triton_list_t* list_out, void** free_ptr); -static int compare_log_map_key(DB * dbp, const DBT * a, const DBT * b); -static int compare_missing_version(DB * dbp, const DBT * a, const DBT * b); -static int compare_uint64(DB * dbp, const DBT * a, const DBT * b); -static int cmp_lme(const void *p1, const void *p2); - -/* counter used by poll function in thread-per-op case to know if ops have - * finished since last poll - */ -static int completed_counter = 0; -static triton_mutex_t completed_counter_mutex = TRITON_MUTEX_INITIALIZER; -static triton_cond_t completed_counter_cond = TRITON_COND_INITIALIZER; - -/* uniquely identifies each active txn (in memory) */ -struct txn_accumulator -{ - /* txn identifier */ - uint64_t txn_number; - /* list of updates included in this txn */ - triton_list_t update_list; - int update_list_count; - - /* link into hash table of current txns */ - struct triton_hash_link hash_link; -}; - -/* db entry representing region in logical map */ -/* indexed via last offset */ -struct logical_map_entry -{ - int64_t size; /* size of region */ - int64_t logical_offset; /* beginning of logical region */ - int64_t logical_offset_end; /* end of logical region */ - int64_t log_offset; /* offset into log */ - uint64_t version; /* version number */ - struct triton_list_link list_link; -}; - -struct logical_map_key -{ - uint64_t oid; - int64_t logical_offset_end; -}; - -/* represents a missing version number in a particular object */ -struct missing_version -{ - uint64_t oid; - uint64_t version; -}; - -struct cosd_op -{ - union { - struct create_op{ - uint64_t requested_oid; - uint64_t* out_oid; - } create; - struct write_op{ - uint64_t oid; - uint64_t txn_number; - char** mem_offsets; - int64_t* mem_sizes; - int mem_count; - int64_t* obj_offsets; - int64_t* obj_sizes; - int obj_count; - } write; - struct txn_close_op{ - uint64_t oid; - uint64_t txn_number; - } txn_close; - struct get_version_op{ - uint64_t oid; - uint64_t *version; - } get_version; -#if 0 - struct remove_op{ - uint64_t oid; - } remove; - struct setattr_list_op{ - uint64_t oid; - int count; - const uint32_t* page_array; - const uint32_t* number_array; - const void** val_array; - const int* len_array; - } setattr_list; - struct getattr_list_op{ - uint64_t oid; - int count; - const uint32_t* page_array; - const uint32_t* number_array; - void** val_array; - int* len_array; - } getattr_list; -#endif - } u; - ae_op_id_t op_id; - struct ae_op op; - int error_code; - void (*cleanup_fn)(struct cosd_op* c_op); -}; - -static void* thread_fn(void* foo) -{ - struct ae_op* op = foo; - struct cosd_op* c_op = ae_op_entry(op, struct cosd_op, op); - - triton_mutex_lock(&cosd_mutex); - /* pull off of list */ - ae_ops_del(op); - triton_mutex_unlock(&cosd_mutex); - - /* spin on op worker */ - while(op->op_worker(op) != 1); - - /* call cleanup function if present */ - if(c_op->cleanup_fn) - { - c_op->cleanup_fn(c_op); - } - - /* trigger completion of the operation */ - ae_opcache_complete_op(cosd_opcache, op, c_op->error_code); - - /* wake up any pollers */ - triton_mutex_lock(&completed_counter_mutex); - completed_counter++; - triton_cond_signal(&completed_counter_cond); - triton_mutex_unlock(&completed_counter_mutex); - - return(NULL); -} - -static int txn_acc_compare(void *key, struct triton_hash_link *hash_link) -{ - struct txn_accumulator *txn_acc; - - txn_acc = triton_hash_get_entry(hash_link, struct txn_accumulator, hash_link); - return(*((uint64_t*)key) == txn_acc->txn_number); -} - -static int triton_cosd_launch_op(struct ae_op *op, enum progress_mode mode) -{ - int ret; - pthread_t tid; - pthread_attr_t attr; - - switch(mode) - { - case TRITON_PROG_POLL: - triton_mutex_lock(&cosd_mutex); - ae_ops_enqueue(op, &cosd_oplist); - triton_mutex_unlock(&cosd_mutex); - break; - case TRITON_PROG_THREAD_PER_OP: - /* TODO: make this better. Right now its a free for all */ - - /* put on the queue */ - triton_mutex_lock(&cosd_mutex); - ae_ops_enqueue(op, &cosd_oplist); - triton_mutex_unlock(&cosd_mutex); - - /* launch a thread to do the work */ - /* TODO: error handling */ - ret = pthread_attr_init(&attr); - assert(ret == 0); - ret = pthread_attr_setdetachstate(&attr, - PTHREAD_CREATE_DETACHED); - assert(ret == 0); - /* TODO: store tid in op (to help with cancelling or joining?) */ - ret = pthread_create(&tid, &attr, thread_fn, op); - assert(ret == 0); - pthread_attr_destroy(&attr); - - break; - case TRITON_PROG_NONE: - return(-EINVAL); - break; - case TRITON_PROG_THREAD_POOL: - /* TODO: alert the thread pool etc. */ - /* TODO: gossip... */ - triton_mutex_lock(&cosd_mutex); - ae_ops_enqueue(op, &cosd_oplist); - triton_mutex_unlock(&cosd_mutex); - return(-EINVAL); - break; - case TRITON_PROG_MAX: - break; - } - - return(0); -} - -/* triton_cosd_poll_thread_per_op() - * - * poll function in the thread-per-op mode that doesn't do anything except - * make sure that triton_poll wakes up if operations complete. - */ -static int triton_cosd_poll_thread_per_op(ae_context_t context, int millisecs) -{ - struct timespec abstime; - struct timeval start; - int ret; - - if(millisecs > 0) - { - ret = gettimeofday(&start, NULL); - if (ret < 0) - return (0); - - abstime.tv_sec = start.tv_sec + millisecs / 1000; - abstime.tv_nsec = (start.tv_usec + ((millisecs % 1000)*1000))*1000; - if (abstime.tv_nsec > 1000000000) - { - abstime.tv_nsec = abstime.tv_nsec - 1000000000; - abstime.tv_sec++; - } - } - - triton_mutex_lock(&completed_counter_mutex); - ret = 0; - while(completed_counter == 0 && ret == 0) - { - if(millisecs > 0) - { - ret = triton_cond_timedwait(&completed_counter_cond, - &completed_counter_mutex, &abstime); - } - else - { - ret = ETIMEDOUT; - } - } - completed_counter = 0; /* reset for next poller */ - triton_mutex_unlock(&completed_counter_mutex); - - return(0); -} - -static int triton_cosd_poll(ae_context_t context, int millisecs) -{ - struct ae_op *gop; - struct cosd_op *c_op; - struct timespec ts_sleep; - int ret; - - /* NOTE: just servicing one op per call right now */ - - /* NOTE: poll doesn't need locking, because it is not used in the - * threaded modes - */ - - /* triton_mutex_lock(&cosd_mutex); */ - - /* TODO: decouple locking for op list from servicing of operations so - * that multithreaded apps can post while servicing happens - * simultaneously - */ - gop = ae_ops_dequeue(&cosd_oplist); - if(!gop) - { - /* sleep */ - /* TODO: this needs to be something that can be interrupted if - * something is posted - */ - ts_sleep.tv_sec = (int)(millisecs / 1e3); - ts_sleep.tv_nsec = (millisecs % 1000) * 1e6; - nanosleep(&ts_sleep, NULL); - /* triton_mutex_unlock(&cosd_mutex); */ - return(0); - } - - c_op = ae_op_entry(gop, struct cosd_op, op); - - ret = gop->op_worker(gop); - if(ret == 1) - { - /* call cleanup function if present */ - if(c_op->cleanup_fn) - { - c_op->cleanup_fn(c_op); - } - - /* done */ - ae_opcache_complete_op(cosd_opcache, gop, c_op->error_code); - } - else - { - assert(ret == 0); /* only 0 and 1 allowed? */ - /* not done */ - ae_ops_enqueue(gop, &cosd_oplist); - } - - /* triton_mutex_unlock(&cosd_mutex); */ - - return 0; -} - -/* TODO: does this have to handle the case of the op already having - * disappeared, or does the aesop engine protect against that? - */ -static int triton_cosd_cancel(ae_context_t ctx, ae_op_id_t op_id) -{ - int cache_id, resource_id; - triton_mutex_lock(&cosd_mutex); - struct ae_op *op; - struct cosd_op *c_op; - - cache_id = triton_id_lookup(op_id, &resource_id); - assert(resource_id == cosd_resource_id); - - op = ae_opcache_lookup(cosd_opcache, (int)cache_id); - c_op = ae_op_entry(op, struct cosd_op, op); -#if 0 - ae_ops_del(op); - ae_opcache_put(cosd_opcache, op); -#endif - - triton_mutex_unlock(&cosd_mutex); - - return 0; -} - -struct triton_resource cosd_resource = -{ - .resource_name = "cosd", - .poll_context = triton_cosd_poll, - .cancel = triton_cosd_cancel -}; - -int triton_cosd_init(enum progress_mode mode, const char* path) -{ - int ret = 0; - int dir_exists = 0; - uint32_t env_flags; - uint32_t open_flags; - - /* make a directory for storage if not already present */ - ret = mkdir(path, 0755); - if(ret != 0 && errno == EEXIST) - { - dir_exists = 1; - } - else if(ret != 0) - { - /* some other error */ - return(ret); - } - - /* store paths */ - /* TODO: free both of these on error */ - cosd_path = strdup(path); - if(!cosd_path) - return(-errno); - cosd_log_path = malloc(strlen(path)+strlen(COSD_LOG_SUBDIR)+2); - if(!cosd_log_path) - return(-errno); - sprintf(cosd_log_path, "%s/%s", path, COSD_LOG_SUBDIR); - - /* create berkeley db environment */ - ret = db_env_create(&envp, 0); - if(ret != 0) - { - /* TODO: err handling */ - return(-1); - } - - /* have db do deadlock detection and reject txn with fewest locks */ - ret = envp->set_lk_detect(envp, DB_LOCK_MINWRITE); - if(ret != 0) - { - /* TODO: err handling */ - return(-1); - } - - env_flags = - DB_CREATE | /* Create the environment if it does not exist */ - DB_RECOVER | /* Run normal recovery. */ - DB_INIT_LOCK | /* Initialize the locking subsystem */ - DB_INIT_LOG | /* Initialize the logging subsystem */ - DB_INIT_TXN | /* Initialize the transactional subsystem. This - * also turns on logging. */ - DB_INIT_MPOOL | /* Initialize the memory pool (in-memory cache) */ - DB_THREAD | /* Cause the environment to be free-threaded */ - DB_RECOVER; /* Run normal recovery steps */ - - if(!dir_exists) - { - /* making a brand new storage space */ - - /* new directory for logs */ - ret = mkdir(cosd_log_path, 0755); - if(ret != 0) - return(-errno); - } - - /* open environment */ - ret = envp->open(envp, cosd_path, env_flags, 0); - if(ret != 0) - { - /* TODO: error handling */ - return(-1); - } - - /* create db handles */ - /* custom sort functions allow all dbs to be queried using cursors over - * id ranges - */ - ret = db_create(&log_map_dbp, envp, 0); - if(ret != 0) - { - /* TODO: error handling */ - return(-1); - } - log_map_dbp->set_bt_compare(log_map_dbp, compare_log_map_key); - ret = db_create(&missing_ver_dbp, envp, 0); - if(ret != 0) - { - /* TODO: error handling */ - return(-1); - } - missing_ver_dbp->set_bt_compare(missing_ver_dbp, compare_missing_version); - ret = db_create(&ver_dbp, envp, 0); - if(ret != 0) - { - /* TODO: error handling */ - return(-1); - } - ver_dbp->set_bt_compare(ver_dbp, compare_uint64); - ret = db_create(&log_offset_dbp, envp, 0); - if(ret != 0) - { - /* TODO: error handling */ - return(-1); - } - log_offset_dbp->set_bt_compare(log_offset_dbp, compare_uint64); - - - /* open dbs */ - open_flags = DB_CREATE | /* Allow database creation */ - DB_READ_UNCOMMITTED | /* Allow dirty reads */ - DB_AUTO_COMMIT; /* Allow autocommit */ - - ret = log_map_dbp->open(log_map_dbp, NULL, "logical-map.db", - NULL, DB_BTREE, open_flags, 0); - if(ret != 0) - { - /* TODO: error handling */ - return(-1); - } - ret = missing_ver_dbp->open(missing_ver_dbp, NULL, "missing_versions.db", - NULL, DB_BTREE, open_flags, 0); - if(ret != 0) - { - /* TODO: error handling */ - return(-1); - } - ret = ver_dbp->open(ver_dbp, NULL, "version.db", - NULL, DB_BTREE, open_flags, 0); - if(ret != 0) - { - /* TODO: error handling */ - return(-1); - } - ret = log_offset_dbp->open(log_offset_dbp, NULL, "log-offset.db", - NULL, DB_BTREE, open_flags, 0); - if(ret != 0) - { - /* TODO: error handling */ - return(-1); - } - - /* flush out txn logs up front; otherwise the first I/O operation to the - * COSD may bog down instead. - */ - envp->txn_checkpoint(envp, 0, 0, 0); - - triton_mutex_lock(&txn_mutex); - /* create hash table for open txns */ - txn_table = triton_hash_init(txn_acc_compare, triton_hash_64bit_hash, 1024); - if(!txn_table) - { - /* TODO: error handling */ - triton_mutex_unlock(&txn_mutex); - return(-1); - } - triton_mutex_unlock(&txn_mutex); - - ae_ops_init(&cosd_oplist); - - ret = TRITON_OPCACHE_INIT(struct cosd_op, op, STORAGE_DEFAULT_OPCACHE_SIZE, &cosd_opcache); - if(ret < 0) - { - return(ret); - } - - assert(mode > TRITON_PROG_NONE && mode < TRITON_PROG_MAX); - - /* modify poll function depending on requested mode */ - switch(mode) - { - case TRITON_PROG_POLL: - cosd_resource.poll_context = triton_cosd_poll; - break; - case TRITON_PROG_THREAD_PER_OP: - case TRITON_PROG_THREAD_POOL: - cosd_resource.poll_context = triton_cosd_poll_thread_per_op; - break; - case TRITON_PROG_NONE: - case TRITON_PROG_MAX: - return(-EINVAL); - } - - cosd_resource_id = ae_resource_register(&cosd_resource); - if(cosd_resource_id < 0) - { - ae_opcache_destroy(cosd_opcache); - return(cosd_resource_id); - } - triton_cosd_progress_mode = mode; - - return ret; -} - -int triton_cosd_finalize(void) -{ - triton_resource_unregister(cosd_resource_id); - ae_opcache_destroy(cosd_opcache); - - envp = log_map_dbp->get_env(log_map_dbp); - log_map_dbp->close(log_map_dbp, 0); - missing_ver_dbp->close(missing_ver_dbp, 0); - ver_dbp->close(ver_dbp, 0); - log_offset_dbp->close(log_offset_dbp, 0); - - triton_mutex_lock(&txn_mutex); - triton_hash_finalize(txn_table); - triton_mutex_unlock(&txn_mutex); - - return 0; -} - -/* write_op_cleanup() - * - * cleans up memory after a write operation completes - */ -static void write_op_cleanup(struct cosd_op *c_op) -{ - if(c_op->u.write.mem_offsets) - free(c_op->u.write.mem_offsets); - if(c_op->u.write.mem_sizes) - free(c_op->u.write.mem_sizes); - if(c_op->u.write.obj_sizes) - free(c_op->u.write.obj_sizes); - if(c_op->u.write.obj_offsets) - free(c_op->u.write.obj_offsets); - - return; -} - -/* write_op_worker() - * - * writes data to an object - */ -static int write_op_worker(struct ae_op* op) -{ - struct cosd_op *c_op; - int ret; - DB_TXN *txn; - DBT key, value; - char log_name[PATH_MAX]; - int done = 0; - int mem_index = 0; - int obj_index = 0; - struct logical_map_entry *tmp_update; - const char* mem_ptr; - void* scratch_buffer = NULL; - int scratch_size = 0; - int64_t aligned_size = 0; - struct txn_accumulator* txn_acc; - struct triton_hash_link* hash_link; - - c_op = ae_op_entry(op, struct cosd_op, op); - assert(c_op); - - /* only support one object for now */ - assert(c_op->u.write.oid == 1); - - assert(c_op->u.write.mem_count > 0); - assert(c_op->u.write.obj_count > 0); - - if(global_fd < 0) - { - /* open log file */ - sprintf(log_name, "%s/%llu.dat", cosd_log_path, - llu(c_op->u.write.oid)); - ret = open(log_name, O_RDWR|O_DIRECT|O_EXCL|O_NOATIME, - S_IRUSR|S_IWUSR); - if(ret < 0) - { - c_op->error_code = -errno; - return(1); - } - global_fd = ret; - } - - /* TODO: safety check that total mem size equals total obj size */ - /* TODO: safety check no zero buffers in either list */ - - while(!done) - { - /* structure to track this update in the txn */ - tmp_update = malloc(sizeof(*tmp_update)); - if(!tmp_update) - { - /* TODO: err handling */ - c_op->error_code = -errno; - return(1); - } - - /* find the next chunk that is contiguous in memory and disk */ - mem_ptr = c_op->u.write.mem_offsets[mem_index]; - tmp_update->logical_offset = c_op->u.write.obj_offsets[obj_index]; - tmp_update->size = c_op->u.write.mem_sizes[mem_index]; - tmp_update->logical_offset_end = tmp_update->logical_offset + - tmp_update->size; - if(tmp_update->size >= c_op->u.write.obj_sizes[obj_index]) - { - /* mem region is bigger than obj region */ - tmp_update->size = c_op->u.write.obj_sizes[obj_index]; - } - - /* advance pointers */ - c_op->u.write.mem_sizes[mem_index] -= tmp_update->size; - c_op->u.write.mem_offsets[mem_index] += tmp_update->size; - if(c_op->u.write.mem_sizes[mem_index] == 0) - { - if(mem_index == (c_op->u.write.mem_count -1)) - done = 1; - else - mem_index++; - } - c_op->u.write.obj_sizes[obj_index] -= tmp_update->size; - c_op->u.write.obj_offsets[obj_index] += tmp_update->size; - if(c_op->u.write.obj_sizes[obj_index] == 0) - { - if(obj_index == (c_op->u.write.obj_count -1)) - done = 1; - else - obj_index++; - } - - /* calculate aligned buffer size */ - if(tmp_update->size % DIRECT_ALIGN != 0) - aligned_size = - ((tmp_update->size / DIRECT_ALIGN)+1)*DIRECT_ALIGN; - else - aligned_size = tmp_update->size; - - /* TODO: think about how to track this per object; we need to - * atomically get a new log offset, but it doesn't have to be - * flushed to db until we close a transaction. For now using a - * global var and global mutex - */ - /* get next log offset and increment */ - triton_mutex_lock(&global_log_mutex); - if(global_log_offset < 0) - { - COSD_INIT_DBT(key, c_op->u.write.oid); - COSD_INIT_DBT(value, global_log_offset); - -write_op_txn: - /* read log offset from db */ - ret = envp->txn_begin(envp, NULL, &txn, 0); - if(ret != 0) - { - /* TODO: error handling */ - c_op->error_code = -1; - return(1); - } - - ret = log_offset_dbp->get(log_offset_dbp, txn, &key, &value, 0); - if(ret != 0) - { - txn->abort(txn); - if(ret == DB_LOCK_DEADLOCK) - goto write_op_txn; - - /* TODO: error handling */ - c_op->error_code = -1; - return(1); - } - - ret = txn->commit(txn, 0); - if(ret != 0) - { - txn->abort(txn); - if(ret == DB_LOCK_DEADLOCK) - goto write_op_txn; - - /* TODO: error handling */ - assert(0); - } - - assert(global_log_offset > -1); - } - - tmp_update->log_offset = global_log_offset; - global_log_offset += aligned_size; - triton_mutex_unlock(&global_log_mutex); - - if(((unsigned long)mem_ptr) % DIRECT_ALIGN || tmp_update->size != aligned_size) - { - /* mem buffer is not aligned */ - /* allocate a scratch buffer to copy to */ - if(scratch_size < aligned_size) - { - if(scratch_buffer) - free(scratch_buffer); - scratch_size = aligned_size; - ret = posix_memalign(&scratch_buffer, DIRECT_ALIGN, - aligned_size); - if(ret < 0) - { - /* TODO: err handling */ - c_op->error_code = -errno; - return(1); - } - } - memcpy(scratch_buffer, mem_ptr, tmp_update->size); - mem_ptr = scratch_buffer; - } - - /* actually write the data */ - ret = pwrite(global_fd, mem_ptr, aligned_size, - tmp_update->log_offset); - if(ret < 0) - { - /* TODO: err handling */ - c_op->error_code = -errno; - return(1); - } - - /* track this update in the txn accumulator */ - triton_mutex_lock(&txn_mutex); - hash_link = triton_hash_search(txn_table, &c_op->u.write.txn_number); - if(!hash_link) - { - /* TODO: txn is gone (which could be normal); error handling */ - c_op->error_code = -1; - triton_mutex_unlock(&txn_mutex); - return(1); - } - txn_acc = triton_hash_get_entry(hash_link, struct txn_accumulator, - hash_link); - tmp_update->version = txn_acc->txn_number; - triton_list_add_front(&tmp_update->list_link, &txn_acc->update_list); - txn_acc->update_list_count++; - triton_mutex_unlock(&txn_mutex); - } - - /* cleanup any leftover buffer */ - if(scratch_buffer) - free(scratch_buffer); - - c_op->error_code = 0; - return(1); -} - -/* dump_op_worker() - * - * dumps all db information from cosd - */ -/* TODO: audit for deadlocks */ -static int dump_op_worker(struct ae_op* op) -{ - struct cosd_op *c_op; - int ret; - DB_TXN *txn; - DBC *log_map_dbcp, *missing_ver_dbcp, *ver_dbcp, *log_offset_dbcp; - DBT log_map_key, missing_ver_key, ver_key, log_offset_key; - DBT log_map_value, missing_ver_value, ver_value, log_offset_value; - int c_get_flag = DB_SET_RANGE; - - /* keys for each db */ - struct logical_map_key lmk; - struct missing_version mvk; - uint64_t lok; - uint64_t vk; - COSD_INIT_DBT(log_map_key, lmk); - COSD_INIT_DBT(missing_ver_key, mvk); - COSD_INIT_DBT(log_offset_key, lok); - COSD_INIT_DBT(ver_key, vk); - - /* values for each db */ - struct logical_map_entry lmv; - uint64_t vv; - int64_t lov; - COSD_INIT_DBT(log_map_value, lmv); - COSD_INIT_DBT_EMPTY(missing_ver_value); - COSD_INIT_DBT(log_offset_value, lov); - COSD_INIT_DBT(ver_value, vv); - - c_op = ae_op_entry(op, struct cosd_op, op); - assert(c_op); - - ret = envp->txn_begin(envp, NULL, &txn, 0); - if(ret != 0) - { - /* TODO: error handling */ - c_op->error_code = -1; - return(1); - } - - /* create cursors on all 4 dbs */ - ret = log_map_dbp->cursor(log_map_dbp, txn, &log_map_dbcp, 0); - assert(ret == 0); /* TODO: err handling */ - ret = ver_dbp->cursor(ver_dbp, txn, &ver_dbcp, 0); - assert(ret == 0); /* TODO: err handling */ - ret = missing_ver_dbp->cursor(missing_ver_dbp, txn, &missing_ver_dbcp, 0); - assert(ret == 0); /* TODO: err handling */ - ret = log_offset_dbp->cursor(log_offset_dbp, txn, &log_offset_dbcp, 0); - assert(ret == 0); /* TODO: err handling */ - - /* loop through version db, one entry per object */ - while ((ret = ver_dbcp->c_get(ver_dbcp, &ver_key, &ver_value, DB_NEXT)) == 0) - { - printf("OID: %llu\n", llu(vk)); - printf("=============================================\n"); - printf(" version: %llu\n", llu(vv)); - - /* next log offset entry should match, no need to search */ - ret = log_offset_dbcp->c_get(log_offset_dbcp, &log_offset_key, - &log_offset_value, DB_NEXT); - assert(ret == 0); /* TODO: err handling */ - assert(lok == vk); - printf(" next log offset: %lld\n", lld(lov)); - - /* search for any missing versions */ - printf(" missing versions: "); - mvk.oid = vk; - mvk.version = 0; - c_get_flag = DB_SET_RANGE; - while((ret = missing_ver_dbcp->c_get(missing_ver_dbcp, - &missing_ver_key, &missing_ver_value, c_get_flag)) == 0) - { - c_get_flag = DB_NEXT; - printf("%llu ", llu(mvk.version)); - } - printf("\n"); - assert(ret == DB_NOTFOUND); /* TODO: err handling */ - - /* search for logical map entries */ - printf(" logical map:\n"); - printf(" ------------------------------------------\n"); - lmk.oid = vk; - lmk.logical_offset_end = 0; - c_get_flag = DB_SET_RANGE; - while((ret = log_map_dbcp->c_get(log_map_dbcp, - &log_map_key, &log_map_value, c_get_flag)) == 0) - { - printf("logical_off: %lld, logical_end: %lld, size: %lld, log_off: %lld, ver: %llu\n", - lld(lmv.logical_offset), lld(lmv.logical_offset_end), - lld(lmv.size), lld(lmv.log_offset), llu(lmv.version)); - c_get_flag = DB_NEXT; - } - assert(ret == DB_NOTFOUND); /* TODO: err handling */ - - printf("\n"); - } - assert(ret == DB_NOTFOUND); /* TODO: err handling */ - - log_map_dbcp->c_close(log_map_dbcp); - log_offset_dbcp->c_close(log_offset_dbcp); - ver_dbcp->c_close(ver_dbcp); - missing_ver_dbcp->c_close(missing_ver_dbcp); - - ret = txn->commit(txn, 0); - if(ret != 0) - { - /* TODO: error handling */ - assert(0); - } - - c_op->error_code = 0; - return(1); -} - - -/* create_op_worker() - * - * creates an object - */ -/* TODO: audit for deadlocks */ -static int create_op_worker(struct ae_op* op) -{ - struct cosd_op *c_op; - int ret; - DB_TXN *txn; - int64_t val; - DBT key, value; - char log_name[PATH_MAX]; - - c_op = ae_op_entry(op, struct cosd_op, op); - assert(c_op); - - /* only support one object for now */ - assert(c_op->u.create.requested_oid == 1); - *c_op->u.create.out_oid = 1; - - /* create a log file */ - sprintf(log_name, "%s/%llu.dat", cosd_log_path, - llu(c_op->u.create.requested_oid)); - ret = open(log_name, O_RDWR|O_CREAT|O_DIRECT|O_EXCL|O_NOATIME, - S_IRUSR|S_IWUSR); - if(ret < 0) - { - c_op->error_code = -errno; - return(1); - } - global_fd = ret; - - /* do db stuff */ - ret = envp->txn_begin(envp, NULL, &txn, 0); - if(ret != 0) - { - /* TODO: error handling */ - c_op->error_code = -1; - return(1); - } - - /* set initial version of 1 */ - val = 1; - COSD_INIT_DBT(key, c_op->u.create.requested_oid); - COSD_INIT_DBT(value, val); - - ret = ver_dbp->put(ver_dbp, txn, &key, &value, 0); - if(ret != 0) - { - /* TODO: error handling */ - assert(0); - } - - /* set initial log offset of 0 */ - val = 0; - ret = log_offset_dbp->put(log_offset_dbp, txn, &key, &value, 0); - if(ret != 0) - { - /* TODO: error handling */ - assert(0); - } - - ret = txn->commit(txn, 0); - if(ret != 0) - { - /* TODO: error handling */ - assert(0); - } - - c_op->error_code = 0; - - return(1); -} - -triton_ret_t triton_cosd_write_post( - uint64_t oid, - uint64_t txn_number, - char** mem_offsets, - int64_t* mem_sizes, - int mem_count, - int64_t* obj_offsets, - int64_t* obj_sizes, - int obj_count, - void (*callback)(void *ptr, int ret), - void *user_ptr, - ae_hints_t hints, - ae_context_t ctx, - ae_op_id_t *op_id) -{ - struct ae_op *op; - struct cosd_op *c_op; - - op = ae_opcache_get(cosd_opcache); - ae_op_fill(op, callback, user_ptr, hints, ctx); - - c_op = ae_op_entry(op, struct cosd_op, op); - c_op->op_id = triton_id_gen(cosd_resource_id, (uint64_t)(op->cache_id)); - c_op->u.write.oid = oid; - c_op->u.write.txn_number = txn_number; - c_op->u.write.mem_count = mem_count; - c_op->u.write.obj_count = obj_count; - - /* copy arrays so that we can modify them internally */ - /* TODO: error handling */ - c_op->u.write.mem_offsets = malloc(mem_count*sizeof(*mem_offsets)); - assert(c_op->u.write.mem_offsets); - memcpy(c_op->u.write.mem_offsets, mem_offsets, - mem_count*sizeof(*mem_offsets)); - - c_op->u.write.mem_sizes = malloc(mem_count*sizeof(*mem_sizes)); - assert(c_op->u.write.mem_sizes); - memcpy(c_op->u.write.mem_sizes, mem_sizes, - mem_count*sizeof(*mem_sizes)); - - c_op->u.write.obj_offsets = malloc(obj_count*sizeof(*obj_offsets)); - assert(c_op->u.write.obj_offsets); - memcpy(c_op->u.write.obj_offsets, obj_offsets, - obj_count*sizeof(*obj_offsets)); - - c_op->u.write.obj_sizes = malloc(obj_count*sizeof(*obj_sizes)); - assert(c_op->u.write.obj_sizes); - memcpy(c_op->u.write.obj_sizes, obj_sizes, - obj_count*sizeof(*obj_sizes)); - - *op_id = c_op->op_id; - - /* TODO: put this in the fill function if we keep it? */ - op->op_worker = write_op_worker; - c_op->cleanup_fn = write_op_cleanup; - - triton_cosd_launch_op(op, triton_cosd_progress_mode); - - return TRITON_SUCCESS; -} -triton_ret_t (* triton_cosd_write)( - uint64_t oid, - uint64_t txn_number, - char** mem_offsets, - int64_t* mem_sizes, - int mem_count, - int64_t* obj_offsets, - int64_t* obj_sizes, - int obj_count, - void (*callback)(void *ptr, int ret), - void *user_ptr, - ae_hints_t hints, - ae_context_t ctx, - ae_op_id_t *op_id) = triton_cosd_write_post; - - -triton_ret_t triton_cosd_dump_post( - void (*callback)(void *ptr, int ret), - void *user_ptr, - ae_hints_t hints, - ae_context_t ctx, - ae_op_id_t *op_id) -{ - struct ae_op *op; - struct cosd_op *c_op; - - op = ae_opcache_get(cosd_opcache); - ae_op_fill(op, callback, user_ptr, hints, ctx); - - c_op = ae_op_entry(op, struct cosd_op, op); - c_op->op_id = triton_id_gen(cosd_resource_id, (uint64_t)(op->cache_id)); - - *op_id = c_op->op_id; - - /* TODO: put this in the fill function if we keep it? */ - op->op_worker = dump_op_worker; - c_op->cleanup_fn = NULL; - - triton_cosd_launch_op(op, triton_cosd_progress_mode); - - return TRITON_SUCCESS; -} -triton_ret_t (* triton_cosd_dump)( - void (*callback)(void *ptr, int ret), - void *user_ptr, - ae_hints_t hints, - ae_context_t ctx, - ae_op_id_t *op_id) = triton_cosd_dump_post; - - -triton_ret_t triton_cosd_create_post( - uint64_t requested_oid, - uint64_t* out_oid, - void (*callback)(void *ptr, int ret), - void *user_ptr, - ae_hints_t hints, - ae_context_t ctx, - ae_op_id_t *op_id) -{ - struct ae_op *op; - struct cosd_op *c_op; - - op = ae_opcache_get(cosd_opcache); - ae_op_fill(op, callback, user_ptr, hints, ctx); - - c_op = ae_op_entry(op, struct cosd_op, op); - c_op->op_id = triton_id_gen(cosd_resource_id, (uint64_t)(op->cache_id)); - c_op->u.create.requested_oid = requested_oid; - c_op->u.create.out_oid = out_oid; - - *op_id = c_op->op_id; - - /* TODO: put this in the fill function if we keep it? */ - op->op_worker = create_op_worker; - c_op->cleanup_fn = NULL; - - triton_cosd_launch_op(op, triton_cosd_progress_mode); - - return TRITON_SUCCESS; -} -triton_ret_t (* triton_cosd_create)( - uint64_t requested_oid, - uint64_t* out_oid, - void (*callback)(void *ptr, int ret), - void *user_ptr, - ae_hints_t hints, - ae_context_t ctx, - ae_op_id_t *op_id) = triton_cosd_create_post; - -int triton_cosd_txn_open(uint64_t oid, uint64_t txn_number) -{ - struct txn_accumulator *txn_acc; - - txn_acc = malloc(sizeof(*txn_acc)); - if(!txn_acc) - { - return(-ENOMEM); - } - memset(txn_acc, 0, sizeof(*txn_acc)); - - txn_acc->txn_number = txn_number; - triton_list_init(&txn_acc->update_list); - - triton_mutex_lock(&txn_mutex); - /* TODO: safety test for duplicate txn numbers */ - triton_hash_add(txn_table, &txn_acc->txn_number, &txn_acc->hash_link); - triton_mutex_unlock(&txn_mutex); - - return(0); -} - - -/* get_version_op_worker() - * - * retrieves the current version number of an object - */ -/* TODO: audit for deadlocks */ -static int get_version_op_worker(struct ae_op* op) -{ - struct cosd_op *c_op; - int ret; - DB_TXN *txn; - uint64_t version; - DBT key, value; - - c_op = ae_op_entry(op, struct cosd_op, op); - assert(c_op); - - /* only support one object for now */ - assert(c_op->u.get_version.oid == 1); - - /* do db stuff */ - ret = envp->txn_begin(envp, NULL, &txn, 0); - if(ret != 0) - { - /* TODO: error handling */ - c_op->error_code = -1; - return(1); - } - - /* read current version */ - COSD_INIT_DBT(key, c_op->u.get_version.oid); - COSD_INIT_DBT(value, version); - - ret = ver_dbp->get(ver_dbp, txn, &key, &value, 0); - if(ret != 0) - { - /* TODO: error handling */ - assert(0); - } - - *c_op->u.get_version.version = version; - - ret = txn->commit(txn, 0); - if(ret != 0) - { - /* TODO: error handling */ - assert(0); - } - - c_op->error_code = 0; - - return(1); -} - - -triton_ret_t triton_cosd_get_version_post( - uint64_t oid, - uint64_t* version, - void (*callback)(void *ptr, int ret), - void *user_ptr, - ae_hints_t hints, - ae_context_t ctx, - ae_op_id_t *op_id) -{ - struct ae_op *op; - struct cosd_op *c_op; - - op = ae_opcache_get(cosd_opcache); - ae_op_fill(op, callback, user_ptr, hints, ctx); - - c_op = ae_op_entry(op, struct cosd_op, op); - c_op->op_id = triton_id_gen(cosd_resource_id, (uint64_t)(op->cache_id)); - c_op->u.get_version.oid = oid; - c_op->u.get_version.version = version; - - *op_id = c_op->op_id; - - /* TODO: put this in the fill function if we keep it? */ - op->op_worker = get_version_op_worker; - c_op->cleanup_fn = NULL; - - triton_cosd_launch_op(op, triton_cosd_progress_mode); - - return TRITON_SUCCESS; -} -triton_ret_t (* triton_cosd_get_version)( - uint64_t oid, - uint64_t* version, - void (*callback)(void *ptr, int ret), - void *user_ptr, - ae_hints_t hints, - ae_context_t ctx, - ae_op_id_t *op_id) = triton_cosd_get_version_post; - - -/* txn_close_op_worker() - * - * closes a transaction - */ -static int txn_close_op_worker(struct ae_op* op) -{ - struct cosd_op *c_op; - int ret; - DB_TXN *txn; - DBT key, value; - struct txn_accumulator* txn_acc; - struct triton_hash_link* hash_link; - struct triton_list_link* iterator; - struct triton_list_link* scratch; - struct logical_map_entry* tmp_entry; - struct logical_map_entry* tmp_update; - DBC *dbc_p = NULL; - struct logical_map_entry lme; - struct logical_map_key lmk; - triton_list_t on_disk_entries; - triton_list_t new_disk_entries; - int on_disk_count = 0; - int done = 0; - int c_get_flag = DB_SET_RANGE; - int64_t version; - int64_t missing_ver; - DBT mv_key, mv_value; - struct missing_version mv; - void* free_ptr; - - c_op = ae_op_entry(op, struct cosd_op, op); - assert(c_op); - - /* only support one object for now */ - assert(c_op->u.txn_close.oid == 1); - - lmk.oid = c_op->u.txn_close.oid; - - /* pull txn accumulator out of hash so no one can touch it */ - triton_mutex_lock(&txn_mutex); - hash_link = triton_hash_search(txn_table, &c_op->u.txn_close.txn_number); - if(!hash_link) - { - /* TODO: txn is gone (which could be normal); error handling */ - c_op->error_code = -1; - triton_mutex_unlock(&txn_mutex); - return(1); - } - txn_acc = triton_hash_get_entry(hash_link, struct txn_accumulator, - hash_link); - triton_list_del(&txn_acc->hash_link); - triton_mutex_unlock(&txn_mutex); - -txn_close_op_retry: - on_disk_count = 0; - done = 0; - c_get_flag = DB_SET_RANGE; - /* clear up on disk list in case this is a retry */ - triton_list_for_each(iterator, scratch, &on_disk_entries) - { - tmp_entry = triton_list_get_entry(iterator, struct - logical_map_entry, list_link); - triton_list_del(&tmp_entry->list_link); - free(tmp_entry); - } - - /* do db stuff */ - ret = envp->txn_begin(envp, NULL, &txn, 0); - if(ret != 0) - { - /* TODO: error handling */ - c_op->error_code = -1; - return(1); - } - - /* create a cursor to move through logical map db */ - /* TODO: check flags */ - ret = log_map_dbp->cursor(log_map_dbp, txn, &dbc_p, 0); - if(ret != 0) - { - txn->abort(txn); - if(ret == DB_LOCK_DEADLOCK) - goto txn_close_op_retry; - /* TODO: error handling */ - assert(0); - } - COSD_INIT_DBT(key, lmk); - COSD_INIT_DBT(value, lme); - - /* TODO: optimize to avoid updates if no log regions need to be - * replaced - */ - - /* loop through each update in the cosd txn */ - triton_list_for_each(iterator, scratch, &txn_acc->update_list) - { - tmp_update = triton_list_get_entry(iterator, struct logical_map_entry, - list_link); - - lmk.logical_offset_end = tmp_update->logical_offset + 1; - done = 0; - while(!done) - { - /* get each potentially overlapping on disk region */ - ret = dbc_p->c_get(dbc_p, &key, &value, c_get_flag); - if(ret == DB_NOTFOUND) - { - done = 1; - break; - } - if(ret != 0) - { - txn->abort(txn); - if(ret == DB_LOCK_DEADLOCK) - goto txn_close_op_retry; - /* TODO: err handling */ - assert(0); - } - - if(lme.logical_offset >= tmp_update->logical_offset_end) - { - /* run out of overlapping regions */ - done = 1; - break; - } - - /* store this in a linked list */ - tmp_entry = malloc(sizeof(*tmp_entry)); - if(!tmp_entry) - { - /* TODO: err handling */ - assert(0); - } - *tmp_entry = lme; - triton_list_add_front(&tmp_entry->list_link, &on_disk_entries); - on_disk_count++; - c_get_flag = DB_NEXT; - - /* TODO: worth optimizing? We can instead calculate exactly - * what needs to be updated/added/removed/left alone for each - * region - */ - /* delete it from db; will be added back later if necessary */ - ret = dbc_p->c_del(dbc_p, 0); - if(ret != 0) - { - txn->abort(txn); - if(ret == DB_LOCK_DEADLOCK) - goto txn_close_op_retry; - /* TODO: err handling */ - assert(0); - } - } - } - ret = dbc_p->c_close(dbc_p); - if(ret != 0) - { - txn->abort(txn); - if(ret == DB_LOCK_DEADLOCK) - goto txn_close_op_retry; - /* TODO: error handling */ - assert(0); - } - - /* merge on disk and txn regions */ - ret = merge_logical_map(&on_disk_entries, on_disk_count, - &txn_acc->update_list, txn_acc->update_list_count, - &new_disk_entries, &free_ptr); - if(ret != 0) - { - /* TODO: err handling */ - assert(0); - } - - /* write new logical map updates */ - triton_list_for_each(iterator, scratch, &new_disk_entries) - { - tmp_entry = triton_list_get_entry(iterator, struct logical_map_entry, - list_link); - lme = *tmp_entry; - lmk.logical_offset_end = lme.logical_offset_end; - ret = log_map_dbp->put(log_map_dbp, txn, &key, &value, 0); - if(ret != 0) - { - txn->abort(txn); - free(free_ptr); - if(ret == DB_LOCK_DEADLOCK) - goto txn_close_op_retry; - /* TODO: err handling */ - assert(0); - } - } - free(free_ptr); - - /* read current version */ - COSD_INIT_DBT(key, c_op->u.txn_close.oid); - COSD_INIT_DBT(value, version); - - ret = ver_dbp->get(ver_dbp, txn, &key, &value, 0); - if(ret != 0) - { - txn->abort(txn); - if(ret == DB_LOCK_DEADLOCK) - goto txn_close_op_retry; - - /* TODO: error handling */ - assert(0); - } - - if(txn_acc->txn_number > version) - { - /* this update is newer than the current version of the object */ - COSD_INIT_DBT(mv_key, mv); - COSD_INIT_DBT_EMPTY(mv_value); - - /* identify skipped version numbers */ - missing_ver = version + 1; - while(missing_ver < txn_acc->txn_number) - { - mv.oid = c_op->u.txn_close.oid; - mv.version = missing_ver; - - /* record each missing ver in db */ - ret = missing_ver_dbp->put(missing_ver_dbp, txn, &mv_key, &mv_value, 0); - if(ret != 0) - { - txn->abort(txn); - if(ret == DB_LOCK_DEADLOCK) - goto txn_close_op_retry; - /* TODO: error handling */ - assert(0); - } - - missing_ver++; - } - - /* bump overall version number */ - version = txn_acc->txn_number; - ret = ver_dbp->put(ver_dbp, txn, &key, &value, 0); - if(ret != 0) - { - txn->abort(txn); - if(ret == DB_LOCK_DEADLOCK) - goto txn_close_op_retry; - /* TODO: error handling */ - assert(0); - } - } - if(txn_acc->txn_number < version) - { - /* this update is older than the current version of the object */ - /* remove it from list of missing versions if present */ - memset(&mv_key, 0, sizeof(DBT)); - mv_key.data = &mv; - mv_key.size = sizeof(mv); - mv.oid = c_op->u.txn_close.oid; - mv.version = txn_acc->txn_number; - - /* delete from db db */ - ret = missing_ver_dbp->del(missing_ver_dbp, txn, &mv_key, 0); - if(ret == DB_LOCK_DEADLOCK) - { - txn->abort(txn); - goto txn_close_op_retry; - } - if(ret != 0 && ret != DB_NOTFOUND) - { - txn->abort(txn); - /* TODO: error handling */ - assert(0); - } - } - - /* flush current log offset to db in the same txn */ - /* TODO: any deadlock potential here because of ordering with mutex - * relative to txn? - */ - triton_mutex_lock(&global_log_mutex); - COSD_INIT_DBT(key, c_op->u.txn_close.oid); - COSD_INIT_DBT(value, global_log_offset); - - ret = log_offset_dbp->put(log_offset_dbp, txn, &key, &value, 0); - if(ret != 0) - { - txn->abort(txn); - if(ret == DB_LOCK_DEADLOCK) - goto txn_close_op_retry; - - /* TODO: error handling */ - assert(0); - } - triton_mutex_unlock(&global_log_mutex); - - ret = txn->commit(txn, 0); - if(ret != 0) - { - txn->abort(txn); - if(ret == DB_LOCK_DEADLOCK) - goto txn_close_op_retry; - - /* TODO: error handling */ - assert(0); - } - - triton_list_for_each(iterator, scratch, &on_disk_entries) - { - tmp_entry = triton_list_get_entry(iterator, struct - logical_map_entry, list_link); - triton_list_del(&tmp_entry->list_link); - free(tmp_entry); - } - triton_list_for_each(iterator, scratch, &txn_acc->update_list) - { - tmp_entry = triton_list_get_entry(iterator, struct - logical_map_entry, list_link); - triton_list_del(&tmp_entry->list_link); - free(tmp_entry); - } - - free(txn_acc); - c_op->error_code = 0; - return(1); -} - -triton_ret_t triton_cosd_txn_close_post( - uint64_t oid, - uint64_t txn_number, - void (*callback)(void *ptr, int ret), - void *user_ptr, - ae_hints_t hints, - ae_context_t ctx, - ae_op_id_t *op_id) -{ - struct ae_op *op; - struct cosd_op *c_op; - - op = ae_opcache_get(cosd_opcache); - ae_op_fill(op, callback, user_ptr, hints, ctx); - - c_op = ae_op_entry(op, struct cosd_op, op); - c_op->op_id = triton_id_gen(cosd_resource_id, (uint64_t)(op->cache_id)); - c_op->u.txn_close.oid = oid; - c_op->u.txn_close.txn_number = txn_number; - - *op_id = c_op->op_id; - - /* TODO: put this in the fill function if we keep it? */ - op->op_worker = txn_close_op_worker; - c_op->cleanup_fn = NULL; - - triton_cosd_launch_op(op, triton_cosd_progress_mode); - - return TRITON_SUCCESS; -} -triton_ret_t (* triton_cosd_txn_close)( - uint64_t oid, - uint64_t txn_number, - void (*callback)(void *ptr, int ret), - void *user_ptr, - ae_hints_t hints, - ae_context_t ctx, - ae_op_id_t *op_id) = triton_cosd_txn_close_post; - - -/* merge_logical_map() - * - * merges two logical maps into one map. The output map is allocated from - * scratch and can be freed via the free_ptr argument. - * - * returns 0 on success, -errno on failure - */ -static int merge_logical_map(triton_list_t* list1_in, int - list1_count, triton_list_t* list2_in, int list2_count, - triton_list_t* list_out, void** free_ptr) -{ - struct triton_list_link* iterator; - struct triton_list_link* scratch; - struct logical_map_entry* tmp_entry; - int i=0; - int j=0; - int k=0; - struct logical_map_entry* list1_array; - struct logical_map_entry* list2_array; - struct logical_map_entry* list_out_array; - struct logical_map_entry* winner; - struct logical_map_entry* loser; - int list_out_array_count = 0; - int64_t logical_offset; - - /* maximum size of merged array */ - if(list1_count > list2_count) - list_out_array_count = list1_count * 3; - else - list_out_array_count = list2_count * 3; - - /* allocate linear arrays to use for sorting */ - list_out_array = malloc(list_out_array_count*sizeof(*list_out_array)); - list1_array = malloc(list1_count*sizeof(*list1_array)); - list2_array = malloc(list2_count*sizeof(*list2_array)); - /* TODO: err handling */ - assert(list_out_array && list1_array && list2_array); - - /* populate arrays */ - i=0; - triton_list_for_each(iterator, scratch, list1_in) - { - tmp_entry = triton_list_get_entry(iterator, struct logical_map_entry, - list_link); - list1_array[i] = *tmp_entry; - i++; - } - assert(i==list1_count); - i=0; - triton_list_for_each(iterator, scratch, list2_in) - { - tmp_entry = triton_list_get_entry(iterator, struct logical_map_entry, - list_link); - list2_array[i] = *tmp_entry; - i++; - } - assert(i==list2_count); - - /* sort arrays */ - qsort(list1_array, list1_count, sizeof(struct logical_map_entry), - cmp_lme); - qsort(list2_array, list2_count, sizeof(struct logical_map_entry), - cmp_lme); - - /* pick lowest logical offset to use for iterator */ - assert(list1_count || list2_count); /* at least one needs entries */ - if(list1_count == 0) - logical_offset = list2_array[0].logical_offset; - else if(list2_count == 0) - logical_offset = list1_array[0].logical_offset; - else - { - logical_offset = COSD_MIN(list1_array[0].logical_offset, - list2_array[0].logical_offset); - } - - /* loop through arrays and merge into output array */ - i=0; - j=0; - while(i<list1_count || j<list2_count) - { - - /* consume any elements that have been entirely passed over */ - if(i < list1_count && list1_array[i].logical_offset_end <= logical_offset) - { - i++; - continue; - } - if(j < list2_count && list2_array[j].logical_offset_end <= logical_offset) - { - j++; - continue; - } - - /* shave off the beginning of any extent that has been partially - * passed over - */ - if(i < list1_count && list1_array[i].logical_offset < logical_offset) - { - list1_array[i].size -= (logical_offset - - list1_array[i].logical_offset); - list1_array[i].log_offset += (logical_offset - - list1_array[i].logical_offset); - list1_array[i].logical_offset = logical_offset; - } - if(j < list2_count && list2_array[j].logical_offset < logical_offset) - { - list2_array[j].size -= (logical_offset - - list2_array[j].logical_offset); - list2_array[j].log_offset += (logical_offset - - list2_array[j].logical_offset); - list2_array[j].logical_offset = logical_offset; - } - - /* if one list is already exhausted, then the other wins */ - if(i >= list1_count) - { - logical_offset = list2_array[j].logical_offset_end; - list_out_array[k++] = list2_array[j++]; - continue; - } - if(j >= list2_count) - { - logical_offset = list1_array[i].logical_offset_end; - list_out_array[k++] = list1_array[i++]; - continue; - } - - /* pick winner for overlapped regions */ - if(list1_array[i].logical_offset == list2_array[j].logical_offset) - { - /* TODO: think about how to handle version wrap... */ - if(list1_array[i].version > list2_array[j].version) - { - winner = &list1_array[i]; - loser = &list2_array[j]; - } - else - { - winner = &list2_array[j]; - loser = &list1_array[i]; - } - list_out_array[k] = *winner; - logical_offset = COSD_MIN(winner->logical_offset_end, - loser->logical_offset_end); - list_out_array[k].logical_offset_end = logical_offset; - list_out_array[k].size = list_out_array[k].logical_offset_end - - list_out_array[k].logical_offset; - k++; - continue; - } - - /* pick easy winner for any non-overlapping regions */ - if(list1_array[i].logical_offset < list2_array[j].logical_offset) - { - winner = &list1_array[i]; - loser = &list2_array[j]; - } - if(list2_array[j].logical_offset < list1_array[i].logical_offset) - { - winner = &list2_array[j]; - loser = &list1_array[i]; - } - list_out_array[k] = *winner; - logical_offset = COSD_MIN(winner->logical_offset_end, - loser->logical_offset); - list_out_array[k].logical_offset_end = logical_offset; - list_out_array[k].size = list_out_array[k].logical_offset_end - - list_out_array[k].logical_offset; - k++; - } - - /* TODO: assert that there is no overlap of extents _within_ either - * input array - */ - - /* merge any adjacent entries in output array that have the same version - * number. The above loop may have split some regions more than was - * strictly needed - */ - i=0; - j=1; - list_out_array_count = k; - while(j<k) - { - if(list_out_array[i].logical_offset_end == - list_out_array[j].logical_offset && - list_out_array[i].version == list_out_array[j].version && - (list_out_array[i].log_offset + list_out_array[j].size == - list_out_array[j].log_offset)) - { - list_out_array[i].size += list_out_array[j].size; - list_out_array[i].logical_offset_end += list_out_array[j].size; - list_out_array_count--; - } - else - { - i++; - list_out_array[i] = list_out_array[j]; - } - j++; - } - - /* turn final array into a linked list */ - triton_list_init(list_out); - for(i=0; i<list_out_array_count; i++) - { - triton_list_add_front(&list_out_array[i].list_link, list_out); - } - *free_ptr = list_out_array; - free(list1_array); - free(list2_array); - - return(0); -} - -static int compare_log_map_key(DB * dbp, const DBT * a, const DBT * b) -{ - struct logical_map_key* lmk_a; - struct logical_map_key* lmk_b; - - lmk_a = (struct logical_map_key *) a->data; - lmk_b = (struct logical_map_key *) b->data; - - /* oid takes precedence */ - if(lmk_a->oid > lmk_b->oid) - return(1); - if(lmk_a->oid < lmk_b->oid) - return(-1); - - /* then ending offset within oid */ - if(lmk_a->logical_offset_end > lmk_b->logical_offset_end) - return(1); - if(lmk_a->logical_offset_end < lmk_b->logical_offset_end) - return(-1); - - return 0; -} - -static int compare_missing_version(DB * dbp, const DBT * a, const DBT * b) -{ - struct missing_version* ver_a; - struct missing_version* ver_b; - - ver_a = (struct missing_version *) a->data; - ver_b = (struct missing_version *) b->data; - - /* oid takes precendenc */ - if(ver_a->oid > ver_b->oid) - return 1; - if(ver_a->oid < ver_b->oid) - return -1; - - /* then version within oid */ - if(ver_a->version > ver_b->version) - return 1; - if(ver_a->version < ver_b->version) - return -1; - - return(0); -} - -static int compare_uint64(DB * dbp, const DBT * a, const DBT * b) -{ - uint64_t* int_a; - uint64_t* int_b; - - int_a = (uint64_t *) a->data; - int_b = (uint64_t *) b->data; - - if(*int_a > *int_b) - return(1); - if(*int_a < *int_b) - return(-1); - - return(0); -} - -/* cmp_lme() - * - * logical map entry comparison function for qsort() - */ -static int cmp_lme(const void *p1, const void *p2) -{ - const struct logical_map_entry* lme1 = p1; - const struct logical_map_entry* lme2 = p2; - - if(lme1->logical_offset < lme2->logical_offset) - return(-1); - if(lme1->logical_offset > lme2->logical_offset) - return(1); - - return(0); -} - -/* - * Local variables: - * c-indent-level: 4 - * c-basic-offset: 4 - * End: - * - * vim: ts=8 sts=4 sw=4 expandtab - */ diff --git a/code/src/cosd/prototype/cosd-prototype.hae b/code/src/cosd/prototype/cosd-prototype.hae deleted file mode 100644 index fa29f67..0000000 --- a/code/src/cosd/prototype/cosd-prototype.hae +++ /dev/null @@ -1,116 +0,0 @@ -#ifndef __COSD_PROTOTYPE_GSH__ -#define __COSD_PROTOTYPE_GSH__ - -/** \defgroup COSD prototype - * - * This is a prototype COSD to be used for initial studies of the Grayskull - * replication protocol. - * - * Notes: - * - All functions return 0 on success or -errno on failure unless otherwise - * noted - * . - * @{ - */ - -/** \file - * Declarations for COSD object storage resource. - */ - -#include "src/aesop/aesop.h" - -/** modes of making progress on posted storage operations */ -enum progress_mode -{ - TRITON_PROG_NONE = 0, /**< invalid mode */ - TRITON_PROG_POLL, /**< requires active polling by client */ - TRITON_PROG_THREAD_PER_OP, /**< spawns new thread for each op */ - TRITON_PROG_THREAD_POOL, /**< uses pre-allocated thread pool */ - TRITON_PROG_MAX, /**< invalid mode */ -}; - -/** - * Initializes COSD interface - */ -int triton_cosd_init( - enum progress_mode mode, /**< progress mode */ - const char* path /**< local path to use for storing data, - will be created if needed */ -); - -/** - * Shuts down COSD interface - */ -int triton_cosd_finalize(void); - -/** - * Creates a new object - * \return 0 on success, -errno on failure - */ -__blocking int triton_cosd_create( - uint64_t requested_oid, /**< requested identifier, a value of zero - allows OSD to choose. */ - uint64_t* out_oid /**< assigned identifier */ -); - -/** - * Retrieves current version number of object - * \return 0 on success, -errno on failure - */ -__blocking int triton_cosd_get_version( - uint64_t oid, /**< object to operate on */ - uint64_t* version /**< version number of object */ -); - -/** - * Opens a txn - * \return 0 on success, -errno on failure - */ -int triton_cosd_txn_open( - uint64_t oid, /**< object to operate on */ - uint64_t txn_number /**< caller-assigned txn identifier */ -); - -/** - * Closes a txn - * \return 0 on success, -errno on failure - */ -__blocking int triton_cosd_txn_close( - uint64_t oid, /**< object to operate on */ - uint64_t txn_number /**< caller-assigned txn identifier */ -); - -/** - * Writes data into an object - * \return 0 on success, -errno on failure - */ -__blocking int triton_cosd_write( - uint64_t oid, /**< object to operate on */ - uint64_t txn_number, /**< txn identifier */ - char** mem_offsets, /**< memory region pointers */ - int64_t* mem_sizes, /**< memory region sizes */ - int mem_count, /**< memory region count */ - int64_t* obj_offsets, /**< object region offsets */ - int64_t* obj_sizes, /**< object region sizes */ - int obj_count /**< object region count */ -); - - -/** - * Dumps object version and log information from cosd to stdout - * \return 0 on success, -errno on failure - */ -__blocking int triton_cosd_dump(void); - -#endif - -/* @} */ - -/* - * Local variables: - * c-indent-level: 4 - * c-basic-offset: 4 - * End: - * - * vim: ft=c ts=8 sts=4 sw=4 expandtab - */ diff --git a/code/src/cosd/prototype/module.mk.in b/code/src/cosd/prototype/module.mk.in deleted file mode 100644 index 9449bbd..0000000 --- a/code/src/cosd/prototype/module.mk.in +++ /dev/null @@ -1,6 +0,0 @@ -DIR := resources/cosd-prototype - -GSHDR += $(DIR)/cosd-prototype.hae -LIBSRC += $(DIR)/cosd-prototype.c - -MODCFLATRITON_$(DIR) = @DB_CFLAGS@ diff --git a/code/src/cosd/prototype/test/4M-w-serial.txt b/code/src/cosd/prototype/test/4M-w-serial.txt deleted file mode 100644 index 22c07a2..0000000 --- a/code/src/cosd/prototype/test/4M-w-serial.txt +++ /dev/null @@ -1,7 +0,0 @@ -# <op> <offset> <size> -write 0 4194304 -write 4194304 4194304 -write 8388608 4194304 -write 12582912 4194304 -write 16777216 4194304 -write 20971520 4194304 diff --git a/code/src/cosd/prototype/test/README b/code/src/cosd/prototype/test/README deleted file mode 100644 index 8b13789..0000000 --- a/code/src/cosd/prototype/test/README +++ /dev/null @@ -1 +0,0 @@ - diff --git a/code/src/cosd/prototype/test/cosd-bench-concurrent.ae b/code/src/cosd/prototype/test/cosd-bench-concurrent.ae deleted file mode 100644 index bc5c8e5..0000000 --- a/code/src/cosd/prototype/test/cosd-bench-concurrent.ae +++ /dev/null @@ -1,235 +0,0 @@ - -#include <stdio.h> -#include <errno.h> -#include "src/aesop/aesop.h" -#include "src/cosd/prototype/cosd-prototype.hae" -#include "triton-config.h" - -/* TODO: this needs to be in a header somewhere */ -#ifndef llu -#if SIZEOF_LONG_INT == 4 -# define llu(x) (x) -# define lld(x) (x) -# define SCANF_lld lld -#elif SIZEOF_LONG_INT == 8 -# define llu(x) (unsigned long long)(x) -# define lld(x) (long long)(x) -# define SCANF_lld ld -#else -# error Unexpected sizeof(long int) -#endif -#endif - -enum op_type -{ - WRITE, - READ -}; - -struct bench_op -{ - int64_t offset; - int64_t size; - enum op_type type; - struct triton_list_link list_link; -}; - -TRITON_LIST_DEFINE(op_list); -triton_mutex_t op_list_mutex = TRITON_MUTEX_INITIALIZER; - -static __blocking int do_cosd_test(void) -{ - int ret; - - uint64_t out_oid1; - uint64_t version; - - ret = triton_cosd_create(1, &out_oid1); - if(ret == -EEXIST) - { - printf("# operating on existing object.\n"); - } - else if(ret != 0) - { - printf("Error creating oid=1: %d\n", ret); - return 1; - } - - ret = triton_cosd_get_version(1, &version); - if(ret != 0) - { - printf("Error getting version number for oid=1: %d\n", ret); - return(1); - } - - pwait - { - int i; - /* TODO: make "16" tunable */ - for(i=0; i<16; i++) - { - pbranch - { - struct triton_list_link* tmp_link; - char* buffer = NULL; - uint64_t b_version; - struct bench_op* tmp_op; - int b_ret; - /* TODO: make buffer size configurable, and check that - * nothing in workload desc is bigger than this - */ - int64_t buffer_size = 4*1024*1024; - - buffer = malloc(buffer_size); - assert(buffer); - - triton_mutex_lock(&op_list_mutex); - while((tmp_link = triton_queue_dequeue(&op_list)) != NULL) - { - b_version = version++; - triton_mutex_unlock(&op_list_mutex); - - tmp_op = triton_list_get_entry(tmp_link, struct bench_op, - list_link); - /* only writes for now */ - assert(tmp_op->type == WRITE); - ret = triton_cosd_txn_open(1, b_version); - if(ret != 0) - { - /* TODO: err handling */ - assert(0); - } - - b_ret = triton_cosd_write(1, b_version, &buffer, - &buffer_size, 1, &tmp_op->offset, &tmp_op->size, 1); - if(b_ret < 0) - { - /* TODO: error handling */ - assert(0); - } - - ret = triton_cosd_txn_close(1, b_version); - if(ret != 0) - { - /* TODO: error handling */ - assert(0); - } - - triton_mutex_lock(&op_list_mutex); - } - triton_mutex_unlock(&op_list_mutex); - - free(buffer); - } - } - } - -#if 0 - ret = triton_cosd_dump(); - assert(ret == 0); -#endif - return 0; -} - -int done = 0; - -static void done_callback(void *up, int ret) -{ - done = 1; -} - - -int main(int argc, char *argv[]) -{ - triton_context_t ctx; - triton_op_id_t op_id; - int mode = TRITON_PROG_POLL; - int pc = 0; - FILE *desc = 0; - char line[2048]; - char op_string[100]; - int64_t size; - int64_t offset; - int ret; - struct bench_op* tmp_op; - - if(argc != 4) - { - fprintf(stderr, "Usage: cosd1 <1|2> <workload description file> <cosd dir>\n"); - fprintf(stderr, " # 1 for polling\n"); - fprintf(stderr, " # 2 for thread-per-op\n"); - return(-1); - } - - sscanf(argv[1], "%d", &mode); - if(mode > 2 || mode < 1) - { - fprintf(stderr, "Usage: cosd1 <1|2>\n"); - fprintf(stderr, " # 1 for polling\n"); - fprintf(stderr, " # 2 for thread-per-op\n"); - return(-1); - } - - /* parse description of workload */ - desc = fopen(argv[2], "r"); - if(!desc) - { - perror("fopen"); - return(-1); - } - while(fgets(line, 2048, desc)) - { - if(line[0] == '#') - continue; -#if SIZEOF_LONG_INT == 4 - ret = sscanf(line, "%s %lld %lld", op_string, &offset, &size); -#else - ret = sscanf(line, "%s %ld %ld", op_string, &offset, &size); -#endif - if(ret != 3) - { - fprintf(stderr, "Error: bad line: %s\n", line); - return(-1); - } - tmp_op = malloc(sizeof(*tmp_op)); - assert(tmp_op); - - /* only writes for now */ - assert(strcmp(op_string, "write") == 0); - tmp_op->type = WRITE; - tmp_op->offset = offset; - tmp_op->size = size; - triton_queue_enqueue(&tmp_op->list_link, &op_list); - } - fclose(desc); - - if(mode == 1) - printf("# Initializing cosd in poll-driven mode.\n"); - else - printf("# Initializing cosd in thread-per-op mode.\n"); - - triton_cosd_init(mode, argv[3]); - - triton_context_create(&ctx, 1, "cosd"); - - done = 0; - do_cosd_test_post(done_callback, NULL, NULL, ctx, &op_id); - while(done == 0) - { - pc++; - triton_poll(ctx, 10000); - } - - triton_cosd_finalize(); - triton_context_destroy(ctx); - return 0; -} - -/* - * Local variables: - * c-indent-level: 4 - * c-basic-offset: 4 - * End: - * - * vim: ft=c ts=8 sts=4 sw=4 expandtab - */ diff --git a/code/src/cosd/prototype/test/cosd1.ae b/code/src/cosd/prototype/test/cosd1.ae deleted file mode 100644 index 7b2b51a..0000000 --- a/code/src/cosd/prototype/test/cosd1.ae +++ /dev/null @@ -1,236 +0,0 @@ - -#include <stdio.h> -#include <errno.h> -#include "src/aesop/aesop.h" -#include "src/cosd/prototype/cosd-prototype.hae" -#include "triton-config.h" - -/* TODO: this needs to be in a header somewhere */ -#ifndef llu -#if SIZEOF_LONG_INT == 4 -# define llu(x) (x) -# define lld(x) (x) -# define SCANF_lld "%lld" -#elif SIZEOF_LONG_INT == 8 -# define llu(x) (unsigned long long)(x) -# define lld(x) (long long)(x) -# define SCANF_lld "%ld" -#else -# error Unexpected sizeof(long int) -#endif -#endif - -static __blocking int do_cosd_test(void) -{ - int ret; - char buffer[4096]; - - int64_t buffer_szs[3]; - char* buffer_offsets[3]; - int64_t obj_offsets[3]; - int64_t obj_szs[3]; - - uint64_t out_oid1; - uint64_t version; - - printf("Creating oid 1 (if it doesn't already exist)...\n"); - ret = triton_cosd_create(1, &out_oid1); - if(ret != 0 && ret != -EEXIST) - { - printf("Error creating oid=1: %d\n", ret); - return 1; - } - printf("DONE\n"); - - printf("Getting version number of oid 1...\n"); - ret = triton_cosd_get_version(1, &version); - if(ret != 0) - { - printf("Error getting version number for oid=1: %d\n", ret); - return(1); - } - printf("DONE: %llu\n", llu(version)); - - ret = triton_cosd_dump(); - assert(ret == 0); - /********************************************************/ - printf("opening txn...\n"); - ret = triton_cosd_txn_open(1, (version+1)); - if(ret != 0) - { - printf("Error opening txn 1: %d\n", ret); - return 1; - } - printf("DONE\n"); - - printf("writing 0-1024...\n"); - buffer_offsets[0] = buffer; - buffer_szs[0] = 1024; - obj_offsets[0] = 0; - obj_szs[0] = 1024; - ret = triton_cosd_write(1, (version+1), buffer_offsets, buffer_szs, 1, - obj_offsets, obj_szs, 1); - if(ret != 0) - { - printf("Error writing 0-1024: %d\n", ret); - return 1; - } - printf("DONE\n"); - - printf("closing txn...\n"); - ret = triton_cosd_txn_close(1, (version+1)); - if(ret != 0) - { - printf("Error closing txn 1: %d\n", ret); - return 1; - } - printf("DONE\n"); - - ret = triton_cosd_dump(); - assert(ret == 0); - /********************************************************/ - printf("opening txn...\n"); - ret = triton_cosd_txn_open(1, (version+3)); - if(ret != 0) - { - printf("Error opening txn 1: %d\n", ret); - return 1; - } - printf("DONE\n"); - - printf("writing with listio (3 mem regions, 2 file regions)...\n"); - buffer_offsets[0] = buffer; - buffer_offsets[1] = buffer+512; - buffer_offsets[2] = buffer+768; - buffer_szs[0] = 512; - buffer_szs[1] = 256; - buffer_szs[2] = 256; - obj_offsets[0] = 1024; - obj_offsets[1] = 2000; - obj_szs[0] = 100; - obj_szs[1] = 924; - ret = triton_cosd_write(1, (version+3), buffer_offsets, buffer_szs, 3, - obj_offsets, obj_szs, 2); - if(ret != 0) - { - printf("Error writing with listio: %d\n", ret); - return 1; - } - printf("DONE\n"); - - printf("closing txn...\n"); - ret = triton_cosd_txn_close(1, (version+3)); - if(ret != 0) - { - printf("Error closing txn 1: %d\n", ret); - return 1; - } - printf("DONE\n"); - - ret = triton_cosd_dump(); - assert(ret == 0); - /********************************************************/ - printf("opening txn...\n"); - ret = triton_cosd_txn_open(1, (version+2)); - if(ret != 0) - { - printf("Error opening txn 1: %d\n", ret); - return 1; - } - printf("DONE\n"); - - printf("writing bigger region with old version...\n"); - buffer_offsets[0] = buffer; - buffer_szs[0] = 4096; - obj_offsets[0] = 200; - obj_szs[0] = 4096; - ret = triton_cosd_write(1, (version+2), buffer_offsets, buffer_szs, 1, - obj_offsets, obj_szs, 1); - if(ret != 0) - { - printf("Error writing with listio: %d\n", ret); - return 1; - } - printf("DONE\n"); - - printf("closing txn...\n"); - ret = triton_cosd_txn_close(1, (version+2)); - if(ret != 0) - { - printf("Error closing txn 1: %d\n", ret); - return 1; - } - printf("DONE\n"); - - - - ret = triton_cosd_dump(); - assert(ret == 0); - return 0; -} - -int done = 0; - -static void done_callback(void *up, int ret) -{ - done = 1; -} - - -int main(int argc, char *argv[]) -{ - triton_context_t ctx; - triton_op_id_t op_id; - int mode = TRITON_PROG_POLL; - int pc = 0; - - if(argc != 2) - { - fprintf(stderr, "Usage: cosd1 <1|2>\n"); - fprintf(stderr, " # 1 for polling\n"); - fprintf(stderr, " # 2 for thread-per-op\n"); - return(-1); - } - - sscanf(argv[1], "%d", &mode); - if(mode > 2 || mode < 1) - { - fprintf(stderr, "Usage: cosd1 <1|2>\n"); - fprintf(stderr, " # 1 for polling\n"); - fprintf(stderr, " # 2 for thread-per-op\n"); - return(-1); - } - - if(mode == 1) - printf("Initializing cosd in poll-driven mode...\n"); - else - printf("Initializing cosd in thread-per-op mode...\n"); - - triton_cosd_init(mode, "/tmp/cosd"); - printf("Done.\n"); - - triton_context_create(&ctx, 1, "cosd"); - - done = 0; - do_cosd_test_post(done_callback, NULL, NULL, ctx, &op_id); - while(done == 0) - { - pc++; - triton_poll(ctx, 10000); - fflush(NULL); - printf("polled %d times...\n", pc); - } - - triton_cosd_finalize(); - triton_context_destroy(ctx); - return 0; -} - -/* - * Local variables: - * c-indent-level: 4 - * c-basic-offset: 4 - * End: - * - * vim: ft=c ts=8 sts=4 sw=4 expandtab - */ diff --git a/code/src/cosd/prototype/test/module.mk.in b/code/src/cosd/prototype/test/module.mk.in deleted file mode 100644 index 5b6d349..0000000 --- a/code/src/cosd/prototype/test/module.mk.in +++ /dev/null @@ -1,8 +0,0 @@ -DIR := resources/cosd-prototype/test - -AETESTSRC += $(DIR)/cosd1.ae -AETESTSRC += $(DIR)/cosd-bench-concurrent.ae -AETESTSRC += $(DIR)/workload-gen.ae - -MODLIBS_$(DIR) = -lpthread @DB_LIB@ - diff --git a/code/src/cosd/prototype/test/workload-gen.ae b/code/src/cosd/prototype/test/workload-gen.ae deleted file mode 100644 index f83c225..0000000 --- a/code/src/cosd/prototype/test/workload-gen.ae +++ /dev/null @@ -1,122 +0,0 @@ -#include <stdio.h> -#include <errno.h> -#include <assert.h> -#include <stdlib.h> - -#include "src/aesop/aesop.h" -#include "src/cosd/prototype/cosd-prototype.hae" -#include "triton-config.h" - - -/* - * arguments: - * ./workload-gen <total size> <op size> <l|r> - */ - -/* TODO: this needs to be in a header somewhere */ -#ifndef llu -#if SIZEOF_LONG_INT == 4 -# define llu(x) (x) -# define lld(x) (x) -# define SCANF_lld lld -#elif SIZEOF_LONG_INT == 8 -# define llu(x) (unsigned long long)(x) -# define lld(x) (long long)(x) -# define SCANF_lld ld -#else -# error Unexpected sizeof(long int) -#endif -#endif - -int main(int argc, char **argv) -{ - int64_t total_size = -1; - int64_t op_size = -1; - int random_flag = 0; - int op_count = 0; - int64_t* offset_array; - int i; - int64_t current_offset = 0; - - if(argc != 4) - { - fprintf(stderr, "Usage: %s <total size> <op size> <l|r>\n", - argv[0]); - fprintf(stderr, " r=random, l=linear\n"); - return(-1); - } - -#if SIZEOF_LONG_INT == 4 - sscanf(argv[1], "%lld", &total_size); - sscanf(argv[2], "%lld", &op_size); -#else - sscanf(argv[1], "%ld", &total_size); - sscanf(argv[2], "%ld", &op_size); -#endif - - if(total_size < 1 || op_size < 1) - { - fprintf(stderr, "Usage: %s <total size> <op size> <l|r>\n", - argv[0]); - fprintf(stderr, " r=random, l=linear\n"); - return(-1); - } - - if(strcmp(argv[3], "l") == 0) - random_flag = 0; - else if(strcmp(argv[3], "r") == 0) - random_flag = 1; - else - { - fprintf(stderr, "Usage: %s <total size> <op size> <l|r>\n", - argv[0]); - fprintf(stderr, " r=random, l=linear\n"); - return(-1); - } - - if(total_size % op_size != 0) - { - fprintf(stderr, "Error: sizes must be evenly divisible.\n"); - return(-1); - } - - op_count = total_size/op_size; - - /* allocate one big array with all of the offset */ - offset_array = malloc(op_count*sizeof(int64_t)); - assert(offset_array); - - for(i=0; i<op_count; i++) - { - offset_array[i] = current_offset; - current_offset+= op_size; - } - - if(random_flag && op_count > 1) - { - for(i=0; i<(op_count-1); i++) - { - int j = i + rand() / (RAND_MAX / (op_count-i) + 1); - int64_t t = offset_array[j]; - offset_array[j] = offset_array[i]; - offset_array[i] = t; - } - } - - printf("# <op> <offset> <size>\n"); - for(i=0; i<op_count; i++) - { - printf("write\t%lld\t%lld\n", lld(offset_array[i]), lld(op_size)); - } - - return(0); -} - -/* - * Local variables: - * c-indent-level: 4 - * c-basic-offset: 4 - * End: - * - * vim: ft=c ts=8 sts=4 sw=4 expandtab - */ hooks/post-receive -- Triton Repository
participants (1)
-
noreply@mcs.anl.gov