From 13240670c3b2532efbfd8fc140d3aa3146d80184 Mon Sep 17 00:00:00 2001 From: Jon Meredith Date: Wed, 10 Jun 2009 14:18:26 -0600 Subject: [PATCH] Added bdberl:driver_info() function to get driver parameters. --- c_src/bdberl_drv.c | 69 ++++++++++++++++++++++++++++++++++++++++++-- c_src/bdberl_drv.h | 1 + c_src/bdberl_tpool.c | 10 +++++++ c_src/bdberl_tpool.h | 2 ++ include/bdberl.hrl | 1 + src/bdberl.erl | 32 ++++++++++++++++++++ 6 files changed, 113 insertions(+), 2 deletions(-) diff --git a/c_src/bdberl_drv.c b/c_src/bdberl_drv.c index 14e2239..fd0732c 100644 --- a/c_src/bdberl_drv.c +++ b/c_src/bdberl_drv.c @@ -82,6 +82,7 @@ static void do_async_txnop(void* arg); static void do_async_cursor_get(void* arg); static void do_async_truncate(void* arg); static void do_sync_data_dirs_info(PortData *p); +static void do_sync_driver_info(PortData *d); static int send_dir_info(ErlDrvPort port, ErlDrvTermData pid, const char *path); @@ -906,7 +907,6 @@ static int bdberl_drv_control(ErlDrvData handle, unsigned int cmd, // Outbuf is: <<0:32>> RETURN_INT(0, outbuf); } - case CMD_LOG_DIR_INFO: { FAIL_IF_ASYNC_PENDING(d, outbuf); @@ -933,8 +933,16 @@ static int bdberl_drv_control(ErlDrvData handle, unsigned int cmd, // Outbuf is: <<0:32>> RETURN_INT(0, outbuf); } + case CMD_DRIVER_INFO: + { + FAIL_IF_ASYNC_PENDING(d, outbuf); - + do_sync_driver_info(d); + + // Let caller know that the operation is in progress + // Outbuf is: <<0:32>> + RETURN_INT(0, outbuf); + } } *outbuf = 0; return 0; @@ -1776,6 +1784,63 @@ static void do_sync_data_dirs_info(PortData *d) } +// Send bdberl specific driver info +static void do_sync_driver_info(PortData *d) +{ + unsigned int txn_pending; + unsigned int txn_active; + unsigned int general_pending; + unsigned int general_active; + bdberl_tpool_job_count(G_TPOOL_GENERAL, &general_pending, &general_active); + bdberl_tpool_job_count(G_TPOOL_TXNS, &txn_pending, &txn_active); + + ErlDrvPort port = d->port; + ErlDrvTermData pid = d->port_owner; + ErlDrvTermData response[] = { + ERL_DRV_ATOM, driver_mk_atom("ok"), + // Start of list + ERL_DRV_ATOM, driver_mk_atom("databases_size"), + ERL_DRV_UINT, G_DATABASES_SIZE, + ERL_DRV_TUPLE, 2, + ERL_DRV_ATOM, driver_mk_atom("deadlock_interval"), + ERL_DRV_UINT, G_DEADLOCK_CHECK_INTERVAL, + ERL_DRV_TUPLE, 2, + ERL_DRV_ATOM, driver_mk_atom("trickle_interval"), + ERL_DRV_UINT, G_TRICKLE_INTERVAL, + ERL_DRV_TUPLE, 2, + ERL_DRV_ATOM, driver_mk_atom("trickle_percentage"), + ERL_DRV_UINT, G_TRICKLE_PERCENTAGE, + ERL_DRV_TUPLE, 2, + ERL_DRV_ATOM, driver_mk_atom("checkpoint_interval"), + ERL_DRV_UINT, G_CHECKPOINT_INTERVAL, + ERL_DRV_TUPLE, 2, + ERL_DRV_ATOM, driver_mk_atom("num_general_threads"), + ERL_DRV_UINT, G_NUM_GENERAL_THREADS, + ERL_DRV_TUPLE, 2, + ERL_DRV_ATOM, driver_mk_atom("num_txn_threads"), + ERL_DRV_UINT, G_NUM_TXN_THREADS, + ERL_DRV_TUPLE, 2, + ERL_DRV_ATOM, driver_mk_atom("general_jobs_pending"), + ERL_DRV_UINT, general_pending, + ERL_DRV_TUPLE, 2, + ERL_DRV_ATOM, driver_mk_atom("general_jobs_active"), + ERL_DRV_UINT, general_active, + ERL_DRV_TUPLE, 2, + ERL_DRV_ATOM, driver_mk_atom("txn_jobs_pending"), + ERL_DRV_UINT, txn_pending, + ERL_DRV_TUPLE, 2, + ERL_DRV_ATOM, driver_mk_atom("txn_jobs_active"), + ERL_DRV_UINT, txn_active, + ERL_DRV_TUPLE, 2, + // End of list + ERL_DRV_NIL, + ERL_DRV_LIST, 11+1, + ERL_DRV_TUPLE, 2 + }; + driver_send_term(port, pid, response, sizeof(response) / sizeof(response[0])); +} + + static void* zalloc(unsigned int size) { void* res = driver_alloc(size); diff --git a/c_src/bdberl_drv.h b/c_src/bdberl_drv.h index b81bf32..9daa47a 100644 --- a/c_src/bdberl_drv.h +++ b/c_src/bdberl_drv.h @@ -50,6 +50,7 @@ #define CMD_TXN_STAT_PRINT 30 #define CMD_DATA_DIRS_INFO 31 #define CMD_LOG_DIR_INFO 32 +#define CMD_DRIVER_INFO 33 /** * Command status values diff --git a/c_src/bdberl_tpool.c b/c_src/bdberl_tpool.c index 35ba7da..005f3ed 100644 --- a/c_src/bdberl_tpool.c +++ b/c_src/bdberl_tpool.c @@ -325,3 +325,13 @@ static int is_active_job(TPool* tpool, TPoolJob* job) } return 0; } + +// Return the number of pending and active jobs +void bdberl_tpool_job_count(TPool* tpool, unsigned int *pending_count_ptr, + unsigned int *active_count_ptr) +{ + LOCK(tpool); + *pending_count_ptr = tpool->pending_job_count; + *active_count_ptr = tpool->active_job_count; + UNLOCK(tpool); +} diff --git a/c_src/bdberl_tpool.h b/c_src/bdberl_tpool.h index f1ebee8..58b0f68 100644 --- a/c_src/bdberl_tpool.h +++ b/c_src/bdberl_tpool.h @@ -65,5 +65,7 @@ void bdberl_tpool_run(TPool* tpool, TPoolJobFunc main_fn, void* arg, TPoolJobFun void bdberl_tpool_cancel(TPool* tpool, TPoolJob* job); +void bdberl_tpool_job_count(TPool* tpool, unsigned int *pending_count_ptr, + unsigned int *active_count_ptr); #endif diff --git a/include/bdberl.hrl b/include/bdberl.hrl index 939c741..a92cef4 100644 --- a/include/bdberl.hrl +++ b/include/bdberl.hrl @@ -38,6 +38,7 @@ -define(CMD_TXN_STAT_PRINT, 30). -define(CMD_DATA_DIRS_INFO, 31). -define(CMD_LOG_DIR_INFO, 32). +-define(CMD_DRIVER_INFO, 33). -define(DB_TYPE_BTREE, 1). -define(DB_TYPE_HASH, 2). diff --git a/src/bdberl.erl b/src/bdberl.erl index aa37838..4c00de4 100644 --- a/src/bdberl.erl +++ b/src/bdberl.erl @@ -40,6 +40,7 @@ truncate/0, truncate/1, delete_database/1, cursor_open/1, cursor_next/0, cursor_prev/0, cursor_current/0, cursor_close/0, + driver_info/0, register_logger/0, stop/0]). @@ -2059,6 +2060,22 @@ env_stat_print(Opts) -> env_stat_print() -> env_stat_print([]). + +%%-------------------------------------------------------------------- +%% @doc +%% Retrieve driver info +%% +%% @spec driver_info() -> {ok, [{atom(), number()}]} | {error, Error} +%% +%% @end +%%-------------------------------------------------------------------- +-spec driver_info() -> + {ok, [{atom(), number()}]} | db_error(). + +driver_info() -> + <> = erlang:port_control(get_port(), ?CMD_DRIVER_INFO, <<>>), + recv_val(Rc). + %%-------------------------------------------------------------------- %% @doc %% Registers the port owner pid to receive any BDB err/msg events. Note @@ -2318,3 +2335,18 @@ recv_dirs_info(DirInfos) -> {ok, DirInfos} end. +%% +%% Receive an {ok, Val} pair or an {error, Reason} pair if Rc is ok +%% +recv_val(Rc) -> + case decode_rc(Rc) of + ok -> + receive + {ok, Val} -> + {ok, Val}; + {error, Reason} -> + {error, Reason} + end; + Error -> + {error, Error} + end.