From 7e85e11584bdd452251c67d64bed45867315fb97 Mon Sep 17 00:00:00 2001 From: Monty Taylor Date: Thu, 3 Dec 2009 11:26:03 -0800 Subject: [PATCH] Fixed atomics and getline on solaris. --- clients/memslap.c | 4 ++- clients/ms_atomic.h | 42 +++++++++++++----------- clients/ms_conn.c | 46 +++++++++++++------------- clients/ms_conn.h | 2 +- clients/ms_memslap.h | 4 +-- clients/ms_setting.c | 78 ++++++++++++++++++++++++++++++++++++++++++++ clients/ms_setting.h | 6 ++-- clients/ms_task.c | 12 +++---- clients/ms_thread.c | 12 +++---- 9 files changed, 145 insertions(+), 61 deletions(-) diff --git a/clients/memslap.c b/clients/memslap.c index 3ed6a2b5..298453dd 100644 --- a/clients/memslap.c +++ b/clients/memslap.c @@ -14,6 +14,7 @@ * */ #include +#include #include "ms_sigsegv.h" #include "ms_setting.h" @@ -770,7 +771,8 @@ static void ms_monitor_slap_mode() second++; if ((ms_setting.stat_freq > 0) && (second % ms_setting.stat_freq == 0) - && (ms_stats.active_conns >= ms_setting.nconns)) + && ((int32_t)ms_stats.active_conns >= ms_setting.nconns) + && (ms_stats.active_conns <= (uint32_t)INT_MAX)) { ms_print_statistics(second); } diff --git a/clients/ms_atomic.h b/clients/ms_atomic.h index 580afabf..c833ea8b 100644 --- a/clients/ms_atomic.h +++ b/clients/ms_atomic.h @@ -1,24 +1,28 @@ #ifndef CLIENTS_MS_ATOMIC_H #define CLIENTS_MS_ATOMIC_H -#if defined(__SUNC) +#if defined(__SUNPRO_C) +# define _KERNEL +# include +# undef _KERNEL +#else +# define atomic_add_8(X, Y) __sync_fetch_and_add((X), (Y)) +# define atomic_add_16(X, Y) __sync_fetch_and_add((X), (Y)) +# define atomic_add_32(X, Y) __sync_fetch_and_add((X), (Y)) +# define atomic_add_64(X, Y) __sync_fetch_and_add((X), (Y)) +# define atomic_dec_8(X) __sync_fetch_and_sub((X), 1) +# define atomic_dec_16(X) __sync_fetch_and_sub((X), 1) +# define atomic_dec_32(X) __sync_fetch_and_sub((X), 1) +# define atomic_dec_64(X) __sync_fetch_and_sub((X), 1) +/* The same as above, but these return the new value instead of void */ +# define atomic_add_8_nv(X, Y) __sync_fetch_and_add((X), (Y)) +# define atomic_add_16_nv(X, Y) __sync_fetch_and_add((X), (Y)) +# define atomic_add_32_nv(X, Y) __sync_fetch_and_add((X), (Y)) +# define atomic_add_64_nv(X, Y) __sync_fetch_and_add((X), (Y)) +# define atomic_dec_8_nv(X) __sync_fetch_and_sub((X), 1) +# define atomic_dec_16_nv(X) __sync_fetch_and_sub((X), 1) +# define atomic_dec_32_nv(X) __sync_fetch_and_sub((X), 1) +# define atomic_dec_64_nv(X) __sync_fetch_and_sub((X), 1) +#endif /* defined(__SUNPRO_C) */ -#define _KERNEL -#include -#undef _KERNEL - -inline int32_t __sync_add_and_fetch(volatile int32_t* ptr, int32_t val) -{ - (val == 1) ? atomic_inc_32((volatile uint32_t*)ptr) : atomic_add_32((volatile uint32_t*)ptr, val); - return *ptr; -} - - -inline uint32_t __sync_sub_and_fetch(volatile uint32_t* ptr, uint32_t val) -{ - (val == 1) ? atomic_dec_32(ptr) : atomic_add_32(ptr, 0-(int32_t)val); - return *ptr; -} - -#endif /* defined(__SUNC) */ #endif /* CLIENTS_MS_ATOMIC_H */ diff --git a/clients/ms_conn.c b/clients/ms_conn.c index feb6a476..86e2c68a 100644 --- a/clients/ms_conn.c +++ b/clients/ms_conn.c @@ -40,12 +40,12 @@ static uint64_t key_prefix_seq= KEY_PREFIX_BASE; /* global increasing counter, generating request id for UDP */ -static int32_t udp_request_id= 0; +static volatile uint32_t udp_request_id= 0; extern __thread ms_thread_t ms_thread; /* generate upd request id */ -static int ms_get_udp_request_id(void); +static uint32_t ms_get_udp_request_id(void); /* connect initialize */ @@ -166,9 +166,9 @@ uint64_t ms_get_key_prefix(void) * * @return an unique UDP request id */ -static int ms_get_udp_request_id(void) +static uint32_t ms_get_udp_request_id(void) { - return __sync_fetch_and_add(&udp_request_id, 1); + return atomic_add_32_nv(&udp_request_id, 1); } @@ -358,7 +358,7 @@ static int ms_conn_init(ms_conn_t *c, if (! (ms_setting.facebook_test && is_udp)) { - __sync_fetch_and_add(&ms_stats.active_conns, 1); + atomic_add_32(&ms_stats.active_conns, 1); } return 0; @@ -673,7 +673,7 @@ static void ms_conn_close(ms_conn_t *c) close(c->udpsfd); } - __sync_fetch_and_sub(&ms_stats.active_conns, 1); + atomic_dec_32(&ms_stats.active_conns); ms_conn_free(c); @@ -885,7 +885,7 @@ static int ms_network_connect(ms_conn_t *c, static int ms_reconn(ms_conn_t *c) { int srv_idx= 0; - int srv_conn_cnt= 0; + int32_t srv_conn_cnt= 0; if (ms_setting.rep_write_srv > 0) { @@ -902,7 +902,7 @@ static int ms_reconn(ms_conn_t *c) close(c->sfd); c->tcpsfd[c->cur_idx]= 0; - if (__sync_fetch_and_add(&ms_setting.servers[srv_idx].disconn_cnt, 1) + if (atomic_add_32_nv((volatile uint32_t *)&ms_setting.servers[srv_idx].disconn_cnt, 1) % srv_conn_cnt == 0) { gettimeofday(&ms_setting.servers[srv_idx].disconn_time, NULL); @@ -938,7 +938,7 @@ static int ms_reconn(ms_conn_t *c) ms_setting.udp, &c->sfd) == 0) { c->tcpsfd[c->cur_idx]= c->sfd; - if (__sync_fetch_and_add(&ms_setting.servers[srv_idx].reconn_cnt, 1) + if (atomic_add_32_nv((volatile uint32_t *)(&ms_setting.servers[srv_idx].reconn_cnt), 1) % srv_conn_cnt == 0) { gettimeofday(&ms_setting.servers[srv_idx].reconn_time, NULL); @@ -1032,7 +1032,7 @@ int ms_reconn_socks(ms_conn_t *c) c->tcpsfd[i]= ret_sfd; c->alive_sfds++; - if (__sync_fetch_and_add(&ms_setting.servers[srv_idx].reconn_cnt, 1) + if (atomic_add_32_nv((volatile uint32_t *)(&ms_setting.servers[srv_idx].reconn_cnt), 1) % srv_conn_cnt == 0) { gettimeofday(&ms_setting.servers[srv_idx].reconn_time, NULL); @@ -1569,7 +1569,7 @@ static int ms_udp_read(ms_conn_t *c, char *buf, int len) if (res > 0) { - __sync_fetch_and_add(&ms_stats.bytes_read, res); + atomic_add_64(&ms_stats.bytes_read, res); c->rudpbytes+= res; rbytes+= res; if (res == avail) @@ -1603,7 +1603,7 @@ static int ms_udp_read(ms_conn_t *c, char *buf, int len) if (copybytes == -1) { - __sync_fetch_and_add(&ms_stats.pkt_disorder, 1); + atomic_add_64(&ms_stats.pkt_disorder, 1); } return copybytes; @@ -1681,7 +1681,7 @@ static int ms_try_read_network(ms_conn_t *c) { if (! c->udp) { - __sync_fetch_and_add(&ms_stats.bytes_read, res); + atomic_add_64(&ms_stats.bytes_read, res); } gotdata= 1; c->rbytes+= res; @@ -1745,7 +1745,7 @@ static void ms_verify_value(ms_conn_t *c, if (curr_time.tv_sec - c->curr_task.item->client_time > c->curr_task.item->exp_time + EXPIRE_TIME_ERROR) { - __sync_fetch_and_add(&ms_stats.exp_get, 1); + atomic_add_64(&ms_stats.exp_get, 1); if (ms_setting.verbose) { @@ -1786,7 +1786,7 @@ static void ms_verify_value(ms_conn_t *c, if ((c->curr_task.item->value_size != vlen) || (memcmp(orignval, value, (size_t)vlen) != 0)) { - __sync_fetch_and_add(&ms_stats.vef_failed, 1); + atomic_add_64(&ms_stats.vef_failed, 1); if (ms_setting.verbose) { @@ -2186,7 +2186,7 @@ static int ms_build_udp_headers(ms_conn_t *c) hdr= c->hdrbuf; for (i= 0; i < c->msgused; i++) { - c->msglist[i].msg_iov[0].iov_base= hdr; + c->msglist[i].msg_iov[0].iov_base= (void *)hdr; c->msglist[i].msg_iov[0].iov_len= UDP_HEADER_SIZE; *hdr++= (unsigned char)(c->request_id / 256); *hdr++= (unsigned char)(c->request_id % 256); @@ -2234,7 +2234,7 @@ static int ms_transmit(ms_conn_t *c) res= sendmsg(c->sfd, m, 0); if (res > 0) { - __sync_fetch_and_add(&ms_stats.bytes_written, res); + atomic_add_64(&ms_stats.bytes_written, res); /* We've written some of the data. Remove the completed * iovec entries from the list of pending writes. */ @@ -2249,7 +2249,7 @@ static int ms_transmit(ms_conn_t *c) * adjust it so the next write will do the rest. */ if (res > 0) { - m->msg_iov->iov_base= (unsigned char *)m->msg_iov->iov_base + res; + m->msg_iov->iov_base= (void *)((unsigned char *)m->msg_iov->iov_base + res); m->msg_iov->iov_len-= (uint64_t)res; } return TRANSMIT_INCOMPLETE; @@ -2976,9 +2976,9 @@ int ms_mcd_set(ms_conn_t *c, ms_task_item_t *item) } } - __sync_fetch_and_add(&ms_stats.obj_bytes, - item->key_size + item->value_size); - __sync_fetch_and_add(&ms_stats.cmd_set, 1); + atomic_add_64(&ms_stats.obj_bytes, + item->key_size + item->value_size); + atomic_add_64(&ms_stats.cmd_set, 1); return 0; } /* ms_mcd_set */ @@ -3062,7 +3062,7 @@ int ms_mcd_get(ms_conn_t *c, ms_task_item_t *item, bool verify) } } - __sync_fetch_and_add(&ms_stats.cmd_get, 1); + atomic_add_64(&ms_stats.cmd_get, 1); return 0; } /* ms_mcd_get */ @@ -3161,7 +3161,7 @@ int ms_mcd_mlget(ms_conn_t *c) for (int i= 0; i < c->mlget_task.mlget_num; i++) { item= c->mlget_task.mlget_item[i].item; - __sync_fetch_and_add(&ms_stats.cmd_get, 1); + atomic_add_64(&ms_stats.cmd_get, 1); } return 0; diff --git a/clients/ms_conn.h b/clients/ms_conn.h index efdd4aa9..bb989bed 100644 --- a/clients/ms_conn.h +++ b/clients/ms_conn.h @@ -162,7 +162,7 @@ typedef struct conn /* data for UDP clients */ int udp; /* is this is a UDP "connection" */ - int request_id; /* UDP request ID of current operation, if this is a UDP "connection" */ + uint32_t request_id; /* UDP request ID of current operation, if this is a UDP "connection" */ uint8_t *hdrbuf; /* udp packet headers */ int hdrsize; /* number of headers' worth of space is allocated */ struct sockaddr srv_recv_addr; /* Sent the most recent request to which server */ diff --git a/clients/ms_memslap.h b/clients/ms_memslap.h index 94b53a78..30cc7157 100644 --- a/clients/ms_memslap.h +++ b/clients/ms_memslap.h @@ -69,7 +69,7 @@ typedef struct statistic /* global status statistic structure */ typedef struct stats { - int32_t active_conns; /* active connections */ + volatile uint32_t active_conns; /* active connections */ uint64_t bytes_read; /* read bytes */ uint64_t bytes_written; /* written bytes */ uint64_t obj_bytes; /* object bytes */ @@ -82,7 +82,7 @@ typedef struct stats uint64_t vef_failed; /* total objects of verification failed */ uint64_t unexp_unget; /* total objects which is unexpired but not get */ uint64_t exp_get; /* total objects which is expired but get */ - uint64_t pkt_disorder; /* disorder packages of UDP */ + volatile uint64_t pkt_disorder; /* disorder packages of UDP */ uint64_t pkt_drop; /* packages dropped of UDP */ uint64_t udp_timeout; /* how many times timeout of UDP happens */ } ms_stats_t; diff --git a/clients/ms_setting.c b/clients/ms_setting.c index 8e02bc46..4791c479 100644 --- a/clients/ms_setting.c +++ b/clients/ms_setting.c @@ -59,6 +59,84 @@ static void ms_print_setting(void); static void ms_setting_slapmode_init_pre(void); static void ms_setting_slapmode_init_post(void); +#if defined(__SUNPRO_C) +#include +static ssize_t getline (char **line, size_t *line_size, FILE *fp) +{ + char delim= '\n'; + ssize_t result= 0; + size_t cur_len= 0; + + if (line == NULL || line_size == NULL || fp == NULL) + { + errno = EINVAL; + return -1; + } + + if (*line == NULL || *line_size == 0) + { + char *new_line; + *line_size = 120; + new_line= (char *) realloc (*line, *line_size); + if (new_line == NULL) + { + result= -1; + return result; + } + *line= new_line; + } + + for (;;) + { + char i; + + i = getc(fp); + if (i == EOF) + { + result = -1; + break; + } + + /* Make enough space for len+1 (for final NUL) bytes. */ + if (cur_len + 1 >= *line_size) + { + size_t needed_max= + SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX; + size_t needed= (2 * (*line_size)) + 1; + char *new_line; + + if (needed_max < needed) + needed= needed_max; + if (cur_len + 1 >= needed) + { + result= -1; + errno= EOVERFLOW; + return result; + } + + new_line= (char *)realloc(*line, needed); + if (new_line == NULL) + { + result= -1; + return result; + } + + *line= new_line; + *line_size= needed; + } + + (*line)[cur_len]= i; + cur_len++; + + if (i == delim) + break; + } + (*line)[cur_len] = '\0'; + result= cur_len ? cur_len : result; + + return result; +} +#endif /** * parse the server list string, and build the servers diff --git a/clients/ms_setting.h b/clients/ms_setting.h index 1f1f2347..9283a483 100644 --- a/clients/ms_setting.h +++ b/clients/ms_setting.h @@ -53,8 +53,8 @@ typedef struct mcd_sever int srv_port; /* server port */ /* for calculating how long the server disconnects */ - int32_t disconn_cnt; /* number of disconnections count */ - int32_t reconn_cnt; /* number of reconnections count */ + volatile int32_t disconn_cnt; /* number of disconnections count */ + volatile int32_t reconn_cnt; /* number of reconnections count */ struct timeval disconn_time; /* start time of disconnection */ struct timeval reconn_time; /* end time of reconnection */ } ms_mcd_server_t; @@ -112,7 +112,7 @@ typedef struct setting { int ncpu; /* cpu count of this system */ int nthreads; /* total thread count, must equal or less than cpu cores */ - int nconns; /* total conn count, must multiply by total thread count */ + int nconns; /* total conn count, must multiply by total thread count */ int64_t exec_num; /* total execute number */ int run_time; /* total run time */ diff --git a/clients/ms_task.c b/clients/ms_task.c index 85e85331..c99f67cc 100644 --- a/clients/ms_task.c +++ b/clients/ms_task.c @@ -725,7 +725,7 @@ static void ms_update_multi_get_result(ms_conn_t *c) /* update get miss counter */ if (mlget_item->get_miss) { - __sync_fetch_and_add(&ms_stats.get_misses, 1); + atomic_add_64(&ms_stats.get_misses, 1); } /* get nothing from server for this task item */ @@ -741,7 +741,7 @@ static void ms_update_multi_get_result(ms_conn_t *c) if (curr_time.tv_sec - item->client_time < item->exp_time - EXPIRE_TIME_ERROR) { - __sync_fetch_and_add(&ms_stats.unexp_unget, 1); + atomic_add_64(&ms_stats.unexp_unget, 1); if (ms_setting.verbose) { @@ -779,7 +779,7 @@ static void ms_update_multi_get_result(ms_conn_t *c) } else { - __sync_fetch_and_add(&ms_stats.vef_miss, 1); + atomic_add_64(&ms_stats.vef_miss, 1); if (ms_setting.verbose) { @@ -829,7 +829,7 @@ static void ms_update_single_get_result(ms_conn_t *c, ms_task_item_t *item) /* update get miss counter */ if ((c->precmd.cmd == CMD_GET) && c->curr_task.get_miss) { - __sync_fetch_and_add(&ms_stats.get_misses, 1); + atomic_add_64(&ms_stats.get_misses, 1); } /* get nothing from server for this task item */ @@ -846,7 +846,7 @@ static void ms_update_single_get_result(ms_conn_t *c, ms_task_item_t *item) if (curr_time.tv_sec - item->client_time < item->exp_time - EXPIRE_TIME_ERROR) { - __sync_fetch_and_add(&ms_stats.unexp_unget, 1); + atomic_add_64(&ms_stats.unexp_unget, 1); if (ms_setting.verbose) { @@ -884,7 +884,7 @@ static void ms_update_single_get_result(ms_conn_t *c, ms_task_item_t *item) } else { - __sync_fetch_and_add(&ms_stats.vef_miss, 1); + atomic_add_64(&ms_stats.vef_miss, 1); if (ms_setting.verbose) { diff --git a/clients/ms_thread.c b/clients/ms_thread.c index e1c00e07..4db08750 100644 --- a/clients/ms_thread.c +++ b/clients/ms_thread.c @@ -67,10 +67,10 @@ static void ms_check_sock_timeout(void) /* calculate dropped packets count */ if (c->recvpkt > 0) { - __sync_fetch_and_add(&ms_stats.pkt_drop, c->packets - c->recvpkt); + atomic_add_64(&ms_stats.pkt_drop, c->packets - c->recvpkt); } - __sync_fetch_and_add(&ms_stats.udp_timeout, 1); + atomic_add_64(&ms_stats.udp_timeout, 1); ms_reset_conn(c, true); } } @@ -168,14 +168,14 @@ static int ms_setup_thread(ms_thread_ctx_t *thread_ctx) ms_thread.thread_ctx= thread_ctx; ms_thread.nactive_conn= thread_ctx->nconns; ms_thread.initialized= false; - static int cnt= 0; + static volatile uint32_t cnt= 0; gettimeofday(&ms_thread.startup_time, NULL); ms_thread.base= event_init(); if (ms_thread.base == NULL) { - if (__sync_fetch_and_add(&cnt, 1) == 0) + if (atomic_add_32_nv(&cnt, 1) == 0) { fprintf(stderr, "Can't allocate event base.\n"); } @@ -187,7 +187,7 @@ static int ms_setup_thread(ms_thread_ctx_t *thread_ctx) (ms_conn_t *)malloc((size_t)thread_ctx->nconns * sizeof(ms_conn_t)); if (ms_thread.conn == NULL) { - if (__sync_fetch_and_add(&cnt, 1) == 0) + if (atomic_add_32_nv(&cnt, 1) == 0) { fprintf( stderr, @@ -204,7 +204,7 @@ static int ms_setup_thread(ms_thread_ctx_t *thread_ctx) if (ms_setup_conn(&ms_thread.conn[i]) != 0) { /* only output this error once */ - if (__sync_fetch_and_add(&cnt, 1) == 0) + if (atomic_add_32_nv(&cnt, 1) == 0) { fprintf(stderr, "Initializing connection failed.\n"); } -- 2.30.2