summaryrefslogtreecommitdiff
path: root/innobase/com
diff options
context:
space:
mode:
authorunknown <monty@donna.mysql.com>2001-02-17 14:19:19 +0200
committerunknown <monty@donna.mysql.com>2001-02-17 14:19:19 +0200
commit2662b59306ef0cd495fa6e2edf7129e58a11393a (patch)
treebfe39951a73e906579ab819bf5198ad8f3a64a36 /innobase/com
parent66de55a56bdcf2f7a9c0c4f8e19b3e761475e202 (diff)
downloadmariadb-git-2662b59306ef0cd495fa6e2edf7129e58a11393a.tar.gz
Added Innobase to source distribution
Docs/manual.texi: Added Innobase documentation configure.in: Incremented version include/my_base.h: Added option for Innobase myisam/mi_check.c: cleanup mysql-test/t/bdb.test: cleanup mysql-test/t/innobase.test: Extended with new tests from bdb.test mysql-test/t/merge.test: Added test of SHOW create mysys/my_init.c: Fix for UNIXWARE 7 scripts/mysql_install_db.sh: Always write how to start mysqld scripts/safe_mysqld.sh: Fixed type sql/ha_innobase.cc: Update to new version sql/ha_innobase.h: Update to new version sql/handler.h: Added 'update_table_comment()' and 'append_create_info()' sql/sql_delete.cc: Fixes for Innobase sql/sql_select.cc: Fixes for Innobase sql/sql_show.cc: Append create information (for MERGE tables) sql/sql_update.cc: Fixes for Innobase
Diffstat (limited to 'innobase/com')
-rw-r--r--innobase/com/Makefile.am24
-rw-r--r--innobase/com/com0com.c345
-rw-r--r--innobase/com/com0shm.c1159
-rw-r--r--innobase/com/makefilewin12
-rw-r--r--innobase/com/ts/makefile19
-rw-r--r--innobase/com/ts/tscli.c96
-rw-r--r--innobase/com/ts/tscom.c94
7 files changed, 1749 insertions, 0 deletions
diff --git a/innobase/com/Makefile.am b/innobase/com/Makefile.am
new file mode 100644
index 00000000000..27ae396bc6e
--- /dev/null
+++ b/innobase/com/Makefile.am
@@ -0,0 +1,24 @@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+# & Innobase Oy
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+include ../include/Makefile.i
+
+libs_LIBRARIES = libcom.a
+
+libcom_a_SOURCES = com0com.c com0shm.c
+
+EXTRA_PROGRAMS =
diff --git a/innobase/com/com0com.c b/innobase/com/com0com.c
new file mode 100644
index 00000000000..94585d9f269
--- /dev/null
+++ b/innobase/com/com0com.c
@@ -0,0 +1,345 @@
+/******************************************************
+The communication primitives
+
+(c) 1995 Innobase Oy
+
+Created 9/23/1995 Heikki Tuuri
+*******************************************************/
+
+#include "com0com.h"
+#ifdef UNIV_NONINL
+#include "com0com.ic"
+#endif
+
+#include "mem0mem.h"
+#include "com0shm.h"
+
+/*
+ IMPLEMENTATION OF COMMUNICATION PRIMITIVES
+ ==========================================
+
+The primitives provide a uniform function interface for
+use in communication. The primitives have been modeled
+after the Windows Sockets interface. Below this uniform
+API, the precise methods of communication, for example,
+shared memory or Berkeley sockets, can be implemented
+as subroutines.
+*/
+
+struct com_endpoint_struct{
+ ulint type; /* endpoint type */
+ void* par; /* type-specific data structures */
+ ibool bound; /* TRUE if the endpoint has been
+ bound to an address */
+};
+
+/*************************************************************************
+Accessor functions for an endpoint */
+UNIV_INLINE
+ulint
+com_endpoint_get_type(
+/*==================*/
+ com_endpoint_t* ep)
+{
+ ut_ad(ep);
+ return(ep->type);
+}
+
+UNIV_INLINE
+void
+com_endpoint_set_type(
+/*==================*/
+ com_endpoint_t* ep,
+ ulint type)
+{
+ ut_ad(ep);
+ ut_ad(type == COM_SHM);
+
+ ep->type = type;
+}
+
+UNIV_INLINE
+void*
+com_endpoint_get_par(
+/*=================*/
+ com_endpoint_t* ep)
+{
+ ut_ad(ep);
+ return(ep->par);
+}
+
+UNIV_INLINE
+void
+com_endpoint_set_par(
+/*=================*/
+ com_endpoint_t* ep,
+ void* par)
+{
+ ut_ad(ep);
+ ut_ad(par);
+
+ ep->par = par;
+}
+
+UNIV_INLINE
+ibool
+com_endpoint_get_bound(
+/*===================*/
+ com_endpoint_t* ep)
+{
+ ut_ad(ep);
+ return(ep->bound);
+}
+
+UNIV_INLINE
+void
+com_endpoint_set_bound(
+/*===================*/
+ com_endpoint_t* ep,
+ ibool bound)
+{
+ ut_ad(ep);
+
+ ep->bound = bound;
+}
+
+
+/*************************************************************************
+Creates a communications endpoint. */
+
+com_endpoint_t*
+com_endpoint_create(
+/*================*/
+ /* out, own: communications endpoint, NULL if
+ did not succeed */
+ ulint type) /* in: communication type of endpoint:
+ only COM_SHM supported */
+{
+ com_endpoint_t* ep;
+ void* par;
+
+ ep = mem_alloc(sizeof(com_endpoint_t));
+
+ com_endpoint_set_type(ep, type);
+ com_endpoint_set_bound(ep, FALSE);
+
+ if (type == COM_SHM) {
+ par = com_shm_endpoint_create();
+ com_endpoint_set_par(ep, par);
+ } else {
+ par = NULL;
+ ut_error;
+ }
+
+ if (par != NULL) {
+ return(ep);
+ } else {
+ mem_free(ep);
+ return(NULL);
+ }
+}
+
+/*************************************************************************
+Frees a communications endpoint. */
+
+ulint
+com_endpoint_free(
+/*==============*/
+ /* out: O if succeed, else error number */
+ com_endpoint_t* ep) /* in, own: communications endpoint */
+{
+ ulint type;
+ ulint ret;
+ void* par;
+
+ type = com_endpoint_get_type(ep);
+ par = com_endpoint_get_par(ep);
+
+ if (type == COM_SHM) {
+ ret = com_shm_endpoint_free((com_shm_endpoint_t*)par);
+ } else {
+ ret = 0;
+ ut_error;
+ }
+
+ if (ret) {
+ return(ret);
+ } else {
+ mem_free(ep);
+ return(0);
+ }
+}
+
+/*************************************************************************
+Sets an option, like the maximum datagram size for an endpoint.
+The options may vary depending on the endpoint type. */
+
+ulint
+com_endpoint_set_option(
+/*====================*/
+ /* out: 0 if succeed, else error number */
+ com_endpoint_t* ep, /* in: endpoint */
+ ulint optno, /* in: option number, only
+ COM_OPT_MAX_DGRAM_SIZE currently supported */
+ byte* optval, /* in: pointer to a buffer containing the
+ option value to set */
+ ulint optlen) /* in: option value buffer length */
+{
+ ulint type;
+ ulint ret;
+ void* par;
+
+ type = com_endpoint_get_type(ep);
+ par = com_endpoint_get_par(ep);
+
+ if (type == COM_SHM) {
+ ret = com_shm_endpoint_set_option((com_shm_endpoint_t*)par,
+ optno, optval, optlen);
+ } else {
+ ret = 0;
+ ut_error;
+ }
+
+ return(ret);
+}
+
+/*************************************************************************
+Binds a communications endpoint to the specified address. */
+
+ulint
+com_bind(
+/*=====*/
+ /* out: 0 if succeed, else error number */
+ com_endpoint_t* ep, /* in: communications endpoint */
+ char* name, /* in: address name */
+ ulint len) /* in: name length */
+{
+ ulint type;
+ ulint ret;
+ void* par;
+
+ ut_ad(len <= COM_MAX_ADDR_LEN);
+
+ if (com_endpoint_get_bound(ep)) {
+ return(COM_ERR_ALREADY_BOUND);
+ }
+
+ type = com_endpoint_get_type(ep);
+ par = com_endpoint_get_par(ep);
+
+ if (type == COM_SHM) {
+ ret = com_shm_bind((com_shm_endpoint_t*)par, name, len);
+ } else {
+ ret = 0;
+ ut_error;
+ }
+
+ if (ret == 0) {
+ com_endpoint_set_bound(ep, TRUE);
+ }
+
+ return(ret);
+}
+
+/*************************************************************************
+Waits for a datagram to arrive at an endpoint. */
+
+ulint
+com_recvfrom(
+/*=========*/
+ /* out: 0 if succeed, else error number */
+ com_endpoint_t* ep, /* in: communications endpoint */
+ byte* buf, /* out: datagram buffer; the buffer is
+ supplied by the caller */
+ ulint buf_len,/* in: datagram buffer length */
+ ulint* len, /* out: datagram length */
+ char* from, /* out: address name buffer; the buffer is
+ supplied by the caller */
+ ulint from_len,/* in: address name buffer length */
+ ulint* addr_len)/* out: address name length */
+{
+ ulint type;
+ ulint ret;
+ void* par;
+
+ if (!com_endpoint_get_bound(ep)) {
+
+ return(COM_ERR_NOT_BOUND);
+ }
+
+ type = com_endpoint_get_type(ep);
+ par = com_endpoint_get_par(ep);
+
+ if (type == COM_SHM) {
+ ret = com_shm_recvfrom((com_shm_endpoint_t*)par,
+ buf, buf_len, len, from, from_len,
+ addr_len);
+ } else {
+ ret = 0;
+
+ ut_error;
+ }
+
+ return(ret);
+}
+
+/*************************************************************************
+Sends a datagram to the specified destination. */
+
+ulint
+com_sendto(
+/*=======*/
+ /* out: 0 if succeed, else error number */
+ com_endpoint_t* ep, /* in: communications endpoint */
+ byte* buf, /* in: datagram buffer */
+ ulint len, /* in: datagram length */
+ char* to, /* in: address name buffer */
+ ulint tolen) /* in: address name length */
+{
+ ulint type;
+ ulint ret;
+ void* par;
+
+ if (!com_endpoint_get_bound(ep)) {
+ return(COM_ERR_NOT_BOUND);
+ }
+
+ type = com_endpoint_get_type(ep);
+ par = com_endpoint_get_par(ep);
+
+ if (type == COM_SHM) {
+ ret = com_shm_sendto((com_shm_endpoint_t*)par, buf, len,
+ to, tolen);
+ } else {
+ ret = 0;
+ ut_error;
+ }
+
+ return(ret);
+}
+
+/*************************************************************************
+Gets the maximum datagram size for an endpoint. */
+
+ulint
+com_endpoint_get_max_size(
+/*======================*/
+ /* out: maximum size */
+ com_endpoint_t* ep) /* in: endpoint */
+{
+ ulint type;
+ ulint ret;
+ void* par;
+
+ type = com_endpoint_get_type(ep);
+ par = com_endpoint_get_par(ep);
+
+ if (type == COM_SHM) {
+ ret = com_shm_endpoint_get_size((com_shm_endpoint_t*)par);
+ } else {
+ ret = 0;
+ ut_error;
+ }
+
+ return(ret);
+}
diff --git a/innobase/com/com0shm.c b/innobase/com/com0shm.c
new file mode 100644
index 00000000000..630241ff2f1
--- /dev/null
+++ b/innobase/com/com0shm.c
@@ -0,0 +1,1159 @@
+/******************************************************
+The communication through shared memory
+
+(c) 1995 Innobase Oy
+
+Created 9/25/1995 Heikki Tuuri
+*******************************************************/
+
+#include "com0shm.h"
+#ifdef UNIV_NONINL
+#include "com0shm.ic"
+#endif
+
+#include "mem0mem.h"
+#include "ut0mem.h"
+#include "com0com.h"
+#include "os0shm.h"
+#include "sync0sync.h"
+#include "sync0ipm.h"
+#include "hash0hash.h"
+
+/*
+ IMPLEMENTATION OF COMMUNICATION PRIMITIVES
+ ==========================================
+
+When bind is called for an endpoint, a shared memory area of
+a size specified by com_shm_set_option is created with the
+name of the address given concatenated to "_IBSHM".
+Also a mutex is created for controlling the access to the
+shared memory area. The name of the mutex is address + "_IBSHM_MTX".
+An event with name address + "_IBSHM_EV_NE" is created. This event
+is in signaled state when the shared memory area is not empty, i.e.,
+there is a datagram to read. An event address + "_IBSHM_EV_EM"
+is signaled, when the area is empty, i.e., a datagram can be
+written to it.
+
+The shared memory area consists of an info struct
+at the beginning, containing fields telling:
+if the area is valid, i.e., is anybody going to
+read it, whether it currently contains a datagram, the
+length of the address from which the datagram was received,
+the length of the datagram, and the maximum allowed length of
+a datagram.
+After the info struct, there is a string of bytes
+containing the sender address and the data
+of the datagram.
+*/
+
+/* The following is set TRUE when the first endpoint is created. */
+
+ibool com_shm_initialized = FALSE;
+
+/* When a datagram is sent, the shared memory area
+corresponding to the destination address is mapped
+to the address space of this (sender) process.
+We preserve it and keep the relevant info in the
+following list. We can save a lot of CPU time
+if the destination can be found on the list. The list is
+protected by the mutex below. */
+
+mutex_t com_shm_destination_mutex;
+hash_table_t* com_shm_destination_cache;
+UT_LIST_BASE_NODE_T(com_shm_endpoint_t)
+ com_shm_destination_list;
+
+/* The number of successfully bound endpoints in this process. When this
+number drops to 0, the destination cache is freed. This variable is protected
+by com_shm_destination_mutex above. */
+
+ulint com_shm_bind_count = 0;
+
+/* The performance of communication in NT depends on how
+many times a system call is made (excluding os_thread_yield,
+as that is the fastest way to switch thread).
+The following variable counts such events. */
+
+ulint com_shm_system_call_count = 0;
+
+/* The info struct at the beginning of a shared memory area */
+
+typedef struct com_shm_info_struct com_shm_info_t;
+
+/* An area of shared memory consists of an info struct followed
+by a string of bytes. */
+
+typedef com_shm_info_t com_shm_t;
+
+struct com_shm_endpoint_struct{
+ ibool owns_shm; /* This is true if the shared memory
+ area is owned by this endpoint structure
+ (it may also be opened for this endpoint,
+ not created, in which case does not own it) */
+ char* addr; /* pointer to address the endpoint is bound
+ to, NULL if not bound */
+ ulint addr_len; /* address length */
+ ulint size; /* maximum allowed datagram size, initialized
+ to 0 at creation */
+ os_shm_t shm; /* operating system handle of the shared
+ memory area */
+ com_shm_t* map; /* pointer to the start address of the shared
+ memory area */
+ os_event_t not_empty; /* this is in the signaled state if
+ the area currently may contain a datagram;
+ NOTE: automatic event */
+ os_event_t empty; /* this is in the signaled state if the area
+ currently may be empty; NOTE: automatic event */
+ ip_mutex_hdl_t* ip_mutex; /* handle to the interprocess mutex
+ protecting the shared memory */
+ UT_LIST_NODE_T(com_shm_endpoint_t) list; /* If the endpoint struct
+ is inserted into a list, this contains
+ pointers to next and prev */
+ com_shm_endpoint_t* addr_hash;
+ /* hash table link */
+};
+
+struct com_shm_info_struct{
+ ulint valid; /* This is COM_SHM_VALID if the creator
+ of the shared memory area has it still
+ mapped to its address space. Otherwise,
+ we may conclude that the datagram cannot
+ be delivered. */
+ ibool not_empty; /* TRUE if the area currently contains
+ a datagram */
+ ulint empty_waiters; /* Count of (writer) threads which are
+ waiting for the empty-event */
+ ulint max_len;/* maximum allowed length for a datagram */
+ ulint addr_len;/* address length for the sender address */
+ ulint data_len;/* datagram length */
+ ip_mutex_t ip_mutex;/* fast interprocess mutex protecting
+ the shared memory area */
+};
+
+#define COM_SHM_VALID 76640
+
+/*************************************************************************
+Accessor functions for a shared memory endpoint */
+
+UNIV_INLINE
+ibool
+com_shm_endpoint_get_owns_shm(
+/*==========================*/
+ com_shm_endpoint_t* ep)
+{
+ ut_ad(ep);
+ return(ep->owns_shm);
+}
+
+UNIV_INLINE
+void
+com_shm_endpoint_set_owns_shm(
+/*==========================*/
+ com_shm_endpoint_t* ep,
+ ibool flag)
+{
+ ut_ad(ep);
+
+ ep->owns_shm = flag;
+}
+
+UNIV_INLINE
+char*
+com_shm_endpoint_get_addr(
+/*======================*/
+ com_shm_endpoint_t* ep)
+{
+ ut_ad(ep);
+ return(ep->addr);
+}
+
+UNIV_INLINE
+void
+com_shm_endpoint_set_addr(
+/*======================*/
+ com_shm_endpoint_t* ep,
+ char* addr)
+{
+ ut_ad(ep);
+
+ ep->addr = addr;
+}
+
+UNIV_INLINE
+ulint
+com_shm_endpoint_get_addr_len(
+/*==========================*/
+ com_shm_endpoint_t* ep)
+{
+ return(ep->addr_len);
+}
+
+UNIV_INLINE
+void
+com_shm_endpoint_set_addr_len(
+/*==========================*/
+ com_shm_endpoint_t* ep,
+ ulint len)
+{
+ ut_ad(ep);
+ ut_ad(len > 0);
+
+ ep->addr_len = len;
+}
+
+ulint
+com_shm_endpoint_get_size(
+/*======================*/
+ com_shm_endpoint_t* ep)
+{
+ return(ep->size);
+}
+
+UNIV_INLINE
+void
+com_shm_endpoint_set_size(
+/*======================*/
+ com_shm_endpoint_t* ep,
+ ulint size)
+{
+ ut_ad(ep);
+
+ ep->size = size;
+}
+
+UNIV_INLINE
+os_shm_t
+com_shm_endpoint_get_shm(
+/*=====================*/
+ com_shm_endpoint_t* ep)
+{
+ return(ep->shm);
+}
+
+UNIV_INLINE
+void
+com_shm_endpoint_set_shm(
+/*=====================*/
+ com_shm_endpoint_t* ep,
+ os_shm_t shm)
+{
+ ut_ad(ep);
+ ut_ad(shm);
+
+ ep->shm = shm;
+}
+
+UNIV_INLINE
+com_shm_t*
+com_shm_endpoint_get_map(
+/*=====================*/
+ com_shm_endpoint_t* ep)
+{
+ return(ep->map);
+}
+
+UNIV_INLINE
+void
+com_shm_endpoint_set_map(
+/*=====================*/
+ com_shm_endpoint_t* ep,
+ com_shm_t* map)
+{
+ ut_ad(ep);
+ ut_ad(map);
+
+ ep->map = map;
+}
+
+UNIV_INLINE
+os_event_t
+com_shm_endpoint_get_empty(
+/*=======================*/
+ com_shm_endpoint_t* ep)
+{
+ return(ep->empty);
+}
+
+UNIV_INLINE
+void
+com_shm_endpoint_set_empty(
+/*=======================*/
+ com_shm_endpoint_t* ep,
+ os_event_t event)
+{
+ ut_ad(ep);
+ ut_ad(event);
+
+ ep->empty = event;
+}
+
+UNIV_INLINE
+os_event_t
+com_shm_endpoint_get_not_empty(
+/*===========================*/
+ com_shm_endpoint_t* ep)
+{
+ return(ep->not_empty);
+}
+
+UNIV_INLINE
+void
+com_shm_endpoint_set_not_empty(
+/*===========================*/
+ com_shm_endpoint_t* ep,
+ os_event_t event)
+{
+ ut_ad(ep);
+ ut_ad(event);
+
+ ep->not_empty = event;
+}
+
+/************************************************************************
+Accessor functions for the shared memory area info struct. */
+UNIV_INLINE
+ulint
+com_shm_get_valid(
+/*==============*/
+ com_shm_info_t* info)
+{
+ return(info->valid);
+}
+
+UNIV_INLINE
+void
+com_shm_set_valid(
+/*==============*/
+ com_shm_info_t* info,
+ ulint flag)
+{
+ ut_ad(info);
+
+ info->valid = flag;
+}
+
+UNIV_INLINE
+ibool
+com_shm_get_not_empty(
+/*==================*/
+ com_shm_info_t* info)
+{
+ return(info->not_empty);
+}
+
+UNIV_INLINE
+void
+com_shm_set_not_empty(
+/*==================*/
+ com_shm_info_t* info,
+ ibool flag)
+{
+ ut_ad(info);
+
+ info->not_empty = flag;
+}
+
+UNIV_INLINE
+ulint
+com_shm_get_empty_waiters(
+/*======================*/
+ com_shm_info_t* info)
+{
+ ut_ad(info->empty_waiters < 1000);
+
+ return(info->empty_waiters);
+}
+
+UNIV_INLINE
+void
+com_shm_set_empty_waiters(
+/*======================*/
+ com_shm_info_t* info,
+ ulint count)
+{
+ ut_ad(info);
+ ut_ad(count < 1000);
+
+ info->empty_waiters = count;
+}
+
+UNIV_INLINE
+ulint
+com_shm_get_max_len(
+/*================*/
+ com_shm_info_t* info)
+{
+ return(info->max_len);
+}
+
+UNIV_INLINE
+void
+com_shm_set_max_len(
+/*================*/
+ com_shm_info_t* info,
+ ulint len)
+{
+ ut_ad(info);
+ ut_ad(len > 0);
+
+ info->max_len = len;
+}
+
+UNIV_INLINE
+ulint
+com_shm_get_addr_len(
+/*=================*/
+ com_shm_info_t* info)
+{
+ return(info->addr_len);
+}
+
+UNIV_INLINE
+void
+com_shm_set_addr_len(
+/*=================*/
+ com_shm_info_t* info,
+ ulint len)
+{
+ ut_ad(info);
+ ut_ad(len > 0);
+
+ info->addr_len = len;
+}
+
+UNIV_INLINE
+ulint
+com_shm_get_data_len(
+/*=================*/
+ com_shm_info_t* info)
+{
+ return(info->data_len);
+}
+
+UNIV_INLINE
+void
+com_shm_set_data_len(
+/*=================*/
+ com_shm_info_t* info,
+ ulint len)
+{
+ ut_ad(info);
+ ut_ad(len > 0);
+
+ info->data_len = len;
+}
+
+UNIV_INLINE
+ip_mutex_t*
+com_shm_get_ip_mutex(
+/*=================*/
+ com_shm_info_t* info)
+{
+ return(&(info->ip_mutex));
+}
+
+/*************************************************************************
+Accessor functions for the address and datagram fields inside a
+shared memory area. */
+
+UNIV_INLINE
+char*
+com_shm_get_addr(
+/*=============*/
+ com_shm_t* area)
+{
+ return((char*)area + sizeof(com_shm_info_t));
+}
+
+UNIV_INLINE
+byte*
+com_shm_get_data(
+/*=============*/
+ com_shm_t* area)
+{
+ return((byte*)com_shm_get_addr(area) + com_shm_get_addr_len(area));
+}
+
+/*************************************************************************
+Initializes the shared memory communication system for this
+process. */
+UNIV_INLINE
+void
+com_shm_init(void)
+/*==============*/
+{
+ mutex_create(&com_shm_destination_mutex);
+
+ mutex_set_level(&com_shm_destination_mutex, SYNC_ANY_LATCH);
+
+ com_shm_destination_cache = hash_create(1000);
+
+ UT_LIST_INIT(com_shm_destination_list);
+
+ com_shm_initialized = TRUE;
+}
+
+/*************************************************************************
+Reserves the ip mutex of the shared memory area of an endpoint. */
+UNIV_INLINE
+void
+com_shm_enter(
+/*==========*/
+ com_shm_endpoint_t* ep)
+{
+ ulint ret;
+
+ ret = ip_mutex_enter(ep->ip_mutex, 10000000);
+
+ if (ret != 0) {
+ mutex_list_print_info();
+
+ ut_error;
+ }
+}
+
+/*************************************************************************
+Releases the ip mutex of the shared memory area of an endpoint. */
+UNIV_INLINE
+void
+com_shm_exit(
+/*=========*/
+ com_shm_endpoint_t* ep)
+{
+ ip_mutex_exit(ep->ip_mutex);
+}
+
+/*************************************************************************
+Looks for the given address in the cached destination addresses. */
+UNIV_INLINE
+com_shm_endpoint_t*
+com_shm_destination_cache_search(
+/*=============================*/
+ /* out: cached endpoint structure if found, else NULL */
+ char* addr, /* in: destination address */
+ ulint len) /* in: address length */
+{
+ com_shm_endpoint_t* ep;
+ ulint fold;
+
+ fold = ut_fold_binary((byte*)addr, len);
+/*
+ printf("Searching dest. cache %s %lu fold %lu\n", addr, len, fold);
+*/
+ mutex_enter(&com_shm_destination_mutex);
+
+ HASH_SEARCH(addr_hash, com_shm_destination_cache, fold, ep,
+ ((ep->addr_len == len)
+ && (0 == ut_memcmp(addr, ep->addr, len))));
+
+ mutex_exit(&com_shm_destination_mutex);
+
+ return(ep);
+}
+
+/*************************************************************************
+Inserts the given endpoint structure in the cached destination addresses. */
+static
+void
+com_shm_destination_cache_insert(
+/*=============================*/
+ com_shm_endpoint_t* ep) /* in: endpoint struct to insert */
+{
+ ulint fold;
+
+ fold = ut_fold_binary((byte*)(ep->addr), ep->addr_len);
+
+ mutex_enter(&com_shm_destination_mutex);
+
+ /* Add to hash table */
+ HASH_INSERT(com_shm_endpoint_t,
+ addr_hash, com_shm_destination_cache, fold, ep);
+
+ UT_LIST_ADD_LAST(list, com_shm_destination_list, ep);
+
+/* printf("Inserting to dest. cache %s %lu fold %lu\n", ep->addr,
+ ep->addr_len, fold);
+*/
+ mutex_exit(&com_shm_destination_mutex);
+}
+
+/*************************************************************************
+Frees the endpoint structs in the destination cache if the bind count is zero.
+If it is not, some send operation may just be using a cached endpoint and it
+cannot be freed. */
+static
+void
+com_shm_destination_cache_no_binds(void)
+/*====================================*/
+{
+ com_shm_endpoint_t* ep;
+ ulint fold;
+
+ mutex_enter(&com_shm_destination_mutex);
+
+ if (com_shm_bind_count != 0) {
+ mutex_exit(&com_shm_destination_mutex);
+
+ return;
+ }
+
+ while (UT_LIST_GET_LEN(com_shm_destination_list) != 0) {
+
+ ep = UT_LIST_GET_FIRST(com_shm_destination_list);
+
+ UT_LIST_REMOVE(list, com_shm_destination_list, ep);
+
+ fold = ut_fold_binary((byte*)ep->addr, ep->addr_len);
+/*
+ printf("Deleting from dest. cache %s %lu fold %lu\n",
+ ep->addr,
+ ep->addr_len, fold);
+*/
+ HASH_DELETE(com_shm_endpoint_t, addr_hash,
+ com_shm_destination_cache, fold, ep);
+
+ com_shm_endpoint_free(ep);
+ }
+
+ mutex_exit(&com_shm_destination_mutex);
+}
+
+/***********************************************************************
+Unbinds an endpoint at the time of freeing. */
+static
+void
+com_shm_unbind(
+/*===========*/
+ com_shm_endpoint_t* ep) /* in: endpoint */
+{
+ com_shm_t* map;
+
+ map = com_shm_endpoint_get_map(ep);
+
+ /* Mark the shared memory area invalid */
+
+ com_shm_set_valid(map, 0);
+
+ /* Decrement the count of bindings */
+
+ mutex_enter(&com_shm_destination_mutex);
+
+ com_shm_bind_count--;
+
+ mutex_exit(&com_shm_destination_mutex);
+
+ /* If there are no binds left, free the cached endpoints */
+
+ com_shm_destination_cache_no_binds();
+}
+
+/*************************************************************************
+Creates a communications endpoint. */
+
+com_shm_endpoint_t*
+com_shm_endpoint_create(void)
+/*=========================*/
+ /* out, own: communications endpoint, NULL if
+ did not succeed */
+{
+ com_shm_endpoint_t* ep;
+
+ if (!com_shm_initialized) {
+
+ com_shm_init();
+ }
+
+ ep = mem_alloc(sizeof(com_shm_endpoint_t));
+
+ com_shm_endpoint_set_owns_shm(ep, FALSE);
+ com_shm_endpoint_set_addr(ep, NULL);
+ com_shm_endpoint_set_size(ep, 0);
+
+ return(ep);
+}
+
+/*************************************************************************
+Frees a communications endpoint. */
+
+ulint
+com_shm_endpoint_free(
+/*==================*/
+ /* out: O if succeed, else error number */
+ com_shm_endpoint_t* ep) /* in, own: communications endpoint */
+{
+ com_shm_t* map;
+
+ ut_ad(ep);
+
+ if (com_shm_endpoint_get_addr(ep) != NULL) {
+
+ map = com_shm_endpoint_get_map(ep);
+
+ if (com_shm_endpoint_get_owns_shm(ep)) {
+
+ com_shm_unbind(ep);
+ }
+
+ /* We do not destroy the data structures in the shared memory
+ area, because we cannot be sure that there is currently no
+ process accessing it. Therefore we just close the ip_mutex
+ residing in the area. */
+
+ ip_mutex_close(ep->ip_mutex);
+
+ os_event_free(com_shm_endpoint_get_not_empty(ep));
+ os_event_free(com_shm_endpoint_get_empty(ep));
+
+ os_shm_unmap(map);
+ os_shm_free(com_shm_endpoint_get_shm(ep));
+
+ mem_free(com_shm_endpoint_get_addr(ep));
+ }
+
+ mem_free(ep);
+
+ return(0);
+}
+
+/*************************************************************************
+Sets an option, like the maximum datagram size for an endpoint.
+The options may vary depending on the endpoint type. */
+
+ulint
+com_shm_endpoint_set_option(
+/*========================*/
+ /* out: 0 if succeed, else error number */
+ com_shm_endpoint_t* ep, /* in: endpoint */
+ ulint optno, /* in: option number, only
+ COM_OPT_MAX_DGRAM_SIZE currently supported */
+ byte* optval, /* in: pointer to a buffer containing the
+ option value to set */
+ ulint optlen) /* in: option value buffer length */
+{
+ ulint size;
+
+ UT_NOT_USED(optlen);
+
+ ut_ad(ep);
+ ut_a(optno == COM_OPT_MAX_DGRAM_SIZE);
+ ut_ad(NULL == com_shm_endpoint_get_addr(ep));
+
+ size = *((ulint*)optval);
+
+ ut_ad(size > 0);
+
+ com_shm_endpoint_set_size(ep, size);
+
+ return(0);
+}
+
+/*************************************************************************
+This function is used either to create a new shared memory area or open an
+existing one, but this does not do the operations necessary with the ip mutex.
+They are performed in com_shm_bind or com_shm_open which call this function. */
+static
+ulint
+com_shm_create_or_open(
+/*===================*/
+ /* out: 0 if succeed, else error number */
+ com_shm_endpoint_t* ep, /* in: communications endpoint */
+ char* name, /* in: address name */
+ ulint len) /* in: address name length */
+{
+ os_shm_t shm;
+ com_shm_t* map;
+ os_event_t event_ne;
+ os_event_t event_em;
+ char* buf;
+
+ ut_ad(ep);
+ ut_ad(name);
+ ut_ad(len > 0);
+
+ buf = mem_alloc(COM_MAX_ADDR_LEN + 20);
+
+ ut_memcpy(buf, name, len);
+
+ ut_strcpy(buf + len, "_IBSHM");
+
+ shm = os_shm_create(sizeof(com_shm_info_t) + COM_MAX_ADDR_LEN +
+ com_shm_endpoint_get_size(ep), buf);
+ if (shm == NULL) {
+
+ return(COM_ERR_NOT_SPECIFIED);
+ }
+
+ map = os_shm_map(shm);
+
+ if (map == NULL) {
+ os_shm_free(shm);
+
+ return(COM_ERR_NOT_SPECIFIED);
+ }
+
+ ut_strcpy(buf + len, "_IBSHM_EV_NE"),
+
+ event_ne = os_event_create_auto(buf);
+
+ ut_ad(event_ne);
+
+ ut_strcpy(buf + len, "_IBSHM_EV_EM"),
+
+ event_em = os_event_create_auto(buf);
+
+ ut_ad(event_em);
+
+ com_shm_endpoint_set_shm(ep, shm);
+ com_shm_endpoint_set_map(ep, map);
+
+ com_shm_endpoint_set_not_empty(ep, event_ne);
+ com_shm_endpoint_set_empty(ep, event_em);
+
+ com_shm_endpoint_set_addr(ep, buf);
+ com_shm_endpoint_set_addr_len(ep, len);
+
+ return(0);
+}
+
+/*************************************************************************
+Opens a shared memory area for communication. */
+static
+ulint
+com_shm_open(
+/*=========*/
+ /* out: 0 if succeed, else error number */
+ com_shm_endpoint_t* ep, /* in: communications endpoint */
+ char* name, /* in: address name */
+ ulint len) /* in: address name length */
+{
+ ip_mutex_hdl_t* ip_hdl;
+ com_shm_t* map;
+ ulint ret;
+ char buf[COM_MAX_ADDR_LEN + 20];
+
+ ret = com_shm_create_or_open(ep, name, len);
+
+ if (ret != 0) {
+
+ return(ret);
+ }
+
+ map = com_shm_endpoint_get_map(ep);
+
+ /* Open the interprocess mutex to protect the shared memory area */
+
+ ut_memcpy(buf, name, len);
+ ut_strcpy(buf + len, "_IBSHM_MTX");
+
+ ret = ip_mutex_open(com_shm_get_ip_mutex(map), buf, &ip_hdl);
+
+ if (ret != 0) {
+
+ return(COM_ERR_NOT_SPECIFIED);
+ }
+
+ ep->ip_mutex = ip_hdl;
+
+ return(0);
+}
+
+/*************************************************************************
+Creates a shared memory area for communication. */
+
+ulint
+com_shm_bind(
+/*=========*/
+ /* out: 0 if succeed, else error number */
+ com_shm_endpoint_t* ep, /* in: communications endpoint */
+ char* name, /* in: address name */
+ ulint len) /* in: address name length */
+{
+ com_shm_t* map;
+ ulint ret;
+ char buf[COM_MAX_ADDR_LEN + 20];
+ ip_mutex_hdl_t* ip_hdl;
+
+ if (com_shm_endpoint_get_size(ep) == 0) {
+
+ return(COM_ERR_MAX_DATAGRAM_SIZE_NOT_SET);
+ }
+
+ ret = com_shm_create_or_open(ep, name, len);
+
+ if (ret != 0) {
+
+ return(ret);
+ }
+
+ map = com_shm_endpoint_get_map(ep);
+
+ /* Create the interprocess mutex to protect the shared memory area */
+
+ ut_memcpy(buf, name, len);
+ ut_strcpy(buf + len, "_IBSHM_MTX");
+
+ ret = ip_mutex_create(com_shm_get_ip_mutex(map), buf, &ip_hdl);
+
+ if (ret != 0) {
+
+ return(COM_ERR_NOT_SPECIFIED);
+ }
+
+ /* This endpoint structure owns the shared memory area */
+
+ com_shm_endpoint_set_owns_shm(ep, TRUE);
+ ep->ip_mutex = ip_hdl;
+
+ mutex_enter(&com_shm_destination_mutex);
+
+ /* Increment the count of successful bindings */
+
+ com_shm_bind_count++;
+
+ mutex_exit(&com_shm_destination_mutex);
+
+ com_shm_set_not_empty(map, FALSE);
+ com_shm_set_empty_waiters(map, 0);
+ com_shm_set_max_len(map, com_shm_endpoint_get_size(ep));
+
+ com_shm_set_valid(map, COM_SHM_VALID);
+
+ os_event_set(com_shm_endpoint_get_empty(ep));
+
+ return(0);
+}
+
+/*************************************************************************
+Waits for a datagram to arrive at an endpoint. */
+
+ulint
+com_shm_recvfrom(
+/*=============*/
+ /* out: 0 if succeed, else error number */
+ com_shm_endpoint_t* ep, /* in: communications endpoint */
+ byte* buf, /* out: datagram buffer; the buffer is
+ supplied by the caller */
+ ulint buf_len,/* in: datagram buffer length */
+ ulint* len, /* out: datagram length */
+ char* from, /* out: address name buffer; the buffer is
+ supplied by the caller */
+ ulint from_len,/* in: address name buffer length */
+ ulint* addr_len)/* out: address name length */
+{
+ com_shm_t* map;
+ ulint loop_count;
+
+ map = com_shm_endpoint_get_map(ep);
+
+ loop_count = 0;
+loop:
+ com_shm_system_call_count++;
+
+ /* NOTE: automatic event */
+
+ os_event_wait(com_shm_endpoint_get_not_empty(ep));
+
+ loop_count++;
+
+ if (loop_count > 1) {
+ printf("!!!!!!!!COM_SHM loop count %lu\n", loop_count);
+ }
+
+ ut_ad(loop_count < 2);
+
+#ifdef notdefined
+ if (!com_shm_get_not_empty(map)) {
+
+ /* There was no datagram, give up the time slice
+ for some writer thread to insert a datagram */
+
+ com_shm_exit(ep);
+
+ os_thread_yield();
+
+ com_shm_enter(ep);
+ }
+#endif
+ com_shm_enter(ep);
+
+ if (!com_shm_get_not_empty(map)) {
+ /* There was no datagram, wait for the event */
+
+ com_shm_exit(ep);
+
+ goto loop;
+ }
+
+ if (com_shm_get_data_len(map) > buf_len) {
+
+ com_shm_exit(ep);
+
+ return(COM_ERR_DATA_BUFFER_TOO_SMALL);
+ }
+
+ if (com_shm_get_addr_len(map) > from_len) {
+
+ com_shm_exit(ep);
+
+ return(COM_ERR_ADDR_BUFFER_TOO_SMALL);
+ }
+
+ *len = com_shm_get_data_len(map);
+ *addr_len = com_shm_get_addr_len(map);
+
+ ut_memcpy(buf, com_shm_get_data(map), *len);
+ ut_memcpy(from, com_shm_get_addr(map), *addr_len);
+
+ com_shm_set_not_empty(map, FALSE);
+
+ /* If there may be writers queuing to insert the datagram, signal the
+ empty-event */
+
+ if (com_shm_get_empty_waiters(map) != 0) {
+
+ com_shm_system_call_count++;
+
+ os_event_set(com_shm_endpoint_get_empty(ep));
+ }
+
+ com_shm_exit(ep);
+
+ return(0);
+}
+
+/*************************************************************************
+Sends a datagram to the specified destination. */
+
+ulint
+com_shm_sendto(
+/*===========*/
+ /* out: 0 if succeed, else error number */
+ com_shm_endpoint_t* ep, /* in: communications endpoint */
+ byte* buf, /* in: datagram buffer */
+ ulint len, /* in: datagram length */
+ char* to, /* in: address name buffer */
+ ulint tolen) /* in: address name length */
+{
+ com_shm_endpoint_t* ep2;
+ com_shm_t* map;
+ ulint sender_len;
+ ulint ret;
+ ulint loop_count;
+
+ /* Try first to find from the cached destination addresses */
+
+ ep2 = com_shm_destination_cache_search(to, tolen);
+
+ if (ep2 == NULL) {
+ /* Did not find it in the cache */
+ ep2 = com_shm_endpoint_create();
+
+ ret = com_shm_open(ep2, to, tolen);
+
+ if (ret != 0) {
+ com_shm_endpoint_free(ep2);
+
+ return(ret);
+ }
+
+ /* Insert into the cached destination addresses */
+
+ com_shm_destination_cache_insert(ep2);
+ }
+
+ map = com_shm_endpoint_get_map(ep2);
+
+ if (com_shm_get_valid(map) != COM_SHM_VALID) {
+
+ com_shm_exit(ep2);
+
+ return(COM_ERR_DGRAM_NOT_DELIVERED);
+ }
+
+ if (com_shm_get_max_len(map) < len) {
+
+ com_shm_exit(ep2);
+
+ return(COM_ERR_DATA_TOO_LONG);
+ }
+
+ /* Optimistically, we first go to see if the datagram area is empty,
+ without waiting for the empty-event */
+
+ loop_count = 0;
+loop:
+ loop_count++;
+
+ if (loop_count > 5) {
+ printf("!!!!!!COM_SHM Notempty loop count %lu\n", loop_count);
+ }
+
+ ut_ad(loop_count < 100);
+
+ com_shm_enter(ep2);
+
+ if (com_shm_get_not_empty(map)) {
+
+ /* Not empty, we cannot insert a datagram */
+
+ com_shm_set_empty_waiters(map,
+ 1 + com_shm_get_empty_waiters(map));
+ com_shm_exit(ep2);
+
+ com_shm_system_call_count++;
+
+ /* Wait for the area to become empty */
+ /* NOTE: automatic event */
+
+ ret = os_event_wait_time(com_shm_endpoint_get_empty(ep2),
+ 10000000);
+ ut_a(ret == 0);
+
+ com_shm_enter(ep2);
+
+ com_shm_set_empty_waiters(map,
+ com_shm_get_empty_waiters(map) - 1);
+ com_shm_exit(ep2);
+
+ goto loop;
+ }
+
+ sender_len = com_shm_endpoint_get_addr_len(ep);
+
+ com_shm_set_data_len(map, len);
+ com_shm_set_addr_len(map, sender_len);
+
+ ut_memcpy(com_shm_get_data(map), buf, len);
+ ut_memcpy(com_shm_get_addr(map), com_shm_endpoint_get_addr(ep),
+ sender_len);
+ com_shm_set_not_empty(map, TRUE);
+#ifdef notdefined
+ com_shm_exit(ep2);
+
+ /* Now we give up our time slice voluntarily to give some reader
+ thread chance to fetch the datagram */
+
+ os_thread_yield();
+
+ com_shm_enter(ep2);
+
+ if (com_shm_get_not_empty(map)) {
+#endif
+ com_shm_system_call_count++;
+
+ com_shm_exit(ep2);
+
+ /* Signal the event */
+
+ os_event_set(com_shm_endpoint_get_not_empty(ep2));
+
+ return(0);
+
+#ifdef notdefined
+ }
+
+ com_shm_exit(ep2);
+
+ return(0);
+#endif
+}
diff --git a/innobase/com/makefilewin b/innobase/com/makefilewin
new file mode 100644
index 00000000000..0d2d6d45952
--- /dev/null
+++ b/innobase/com/makefilewin
@@ -0,0 +1,12 @@
+include ..\include\makefile.i
+
+com.lib: com0com.obj com0shm.obj
+ lib -out:..\libs\com.lib com0com.obj com0shm.obj
+
+com0com.obj: com0com.c
+ $(CCOM) $(CFL) -c com0com.c
+
+com0shm.obj: com0shm.c
+ $(CCOM) $(CFL) -c com0shm.c
+
+
diff --git a/innobase/com/ts/makefile b/innobase/com/ts/makefile
new file mode 100644
index 00000000000..01c14737c78
--- /dev/null
+++ b/innobase/com/ts/makefile
@@ -0,0 +1,19 @@
+
+
+
+include ..\..\makefile.i
+
+doall: tscom tscli
+
+tscom: ..\com.lib tscom.c makefile
+ $(CCOM) $(CFL) -I.. -I..\.. ..\com.lib ..\..\ut.lib ..\..\mem.lib ..\..\sync.lib ..\..\os.lib tscom.c $(LFL)
+
+tscli: ..\com.lib tscli.c makefile
+ $(CCOM) $(CFL) -I.. -I..\.. ..\com.lib ..\..\ut.lib ..\..\mem.lib ..\..\sync.lib ..\..\os.lib tscli.c $(LFL)
+
+
+
+
+
+
+
diff --git a/innobase/com/ts/tscli.c b/innobase/com/ts/tscli.c
new file mode 100644
index 00000000000..27a787a0e5c
--- /dev/null
+++ b/innobase/com/ts/tscli.c
@@ -0,0 +1,96 @@
+/************************************************************************
+The test module for communication
+
+(c) 1995 Innobase Oy
+
+Created 9/26/1995 Heikki Tuuri
+*************************************************************************/
+
+#include "../com0com.h"
+#include "../com0shm.h"
+#include "ut0ut.h"
+#include "mem0mem.h"
+#include "os0thread.h"
+#include "sync0ipm.h"
+#include "sync0sync.h"
+
+byte buf[10000];
+char addr[150];
+
+void
+test1(void)
+/*=======*/
+{
+ com_endpoint_t* ep;
+ ulint ret;
+ ulint size;
+ ulint len;
+ ulint addr_len;
+ ulint i;
+
+ ep = com_endpoint_create(COM_SHM);
+
+ ut_a(ep);
+
+ size = 8192;
+
+ ret = com_endpoint_set_option(ep, COM_OPT_MAX_DGRAM_SIZE,
+ (byte*)&size, 0);
+
+ ut_a(ret == 0);
+
+ ret = com_bind(ep, "CLI", 3);
+
+ ut_a(ret == 0);
+
+ printf("Client endpoint created!\n");
+
+ for (i = 0; i < 10000; i++) {
+
+ ret = com_sendto(ep, (byte*)"Hello from client!\n", 18, "SRV", 3);
+
+ ut_a(ret == 0);
+
+ ret = com_recvfrom(ep, buf, 10000, &len, addr, 150, &addr_len);
+
+ ut_a(ret == 0);
+
+ buf[len] = '\0';
+ addr[addr_len] = '\0';
+/*
+ printf(
+ "Message of len %lu\n%s \nreceived from address %s of len %lu\n",
+ len, buf, addr, addr_len);
+*/
+ }
+
+ ret = com_endpoint_free(ep);
+
+ ut_ad(ret == 0);
+
+
+ printf("Count of extra system calls in com_shm %lu\n",
+ com_shm_system_call_count);
+ printf("Count of extra system calls in ip_mutex %lu\n",
+ ip_mutex_system_call_count);
+}
+
+void
+main(void)
+/*======*/
+{
+ ulint tm, oldtm;
+
+ sync_init();
+ mem_init();
+
+ oldtm = ut_clock();
+
+ test1();
+
+ ut_ad(mem_all_freed());
+
+ tm = ut_clock();
+ printf("Wall clock time for test %ld milliseconds\n", tm - oldtm);
+ printf("TESTS COMPLETED SUCCESSFULLY!\n");
+}
diff --git a/innobase/com/ts/tscom.c b/innobase/com/ts/tscom.c
new file mode 100644
index 00000000000..a02db40efa7
--- /dev/null
+++ b/innobase/com/ts/tscom.c
@@ -0,0 +1,94 @@
+/************************************************************************
+The test module for communication
+
+(c) 1995 Innobase Oy
+
+Created 9/26/1995 Heikki Tuuri
+*************************************************************************/
+
+#include "../com0com.h"
+#include "../com0shm.h"
+#include "ut0ut.h"
+#include "mem0mem.h"
+#include "os0thread.h"
+#include "sync0ipm.h"
+#include "sync0sync.h"
+
+byte buf[10000];
+char addr[150];
+
+void
+test1(void)
+/*=======*/
+{
+ com_endpoint_t* ep;
+ ulint ret;
+ ulint size;
+ ulint len;
+ ulint addr_len;
+ ulint i;
+
+ ep = com_endpoint_create(COM_SHM);
+
+ ut_a(ep);
+
+ size = 8192;
+
+ ret = com_endpoint_set_option(ep, COM_OPT_MAX_DGRAM_SIZE,
+ (byte*)&size, 0);
+
+ ut_a(ret == 0);
+
+ ret = com_bind(ep, "SRV", 3);
+
+ ut_a(ret == 0);
+
+ printf("Server endpoint created!\n");
+
+ for (i = 0; i < 50000; i++) {
+
+ ret = com_recvfrom(ep, buf, 10000, &len, addr, 150, &addr_len);
+
+ ut_a(ret == 0);
+
+ buf[len] = '\0';
+ addr[addr_len] = '\0';
+/*
+ printf(
+ "Message of len %lu\n%s \nreceived from address %s of len %lu\n",
+ len, buf, addr, addr_len);
+*/
+ ret = com_sendto(ep, (byte*)"Hello from server!\n", 18, "CLI", 3);
+
+ ut_a(ret == 0);
+ }
+
+ ret = com_endpoint_free(ep);
+
+ ut_ad(ret == 0);
+
+ printf("Count of extra system calls in com_shm %lu\n",
+ com_shm_system_call_count);
+ printf("Count of extra system calls in ip_mutex %lu\n",
+ ip_mutex_system_call_count);
+}
+
+void
+main(void)
+/*======*/
+{
+ ulint tm, oldtm;
+
+ sync_init();
+ mem_init();
+
+ oldtm = ut_clock();
+
+ test1();
+
+ ut_ad(mem_all_freed());
+
+ tm = ut_clock();
+ printf("Wall clock time for test %ld milliseconds\n", tm - oldtm);
+ printf("TESTS COMPLETED SUCCESSFULLY!\n");
+}