celix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pnol...@apache.org
Subject [2/2] celix git commit: CELIX-272: Added locking/threading example to test synchronization solutions and isues. Introduced release/retain concept for service reference and service registration.
Date Mon, 09 Nov 2015 17:07:56 GMT
CELIX-272: Added locking/threading example to test synchronization solutions and isues. Introduced release/retain concept for service reference and service registration.


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/e0231e51
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/e0231e51
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/e0231e51

Branch: refs/heads/feature/CELIX-272_synchronization_service_registry
Commit: e0231e51e4cac30018c7a71f9469e838348f642b
Parents: e9f2baa
Author: Pepijn Noltes <pepijnnoltes@gmail.com>
Authored: Mon Nov 9 18:06:18 2015 +0100
Committer: Pepijn Noltes <pepijnnoltes@gmail.com>
Committed: Mon Nov 9 18:06:18 2015 +0100

----------------------------------------------------------------------
 .../private/src/dm_component_impl.c             |   5 +-
 examples/CMakeLists.txt                         |   1 +
 examples/deploy.cmake                           |   3 +
 examples/locking/CMakeLists.txt                 |  24 ++
 examples/locking/benchmark/CMakeLists.txt       |  30 ++
 .../private/src/benchmark_runner_activator.c    | 255 +++++++++++++
 .../benchmark/public/include/benchmark.h        |  29 ++
 .../benchmark/public/include/benchmark_result.h |  20 +
 .../public/include/benchmark_service.h          |  27 ++
 .../public/include/frequency_service.h          |  47 +++
 .../benchmark/public/include/math_service.h     |  40 ++
 .../benchmark/public/src/benchmark_activator.c  | 133 +++++++
 examples/locking/consumer.c                     | 372 +++++++++++++++++++
 examples/locking/math_provider/CMakeLists.txt   |  32 ++
 .../private/include/math_component.h            |  14 +
 .../math_provider/private/src/math_component.c  |  28 ++
 .../private/src/provider_activator.c            | 219 +++++++++++
 .../modified_bool_benchmark/CMakeLists.txt      |  32 ++
 .../private/src/modified_bool_benchmark.c       | 162 ++++++++
 examples/locking/mutex_benchmark/CMakeLists.txt |  32 ++
 .../private/src/mutex_benchmark.c               | 117 ++++++
 .../locking/reference_benchmark/CMakeLists.txt  |  32 ++
 .../private/src/reference_benchmark.c           | 116 ++++++
 .../locking/start_stop_benchmark/CMakeLists.txt |  32 ++
 .../private/src/start_stop_benchmark.c          | 189 ++++++++++
 .../private/include/service_reference_private.h |   9 +-
 .../include/service_registration_private.h      |   6 +-
 .../private/include/service_registry_private.h  |   1 +
 framework/private/src/properties.c              |  22 ++
 framework/private/src/service_reference.c       |  71 ++--
 framework/private/src/service_registration.c    |  71 ++--
 framework/private/src/service_registry.c        |  26 +-
 framework/public/include/properties.h           |   3 +
 33 files changed, 2130 insertions(+), 70 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/dependency_manager/private/src/dm_component_impl.c
----------------------------------------------------------------------
diff --git a/dependency_manager/private/src/dm_component_impl.c b/dependency_manager/private/src/dm_component_impl.c
index d08bc28..aa34389 100644
--- a/dependency_manager/private/src/dm_component_impl.c
+++ b/dependency_manager/private/src/dm_component_impl.c
@@ -1097,8 +1097,9 @@ celix_status_t component_registerServices(dm_component_pt component) {
 
 	for (i = 0; i < arrayList_size(component->dm_interfaces); i++) {
 	    dm_interface_t *interface = arrayList_get(component->dm_interfaces, i);
-
-            bundleContext_registerService(component->context, interface->serviceName, interface->service, interface->properties, &interface->registration);
+            properties_pt regProps = NULL;
+            properties_copy(interface->properties, &regProps);
+            bundleContext_registerService(component->context, interface->serviceName, interface->service, regProps, &interface->registration);
 	}
     }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 677a6aa..55468a4 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -32,6 +32,7 @@ if (EXAMPLES)
     add_subdirectory(osgi-in-action/chapter04-correct-listener)
     add_subdirectory(osgi-in-action/chapter01-greeting-example)
     #add_subdirectory(osgi-in-action/chapter04-paint-example) chapter4 example is still based on APR
+    add_subdirectory(locking)
     
     #add_subdirectory(embedding) embedding is still baed on APR
 endif(EXAMPLES)

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/deploy.cmake
----------------------------------------------------------------------
diff --git a/examples/deploy.cmake b/examples/deploy.cmake
index 24c7a11..234f90b 100644
--- a/examples/deploy.cmake
+++ b/examples/deploy.cmake
@@ -28,4 +28,7 @@ if (EXAMPLES)
 	if (NOT ANDROID)
 		deploy("mongoose" BUNDLES shell shell_tui log_service apache_celix_examples_mongoose)
 	endif ()
+
+    deploy("locking_example" BUNDLES benchmark_runner reference_benchmark start_stop_benchmark mutex_benchmark math_provider shell shell_tui log_service log_writer)
+
 endif (EXAMPLES)

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/CMakeLists.txt b/examples/locking/CMakeLists.txt
new file mode 100644
index 0000000..e6c80ab
--- /dev/null
+++ b/examples/locking/CMakeLists.txt
@@ -0,0 +1,24 @@
+	# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+add_subdirectory(benchmark)
+add_subdirectory(math_provider)
+
+add_subdirectory(mutex_benchmark)
+add_subdirectory(reference_benchmark)
+add_subdirectory(start_stop_benchmark)
+add_subdirectory(modified_bool_benchmark)

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/benchmark/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/benchmark/CMakeLists.txt b/examples/locking/benchmark/CMakeLists.txt
new file mode 100644
index 0000000..ce5db7c
--- /dev/null
+++ b/examples/locking/benchmark/CMakeLists.txt
@@ -0,0 +1,30 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+SET(BUNDLE_SYMBOLICNAME benchmark_runner)
+SET(BUNDLE_VERSION 0.0.0)
+
+bundle(benchmark_runner SOURCES
+	private/src/benchmark_runner_activator 
+)
+
+include_directories(private/include)
+include_directories(public/include)
+include_directories(${PROJECT_SOURCE_DIR}/framework/public/include)
+include_directories(${PROJECT_SOURCE_DIR}/utils/public/include)
+
+target_link_libraries(benchmark_runner celix_framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/benchmark/private/src/benchmark_runner_activator.c
----------------------------------------------------------------------
diff --git a/examples/locking/benchmark/private/src/benchmark_runner_activator.c b/examples/locking/benchmark/private/src/benchmark_runner_activator.c
new file mode 100644
index 0000000..e06b77b
--- /dev/null
+++ b/examples/locking/benchmark/private/src/benchmark_runner_activator.c
@@ -0,0 +1,255 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * benchmark_activator.c
+ *
+ *  \date       Feb 12, 2014
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/queue.h>
+
+#include <pthread.h>
+
+#include "bundle_activator.h"
+#include "bundle_context.h"
+#include "service_registration.h"
+#include "service_tracker.h"
+
+#include "benchmark_service.h"
+#include "frequency_service.h"
+
+static celix_status_t benchmarkRunner_addingService(void * handle, service_reference_pt reference, void **service);
+static celix_status_t benchmarkRunner_addedService(void * handle, service_reference_pt reference, void * service);
+static celix_status_t benchmarkRunner_modifiedService(void * handle, service_reference_pt reference, void * service);
+static celix_status_t benchmarkRunner_removedService(void * handle, service_reference_pt reference, void * service);
+
+static void benchmarkRunner_runBenchmark(struct activator *activator);
+static void benchmarkRunner_printHeader(char *name, unsigned int nrOfSamples);
+static void benchmarkRunner_printResult(benchmark_result_t result, double updateFreq, unsigned long elapsedTime);
+static void benchmarkRunner_printFooter(char *name);
+
+struct benchmark_entry {
+	benchmark_service_pt benchmark;
+	LIST_ENTRY(benchmark_entry) entries;
+};
+
+struct activator {
+	bundle_context_pt context;
+	service_tracker_customizer_pt customizer;
+	service_tracker_pt tracker;
+	pthread_t thread;
+
+	pthread_mutex_t mutex;
+	array_list_pt benchmarks;
+	LIST_HEAD(benchmark_entries, entries) benchmarkEntries;
+	frequency_service_pt freqService;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	struct activator * activator = malloc(sizeof(*activator));
+	activator->context=context;
+	activator->customizer = NULL;
+	activator->tracker= NULL;
+	activator->benchmarks = NULL;
+	activator->freqService = NULL;
+
+	LIST_INIT(&activator->benchmarkEntries);
+
+	*userData = activator;
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = userData;
+
+	pthread_mutex_init(&activator->mutex, NULL);
+
+	arrayList_create(&activator->benchmarks);
+
+	serviceTrackerCustomizer_create(activator, benchmarkRunner_addingService, benchmarkRunner_addedService, benchmarkRunner_modifiedService, benchmarkRunner_removedService, &activator->customizer);
+
+	char filter[128];
+	sprintf(filter, "(|(%s=%s)(%s=%s))", "objectClass", BENCHMARK_SERVICE_NAME, "objectClass", FREQUENCY_SERVICE_NAME);
+	serviceTracker_createWithFilter(context, filter, activator->customizer, &activator->tracker);
+	serviceTracker_open(activator->tracker);
+
+	pthread_create(&activator->thread, NULL, (void *)benchmarkRunner_runBenchmark, activator);
+
+	return status;
+}
+
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	struct activator * activator = userData;
+
+	pthread_join(activator->thread, NULL);
+
+	serviceTracker_close(activator->tracker);
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	struct activator * activator = userData;
+
+	return CELIX_SUCCESS;
+}
+
+static celix_status_t benchmarkRunner_addingService(void * handle, service_reference_pt reference, void **service) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = handle;
+	status = bundleContext_getService(activator->context, reference, service);
+	return status;
+
+}
+static celix_status_t benchmarkRunner_addedService(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = handle;
+
+	service_registration_pt registration = NULL;
+	properties_pt properties = NULL;
+	char *serviceName = NULL;
+	serviceReference_getServiceRegistration(reference, &registration);
+	serviceRegistration_getProperties(registration, &properties);
+	serviceName = properties_get(properties, "objectClass");
+	if (strcmp(serviceName, BENCHMARK_SERVICE_NAME) == 0) {
+		pthread_mutex_lock(&activator->mutex);
+		arrayList_add(activator->benchmarks, service);
+		pthread_mutex_unlock(&activator->mutex);
+	} else if (strcmp(serviceName, FREQUENCY_SERVICE_NAME) == 0 ) {
+		pthread_mutex_lock(&activator->mutex);
+		activator->freqService = service;
+		pthread_mutex_unlock(&activator->mutex);
+	}
+
+	return status;
+}
+static celix_status_t benchmarkRunner_modifiedService(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = handle;
+	return status;
+}
+
+static celix_status_t benchmarkRunner_removedService(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = handle;
+
+	service_registration_pt registration = NULL;
+		properties_pt properties = NULL;
+		char *serviceName = NULL;
+		serviceReference_getServiceRegistration(reference, &registration);
+		serviceRegistration_getProperties(registration, &properties);
+		serviceName = properties_get(properties, "objectClass");
+		if (strcmp(serviceName, BENCHMARK_SERVICE_NAME) == 0) {
+			pthread_mutex_lock(&activator->mutex);
+			arrayList_removeElement(activator->benchmarks, service);
+			pthread_mutex_unlock(&activator->mutex);
+		} else if (strcmp(serviceName, FREQUENCY_SERVICE_NAME) == 0 ) {
+			pthread_mutex_lock(&activator->mutex);
+			if (activator->freqService == service) {
+				activator->freqService = NULL;
+			}
+			pthread_mutex_unlock(&activator->mutex);
+		}
+
+	return status;
+}
+
+static void benchmarkRunner_runBenchmark(struct activator *activator) {
+	int i, k;
+	int nrOfBenchmarks;
+	double updateFrequency, measuredFrequency;
+	unsigned int measuredUpdateCounter, nrOfUpdateThreads;
+	int nrOfSamples;
+	benchmark_service_pt benchmarkServ;
+	char *name;
+	benchmark_result_t result;
+	struct timeval begin,end;
+	unsigned long elapsedTime;
+	double sampleFactor;
+
+	int nrOfThreadRuns = 12;
+	int threads[] = {1,2,3,4,5,6,7,8,16,32,64,128};
+
+	nrOfSamples = 100 * 1000;
+	updateFrequency = 1000;
+	nrOfUpdateThreads = 100;
+
+	usleep(2000 * 1000); //wait 2 seconds to get needed services
+
+	pthread_mutex_lock(&activator->mutex);
+	if (activator->freqService != NULL) {
+		activator->freqService->setFrequency(activator->freqService->handle, updateFrequency);
+		activator->freqService->setNrOfThreads(activator->freqService->handle, nrOfUpdateThreads);
+	}
+	nrOfBenchmarks = arrayList_size(activator->benchmarks);
+	for (i = 0 ; i < nrOfBenchmarks ; i += 1) {
+		benchmarkServ = arrayList_get(activator->benchmarks, i);
+		name = benchmarkServ->name(benchmarkServ->handler);
+		sampleFactor = benchmarkServ->getSampleFactor(benchmarkServ->handler);
+		activator->freqService->setBenchmarkName(activator->freqService->handle, name);
+		usleep(1000);
+		benchmarkRunner_printHeader(name, nrOfSamples * sampleFactor);
+		for (k = 0 ; k < nrOfThreadRuns ; k +=1) {
+			if (activator->freqService != NULL) {
+					activator->freqService->resetCounter(activator->freqService->handle);
+
+			}
+			gettimeofday(&begin, NULL);
+			result = benchmarkServ->run(benchmarkServ->handler, threads[k], nrOfSamples * sampleFactor);
+			gettimeofday(&end, NULL);
+			elapsedTime = ((end.tv_sec - begin.tv_sec) * 1000000) + (end.tv_usec - begin.tv_usec);
+			if (activator->freqService != NULL) {
+				measuredUpdateCounter = activator->freqService->getCounter(activator->freqService->handle);
+				measuredFrequency = ((double)(measuredUpdateCounter) / elapsedTime * 1000000);
+			}
+			benchmarkRunner_printResult(result, measuredFrequency, elapsedTime);
+		}
+		benchmarkRunner_printFooter(name);
+	}
+	pthread_mutex_unlock(&activator->mutex);
+}
+
+static void benchmarkRunner_printHeader(char *name, unsigned int nrOfSamples) {
+		int i;
+		printf("---% 35s---------------------------------------------------------------------------------------\n", name);
+		printf("-------samples: %10i---------------------------------------------------------------------------------------------------\n", nrOfSamples);
+}
+
+static void benchmarkRunner_printResult(benchmark_result_t result, double updateFreq, unsigned long elapsedTime) {
+	printf("| threads %5i | ", result.nrOfThreads);
+	printf("average call time: % 10.2f nanoseconds | ", result.averageCallTimeInNanoseconds);
+	printf("frequency calls is % 10.5f MHz | ", result.callFrequencyInMhz);
+	printf("update freq ~ % 8.2f Hz | ", updateFreq);
+	printf("elapsed time is % 8.5f seconds | ", ((double)elapsedTime) / 1000000);
+	printf("\n");
+}
+
+static void benchmarkRunner_printFooter(char *name) {
+	printf("-----------------------------------------------------------------------------------------------------------------------------\n\n\n");
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/benchmark/public/include/benchmark.h
----------------------------------------------------------------------
diff --git a/examples/locking/benchmark/public/include/benchmark.h b/examples/locking/benchmark/public/include/benchmark.h
new file mode 100644
index 0000000..971f111
--- /dev/null
+++ b/examples/locking/benchmark/public/include/benchmark.h
@@ -0,0 +1,29 @@
+/*
+ * consumer.h
+ *
+ *  Created on: Feb 13, 2014
+ *      Author: dl436
+ */
+
+#ifndef CONSUMER_H_
+#define CONSUMER_H_
+
+#include "celix_errno.h"
+
+#include "benchmark_result.h"
+#include "math_service.h"
+
+typedef struct benchmark *benchmark_pt; //ADT
+
+celix_status_t benchmark_create(benchmark_pt *benchmark);
+celix_status_t benchmark_destroy(benchmark_pt benchmark);
+
+benchmark_result_t benchmark_run(benchmark_pt benchmark, int nrOfThreads, int nrOfSamples);
+char * benchmark_getName(benchmark_pt benchmark);
+double benchmark_getSampleFactor(benchmark_pt benchmark);
+
+celix_status_t benchmark_addMathService(benchmark_pt benchmark, math_service_pt mathService);
+celix_status_t benchmark_removeMathService(benchmark_pt benchmark, math_service_pt mathService);
+
+
+#endif /* CONSUMER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/benchmark/public/include/benchmark_result.h
----------------------------------------------------------------------
diff --git a/examples/locking/benchmark/public/include/benchmark_result.h b/examples/locking/benchmark/public/include/benchmark_result.h
new file mode 100644
index 0000000..e0750a8
--- /dev/null
+++ b/examples/locking/benchmark/public/include/benchmark_result.h
@@ -0,0 +1,20 @@
+/*
+ * benchmark_result.h
+ *
+ *  Created on: Feb 13, 2014
+ *      Author: dl436
+ */
+
+#ifndef BENCHMARK_RESULT_H_
+#define BENCHMARK_RESULT_H_
+
+typedef struct benchmark_result {
+		unsigned int nrOfThreads;
+		unsigned int nrOfsamples;
+		unsigned int result;
+		unsigned int skips;
+		double averageCallTimeInNanoseconds;
+		double callFrequencyInMhz;
+} benchmark_result_t;
+
+#endif /* BENCHMARK_RESULT_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/benchmark/public/include/benchmark_service.h
----------------------------------------------------------------------
diff --git a/examples/locking/benchmark/public/include/benchmark_service.h b/examples/locking/benchmark/public/include/benchmark_service.h
new file mode 100644
index 0000000..63ada04
--- /dev/null
+++ b/examples/locking/benchmark/public/include/benchmark_service.h
@@ -0,0 +1,27 @@
+/*
+ * benchmark_service.h
+ *
+ *  Created on: Feb 13, 2014
+ *      Author: dl436
+ */
+
+#ifndef BENCHMARK_SERVICE_H_
+#define BENCHMARK_SERVICE_H_
+
+#include "benchmark_result.h"
+
+typedef struct benchmark_service *benchmark_service_pt;
+
+typedef struct benchmark_handler *benchmark_handler_pt; //ADT
+
+#define BENCHMARK_SERVICE_NAME "benchmark_service"
+
+struct benchmark_service {
+	benchmark_handler_pt handler;
+
+	benchmark_result_t (*run)(benchmark_handler_pt handler, int nrOfThreads, int nrOfSamples);
+	char * (*name)(benchmark_handler_pt handler);
+	double (*getSampleFactor)(benchmark_handler_pt benchmark);
+};
+
+#endif /* BENCHMARK_SERVICE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/benchmark/public/include/frequency_service.h
----------------------------------------------------------------------
diff --git a/examples/locking/benchmark/public/include/frequency_service.h b/examples/locking/benchmark/public/include/frequency_service.h
new file mode 100644
index 0000000..5c022ce
--- /dev/null
+++ b/examples/locking/benchmark/public/include/frequency_service.h
@@ -0,0 +1,47 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * frequence_service.h
+ *
+ *  \date       Feb 4, 2014
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+//TODO change to math provider service ???
+
+#ifndef FREQUENCY_SERVICE_H
+#define FREQUENCY_SERVICE_H
+
+#define FREQUENCY_SERVICE_NAME "frequency_service"
+
+typedef struct frequency_hander frequence_handler_t;
+
+struct frequency_service {
+	frequence_handler_t *handle;
+	void (*setFrequency)(frequence_handler_t *handle, int freq);
+	void (*resetCounter)(frequence_handler_t *handle);
+	uint (*getCounter)(frequence_handler_t *handle);
+	void (*setBenchmarkName)(frequence_handler_t *handle, char *name);
+	void (*setNrOfThreads)(frequence_handler_t *handle, uint nrOfThreads);
+};
+
+typedef struct frequency_service * frequency_service_pt;
+
+#endif /* FREQUENCY_SERVICE_H */

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/benchmark/public/include/math_service.h
----------------------------------------------------------------------
diff --git a/examples/locking/benchmark/public/include/math_service.h b/examples/locking/benchmark/public/include/math_service.h
new file mode 100644
index 0000000..154cc9c
--- /dev/null
+++ b/examples/locking/benchmark/public/include/math_service.h
@@ -0,0 +1,40 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * echo_server.h
+ *
+ *  \date       Sep 21, 2010
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef MATH_SERVICE_H 
+#define MATH_SERVICE_H 
+
+#define MATH_SERVICE_NAME "math_service"
+
+
+struct math_service {
+	void *handle;
+	int (*calc)(void *handle, int arg1, int arg2);
+};
+
+typedef struct math_service * math_service_pt;
+
+#endif /* MATH_SERVICE_H */

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/benchmark/public/src/benchmark_activator.c
----------------------------------------------------------------------
diff --git a/examples/locking/benchmark/public/src/benchmark_activator.c b/examples/locking/benchmark/public/src/benchmark_activator.c
new file mode 100644
index 0000000..a161f11
--- /dev/null
+++ b/examples/locking/benchmark/public/src/benchmark_activator.c
@@ -0,0 +1,133 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * echo_server_activator.c
+ *
+ *  \date       Sep 21, 2010
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "bundle_activator.h"
+#include "bundle_context.h"
+#include "service_registration.h"
+#include "service_tracker.h"
+
+#include "math_service.h"
+#include "benchmark.h"
+#include "benchmark_service.h"
+#include "frequency_service.h"
+
+static celix_status_t addingService(void * handle, service_reference_pt reference, void **service);
+static celix_status_t addedService(void * handle, service_reference_pt reference, void * service);
+static celix_status_t modifiedService(void * handle, service_reference_pt reference, void * service);
+static celix_status_t removedService(void * handle, service_reference_pt reference, void * service);
+
+struct activator {
+	bundle_context_pt context;
+	benchmark_pt benchmark;
+	benchmark_service_pt mathService;
+	service_tracker_customizer_pt customizer;
+	service_tracker_pt tracker;
+	service_registration_pt registration;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	struct activator * activator = malloc(sizeof(*activator));
+	activator->context=context;
+	activator->benchmark=NULL;
+	activator->mathService = NULL;
+	activator->customizer = NULL;
+	activator->tracker=NULL;
+	activator->registration = NULL;
+
+	*userData = activator;
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = userData;
+
+	status = benchmark_create(&activator->benchmark);
+	serviceTrackerCustomizer_create(activator, addingService, addedService, modifiedService, removedService, &activator->customizer);
+
+	char filter[128];
+	sprintf(filter, "(&(objectClass=%s)(benchmark=%s))", MATH_SERVICE_NAME, benchmark_getName(activator->benchmark));
+
+	serviceTracker_createWithFilter(context, filter, activator->customizer, &activator->tracker);
+	serviceTracker_open(activator->tracker);
+
+	activator->mathService = malloc(sizeof(*activator->mathService));
+	activator->mathService->handler = (void *)activator->benchmark;
+	activator->mathService->name=(void *)benchmark_getName;
+	activator->mathService->getSampleFactor=(void *)benchmark_getSampleFactor;
+	activator->mathService->run=(void *)benchmark_run;
+
+	status = bundleContext_registerService(activator->context, BENCHMARK_SERVICE_NAME, activator->mathService, NULL, &activator->registration);
+
+	return status;
+}
+
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	struct activator * activator = userData;
+
+	serviceTracker_close(activator->tracker);
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	struct activator * activator = userData;
+
+	benchmark_destroy(activator->benchmark);
+	activator->benchmark=NULL;
+
+	return CELIX_SUCCESS;
+}
+
+static celix_status_t addingService(void * handle, service_reference_pt reference, void **service) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = handle;
+	status = bundleContext_getService(activator->context, reference, service);
+	return status;
+
+}
+static celix_status_t addedService(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = handle;
+	benchmark_addMathService(activator->benchmark, service);
+	return status;
+}
+static celix_status_t modifiedService(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = handle;
+	return status;
+}
+
+static celix_status_t removedService(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = handle;
+	benchmark_removeMathService(activator->benchmark, service);
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/consumer.c
----------------------------------------------------------------------
diff --git a/examples/locking/consumer.c b/examples/locking/consumer.c
new file mode 100644
index 0000000..b73549e
--- /dev/null
+++ b/examples/locking/consumer.c
@@ -0,0 +1,372 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * consumer.c
+ *
+ *  \date       Feb 3, 2014
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include "consumer.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#include <urcu.h>
+
+#include "math_service.h"
+#include "frequency_service.h"
+
+#define FREELIST_LENGTH 16
+
+typedef union service_counter service_counter_t;
+
+union service_counter {
+	volatile struct {
+		volatile u_int32_t counter; //TODO FIXME assuming little endian!!
+		volatile u_int32_t position;
+		math_service_pt math; // not accesible by raw
+	} info; //TODO rename data
+	volatile u_int64_t data; //TODO rename raw
+};
+
+struct consumer {
+	math_service_pt math;
+	frequency_service_pt frequencyService;
+	locking_type_t currentLockingType;
+	pthread_mutex_t mutex;
+	pthread_rwlock_t rw_lock;
+	service_counter_t *counters[FREELIST_LENGTH];
+	service_counter_t *current;
+};
+
+typedef struct run_info {
+	consumer_pt consumer;
+	volatile locking_type_t type;
+	int nrOfsamples;
+	int result;
+	uint skips;
+	uint updateCounter;
+	struct timeval begin;
+	struct timeval end;
+} run_info_t;
+
+static void * consumer_reference_run(run_info_t *info);
+static void * consumer_no_locking_run(run_info_t *info);
+static void * consumer_mutex_run(run_info_t *info);
+static void * consumer_rcu_run(run_info_t *info);
+static void * consumer_reference_counting_run(run_info_t *info);
+static void * consumer_rw_lock_run(run_info_t *info);
+
+static int consumer_reference_calc(int arg1, int arg2);
+
+celix_status_t consumer_create(consumer_pt *result) {
+	consumer_pt consumer = malloc(sizeof(*consumer));
+	consumer->math = NULL;
+	consumer->frequencyService = NULL;
+	consumer->currentLockingType=LOCKING_TYPE_NO_LOCKING;
+
+
+	service_counter_t *new = malloc(sizeof(service_counter_t));
+	new->info.position = 0;
+	new->info.counter = 0;
+	new->info.math = NULL;
+
+	int i;
+	for (i = 0; i < FREELIST_LENGTH; i+=1) {
+		consumer->counters[i] = NULL;
+	}
+	consumer->current = new;
+	consumer->counters[0] = new;
+
+	pthread_mutex_init(&consumer->mutex, NULL);
+	pthread_rwlock_init(&consumer->rw_lock, NULL);
+
+	rcu_init();
+
+	(*result) = consumer;
+	return CELIX_SUCCESS;
+}
+
+celix_status_t consumer_destroy(consumer_pt consumer) {
+	pthread_mutex_destroy(&consumer->mutex);
+	pthread_rwlock_destroy(&consumer->rw_lock);
+	free(consumer);
+	return CELIX_SUCCESS;
+}
+
+void consumer_setFrequencyService(consumer_pt consumer, frequency_service_pt freqServ) {
+	consumer->frequencyService=freqServ;
+}
+
+void consumer_runBenchmark(consumer_pt consumer, locking_type_t type, int nrOfThreads, int nrOfSamples) {
+	pthread_t threads[nrOfThreads];
+	run_info_t info[nrOfThreads];
+	int elapsedTime, skips, counter;
+	double callTime, callFreq, updateFreq;
+	int i;
+
+	consumer->currentLockingType=type;
+	usleep(1000);
+
+	//init
+	for (i = 0; i< nrOfThreads; i += 1) {
+		info[i].consumer = consumer;
+		info[i].nrOfsamples=nrOfSamples;
+		info[i].result = rand();
+		info[i].skips = 0;
+		info[i].updateCounter = 0;
+	}
+	elapsedTime = 0;
+	skips = 0;
+
+	//start threads
+	info->consumer->frequencyService->resetCounter(info->consumer->frequencyService->handler);
+	for (i = 0; i < nrOfThreads; i += 1) {
+		if (type == LOCKING_TYPE_NO_LOCKING) {
+			pthread_create(&threads[i], NULL, (void *)consumer_no_locking_run, &info[i]);
+		} else if (type == LOCKING_TYPE_MUTEX) {
+			pthread_create(&threads[i], NULL, (void *)consumer_mutex_run, &info[i]);
+		} else if (type == LOCKING_TYPE_REFERENCE) {
+			pthread_create(&threads[i], NULL, (void *)consumer_reference_run, &info[i]);
+		} else if (type == LOCKING_TYPE_RCU) {
+			pthread_create(&threads[i], NULL, (void *)consumer_rcu_run, &info[i]);
+		} else if (type == LOCKING_TYPE_REFERENCE_COUNTER) {
+			pthread_create(&threads[i], NULL, (void *)consumer_reference_counting_run, &info[i]);
+		} else if (type == LOCKING_TYPE_RW_LOCK) {
+			pthread_create(&threads[i], NULL, (void *)consumer_rw_lock_run, &info[i]);
+		} else {
+			printf ("unknown type\n");
+			return;
+		}
+	}
+
+	//join and print result
+
+	for (i = 0; i < nrOfThreads; i +=1 ) {
+		pthread_join(threads[i], NULL);
+		elapsedTime += ((info[i].end.tv_sec - info[i].begin.tv_sec) * 1000000) + (info[i].end.tv_usec - info[i].begin.tv_usec);
+		skips += info[i].skips;
+		counter += info[i].updateCounter;
+	}
+	counter = info->consumer->frequencyService->getCounter(info->consumer->frequencyService->handler);
+	callTime = ((double)elapsedTime * 1000) / (nrOfSamples * nrOfThreads);
+	callFreq = ((double)(nrOfSamples * nrOfThreads) / elapsedTime);
+	updateFreq = ((double)counter * 1000000) / elapsedTime;
+	printf("| threads %5i | ", nrOfThreads);
+	printf("average call time: % 10.2f nanoseconds | ", callTime);
+	printf("frequency calls is % 10.5f MHz | ", callFreq);
+	printf("update freq ~ % 8.2f Hz | ", updateFreq);
+	printf("\n");
+
+	if (skips > 0) {
+		printf("WARNING skips is %i\n", skips);
+	}
+}
+
+celix_status_t consumer_addMathService(consumer_pt consumer, math_service_pt mathService) {
+	if (consumer->currentLockingType == LOCKING_TYPE_MUTEX) {
+		pthread_mutex_lock(&consumer->mutex);
+		consumer->math = mathService;
+		pthread_mutex_unlock(&consumer->mutex);
+	} else if (consumer->currentLockingType == LOCKING_TYPE_RCU) {
+		consumer->math = mathService;
+		synchronize_rcu();
+	} else if (consumer->currentLockingType == LOCKING_TYPE_RW_LOCK) {
+		pthread_rwlock_wrlock(&consumer->rw_lock);
+		consumer->math = mathService;
+		pthread_rwlock_unlock(&consumer->rw_lock);
+	} else { //no locking
+		consumer->math = mathService;
+	}
+
+	//always update for reference counter
+//	service_counter_t *new = malloc(sizeof(service_counter_t));
+//	new->info.position = 0;
+//	new->info.counter = 0;
+//	new->info.math = mathService;
+//	int found = false;
+//	int pos;
+//	for (pos = 0; !found && pos < FREELIST_LENGTH; pos += 1) {
+//		found = __sync_bool_compare_and_swap(&(consumer->counters[pos]), NULL, new);
+//		if (found) {
+//			new->info.position = pos;
+//			break;
+//		}
+//	}
+//
+//	if (!found) {
+//		printf("Cannot find free spot!!!!, will use 0\n");
+//		consumer->counters[0] = new;
+//	}
+//
+//	int changed = false;
+//	service_counter_t *old;
+//	while (!changed) {
+//		old = consumer->current;
+//		changed = __sync_bool_compare_and_swap(&consumer->current, old, new);
+//	}
+//
+//	while (old->info.counter != 0) {usleep(10);}
+//	consumer->counters[old->info.position] = NULL;
+//	free(old);
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t consumer_removeMathService(consumer_pt consumer, math_service_pt mathService) {
+	if (consumer->currentLockingType == LOCKING_TYPE_NO_LOCKING) {
+		__sync_val_compare_and_swap(&consumer->math, mathService, NULL);
+	} else if (consumer->currentLockingType == LOCKING_TYPE_MUTEX) {
+		pthread_mutex_lock(&consumer->mutex);
+		if (consumer->math == mathService) {
+			consumer->math = NULL;
+		}
+		pthread_mutex_unlock(&consumer->mutex);
+	} else if (consumer->currentLockingType == LOCKING_TYPE_RCU) {
+		uatomic_cmpxchg(&consumer->math, mathService, NULL);
+	} else if (consumer->currentLockingType == LOCKING_TYPE_REFERENCE_COUNTER) {
+		//TODO DONT KNOWN IGNORE FOR NOW
+	}
+	return CELIX_SUCCESS;
+}
+
+static void * consumer_reference_run(run_info_t *info) {
+	int i;
+
+	gettimeofday(&info->begin, NULL);
+	for (i = 0; i < info->nrOfsamples; i += 1) {
+		info->result = consumer_reference_calc(info->result, i);
+	}
+	gettimeofday(&info->end, NULL);
+	return NULL;
+}
+
+static void * consumer_no_locking_run(run_info_t *info) {
+	int i;
+
+	gettimeofday(&info->begin, NULL);
+	for (i = 0; i < info->nrOfsamples; i += 1) {
+		if (info->consumer->math != NULL) {
+				info->result = info->consumer->math->calc(info->result, i);
+		} else {
+				info->skips +=1; //should not happen
+		}
+	}
+	gettimeofday(&info->end, NULL);
+	return NULL;
+}
+
+static void * consumer_mutex_run(run_info_t *info) {
+	int i;
+
+	gettimeofday(&info->begin, NULL);
+	for (i = 0; i < info->nrOfsamples; i += 1) {
+		pthread_mutex_lock(&info->consumer->mutex);
+		if (info->consumer->math != NULL) {
+			info->result = info->consumer->math->calc(info->result, i);
+		} else {
+			info->skips += 1; //should not happen
+		}
+		pthread_mutex_unlock(&info->consumer->mutex);
+	}
+	gettimeofday(&info->end, NULL);
+	return NULL;
+}
+
+static void * consumer_rw_lock_run(run_info_t *info) {
+	int i;
+	consumer_pt cons = info->consumer;
+	int result = info->result;
+	pthread_rwlock_t *lock = &cons->rw_lock;
+	int nrOfsamples = info->nrOfsamples;
+
+	gettimeofday(&info->begin, NULL);
+	for (i = 0; i < nrOfsamples; i += 1) {
+		pthread_rwlock_rdlock(lock);
+		if (cons->math != NULL) {
+			result = cons->math->calc(result, i);
+		} else {
+			info->skips += 1; //should not happen
+		}
+		pthread_rwlock_unlock(lock);
+	}
+	gettimeofday(&info->end, NULL);
+	info->result = result;
+	return NULL;
+}
+
+static void * consumer_rcu_run(run_info_t *info) {
+	rcu_register_thread();
+	int i;
+	math_service_pt service;
+
+	gettimeofday(&info->begin, NULL);
+	for (i = 0; i < info->nrOfsamples; i += 1) {
+		rcu_read_lock();
+		if (info->consumer->math != NULL) {
+			info->result = info->consumer->math->calc(info->result, i);
+		} else {
+			info->skips +=1; //should not happen
+		}
+		rcu_read_unlock();
+	}
+	gettimeofday(&info->end, NULL);
+	rcu_unregister_thread();
+	return NULL;
+}
+
+static void * consumer_reference_counting_run(run_info_t *info) {
+	int i;
+	service_counter_t posAndCount;
+
+	gettimeofday(&info->begin, NULL);
+	for (i = 0; i < info->nrOfsamples; i += 1) {
+		posAndCount.data = __sync_add_and_fetch((u_int64_t *)&info->consumer->current->data, 1);
+		volatile service_counter_t *serv = (volatile void *)info->consumer->counters[posAndCount.info.position];
+		if (serv->info.math != NULL) {
+			info->result = serv->info.math->calc(info->result, i);
+		} else {
+			info->skips += 1;
+		}
+		__sync_sub_and_fetch((u_int64_t *)&serv->data, -1);
+
+		//not service_counter will not be deleted...but can we still find it??? is info->consumer->serviceCounter still te same?
+		//change write to swap compare and then only changing the pointer is the counter is null?? not possible.. can compare counter , but not change pointer
+
+		//IDEA create a list with service_counter based on a id (number) this number is 32bit long and put a counter + id in a 64bit value.
+		//use this value to atomic increment and return value and use the id to retrieve the actual pointer. the value can be stored in the heap.
+		//A list with id is used to retrieve a pointer to the service. If the value is null the slot is available this can be check with
+		//compare_and_swap while looping through the list. The list can be extended when the end is reached and then a next list pointer can
+		//be used. This can also be a linked list and the limitation is the max 32bit uint value (of 16bits for 32bit platforms).
+	}
+
+	gettimeofday(&info->end, NULL);
+	return NULL;
+}
+
+//NOTE: copy implementation of the math_service->calc function, for reference.
+static int consumer_reference_calc(int arg1, int arg2) {
+	return  arg1 * arg2 + arg2;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/math_provider/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/math_provider/CMakeLists.txt b/examples/locking/math_provider/CMakeLists.txt
new file mode 100644
index 0000000..288d6ba
--- /dev/null
+++ b/examples/locking/math_provider/CMakeLists.txt
@@ -0,0 +1,32 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+SET(BUNDLE_SYMBOLICNAME math_provider)
+SET(BUNDLE_VERSION 0.0.0)
+
+bundle(math_provider SOURCES 
+	private/src/provider_activator 
+	private/src/math_component
+)
+
+include_directories(public/include)
+include_directories(../benchmark/public/include)
+include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/shell/public/include")
+include_directories(private/include)
+target_link_libraries(math_provider celix_framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/math_provider/private/include/math_component.h
----------------------------------------------------------------------
diff --git a/examples/locking/math_provider/private/include/math_component.h b/examples/locking/math_provider/private/include/math_component.h
new file mode 100644
index 0000000..0b55d10
--- /dev/null
+++ b/examples/locking/math_provider/private/include/math_component.h
@@ -0,0 +1,14 @@
+#ifndef MATH_COMPONENT_H_
+#define MATH_COMPONENT_H_
+
+#include "celix_errno.h"
+
+typedef struct math_component *math_component_pt;
+
+celix_status_t mathComponent_create(math_component_pt *math);
+celix_status_t mathComponent_destroy(math_component_pt math);
+
+int mathComponent_calc(math_component_pt math, int arg1, int arg2);
+
+
+#endif /* MATH_COMPONENT_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/math_provider/private/src/math_component.c
----------------------------------------------------------------------
diff --git a/examples/locking/math_provider/private/src/math_component.c b/examples/locking/math_provider/private/src/math_component.c
new file mode 100644
index 0000000..2937fee
--- /dev/null
+++ b/examples/locking/math_provider/private/src/math_component.c
@@ -0,0 +1,28 @@
+/*
+ * math.c
+ *
+ *  Created on: Oct 8, 2014
+ *      Author: dl436
+ */
+
+#include "math_component.h"
+
+struct math_component {
+	//emtpy
+};
+
+celix_status_t mathComponent_create(math_component_pt *math) {
+	(*math) = malloc(sizeof(struct math_component));
+	return CELIX_SUCCESS;
+}
+
+celix_status_t mathComponent_destroy(math_component_pt math) {
+	free(math);
+	return CELIX_SUCCESS;
+}
+
+int mathComponent_calc(math_component_pt math, int arg1, int arg2) {
+	return arg1 * arg2 + arg2;
+}
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/math_provider/private/src/provider_activator.c
----------------------------------------------------------------------
diff --git a/examples/locking/math_provider/private/src/provider_activator.c b/examples/locking/math_provider/private/src/provider_activator.c
new file mode 100644
index 0000000..319980f
--- /dev/null
+++ b/examples/locking/math_provider/private/src/provider_activator.c
@@ -0,0 +1,219 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * echo_server_activator.c
+ *
+ *  \date       Sep 21, 2010
+ *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <sys/time.h>
+
+#include "bundle_activator.h"
+#include "bundle_context.h"
+#include "service_registration.h"
+
+#include "math_service.h"
+#include "frequency_service.h"
+#include "math_component.h"
+
+typedef struct activator {
+	bundle_context_pt context;
+
+	frequency_service_pt freqService;
+	service_registration_pt freqRegistration;
+
+	math_component_pt math;
+	math_service_pt mathService;
+	char *benchmarkName;
+	service_registration_pt registration;
+
+	uint updateFrequency;
+	uint nrOfThreads;
+	pthread_t *threads;
+
+
+	volatile uint counter;
+	struct timeval beginMeasurement;
+	struct timeval endMeasurement;
+} activator_t;
+
+static int calc(int arg1, int arg2);
+static void run(activator_t *activator);
+static void setFrequency(activator_t *activator, uint freq);
+static void setNrOfThreads(activator_t *activator, uint nrOfThreads);
+static void resetCounter(activator_t *activator);
+static void stopThreads(activator_t *activator);
+static void startThreads(activator_t *activator, uint nrOfThreads);
+static uint getCounter(activator_t *activator);
+static void setBenchmarkName(activator_t *activator, char *benchmark);
+static math_service_pt registerMath(activator_t *activator, service_registration_pt *reg);
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	activator_t * activator = malloc(sizeof(*activator));
+	activator->context = context;
+	activator->benchmarkName = NULL;
+	activator->freqService  = NULL;
+	activator->freqRegistration  = NULL;
+	activator->updateFrequency = 0;
+	activator->nrOfThreads = 0;
+	activator->math = NULL;
+
+	mathComponent_create(&activator->math);
+
+	*userData = activator;
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator * activator = userData;
+
+	activator->mathService = malloc(sizeof(*activator->mathService));
+	activator->mathService->handle = activator->math;
+	activator->mathService->calc = (void *)mathComponent_calc;
+	bundleContext_registerService(activator->context, MATH_SERVICE_NAME, activator->mathService, NULL, &activator->registration);
+
+	activator->freqService = malloc(sizeof(*activator->freqService));
+	activator->freqService->handle = (void *)activator;
+	activator->freqService->setFrequency = (void *)setFrequency;
+	activator->freqService->resetCounter = (void *)resetCounter;
+	activator->freqService->getCounter = (void *)getCounter;
+	activator->freqService->setBenchmarkName = (void *)setBenchmarkName;
+	activator->freqService->setNrOfThreads = (void *)setNrOfThreads;
+	bundleContext_registerService(activator->context, FREQUENCY_SERVICE_NAME, activator->freqService, NULL, &activator->freqRegistration);
+
+	startThreads(activator, activator->nrOfThreads);
+
+	return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	struct activator * activator = userData;
+
+	printf("Stopping service registration thread\n");
+	stopThreads(activator);
+
+	//TODO deregister service & freqService
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	struct echoActivator * activator = userData;
+
+	//TODO free service & freqService struct
+
+	free(activator);
+
+	return CELIX_SUCCESS;
+}
+
+static int calc(int arg1, int arg2) {
+	return  arg1 * arg2 + arg2;
+}
+
+static void stopThreads(activator_t *activator) {
+	//cancel and join threads
+	if (activator->threads != NULL) {
+		for (int i = 0 ; i < activator->nrOfThreads ; i += 1) {
+			pthread_cancel(activator->threads[i]);
+			pthread_join(activator->threads[i], NULL);
+		}
+	}
+}
+
+static void startThreads(activator_t *activator, uint nrOfThreads) {
+	activator->threads = malloc(sizeof(pthread_t) * nrOfThreads);
+	for (int i = 0 ; i < nrOfThreads ; i += 1) {
+		pthread_create(&activator->threads[i], NULL, (void *)run, activator);
+	}
+	activator->nrOfThreads = nrOfThreads;
+}
+
+static void run(activator_t *activator) {
+	service_registration_pt currentReg = NULL;
+	service_registration_pt prevReg = NULL;
+	math_service_pt current = NULL;
+	math_service_pt prev = NULL;
+	while (1) {
+		pthread_testcancel(); //NOTE no clean exit still need to clear a register service
+ 		uint delayInMicroseconds =  activator->updateFrequency == 0 ? 0 : (1000 * 1000) / activator->updateFrequency;
+		if (delayInMicroseconds > 0) {
+			prevReg = currentReg;
+			prev = current;
+
+			currentReg = NULL;
+			current = registerMath(activator, &currentReg);
+
+			if (prevReg != NULL) {
+				serviceRegistration_unregister(prevReg);
+				free(prev);
+			}
+		}
+		usleep(delayInMicroseconds > 0 ? delayInMicroseconds : 1000000);
+	}
+}
+
+static math_service_pt registerMath(activator_t *activator, service_registration_pt *reg) {
+	math_service_pt serv = NULL;
+	serv = malloc(sizeof(*activator->mathService));
+	serv->handle = activator->math;
+	serv->calc = (void *)mathComponent_calc;
+	properties_pt props = properties_create();
+	if (activator->benchmarkName != NULL) { //TODO FIXME race condition
+		properties_set(props, "benchmark", activator->benchmarkName);
+	}
+	bundleContext_registerService(activator->context, MATH_SERVICE_NAME,
+			serv, props, reg);
+	activator->counter += 1;
+	return serv;
+}
+
+static void setBenchmarkName(activator_t *activator, char *benchmark) {
+	char *old = activator->benchmarkName;
+	activator->benchmarkName = strdup(benchmark);
+	free(old);
+	if (activator->updateFrequency == 0) {
+		service_registration_pt reg = NULL;
+		registerMath(activator, &reg); //TODO service will not be cleaned up !
+	}
+}
+
+static void setFrequency(activator_t *activator, uint freq) {
+	printf("Setting frequency to %i\n", freq);
+	activator->updateFrequency = freq;
+}
+
+static void setNrOfThreads(activator_t *activator, uint nrOfThreads) {
+	stopThreads(activator);
+	startThreads(activator, nrOfThreads);
+}
+
+static void resetCounter(activator_t *activator) {
+	activator->counter = 0;
+}
+
+static uint getCounter(activator_t *activator) {
+	return activator->counter;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/modified_bool_benchmark/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/modified_bool_benchmark/CMakeLists.txt b/examples/locking/modified_bool_benchmark/CMakeLists.txt
new file mode 100644
index 0000000..46ceb7a
--- /dev/null
+++ b/examples/locking/modified_bool_benchmark/CMakeLists.txt
@@ -0,0 +1,32 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+SET(BUNDLE_SYMBOLICNAME bool_benchmark)
+SET(BUNDLE_VERSION 0.0.0)
+
+bundle(modified_bool_benchmark SOURCES
+	../benchmark/public/src/benchmark_activator
+	private/src/modified_bool_benchmark 
+)
+
+include_directories(public/include)
+include_directories(../benchmark/public/include)
+include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/shell/public/include")
+target_link_libraries(modified_bool_benchmark celix_framework)
+

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/modified_bool_benchmark/private/src/modified_bool_benchmark.c
----------------------------------------------------------------------
diff --git a/examples/locking/modified_bool_benchmark/private/src/modified_bool_benchmark.c b/examples/locking/modified_bool_benchmark/private/src/modified_bool_benchmark.c
new file mode 100644
index 0000000..b482b2c
--- /dev/null
+++ b/examples/locking/modified_bool_benchmark/private/src/modified_bool_benchmark.c
@@ -0,0 +1,162 @@
+#include <stdlib.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <pthread.h>
+
+#include "array_list.h"
+
+#include "benchmark.h"
+#include "math_service.h"
+
+static const char * const BENCHMARK_NAME = "MODIFIED_BIT";
+static const double SAMPLE_FACTOR = 1;
+static const useconds_t SLEEP_TIME = 10;
+
+typedef struct thread_info {
+	benchmark_pt benchmark;
+	unsigned int result;
+	struct timeval begin;
+	struct timeval end;
+	int skips;
+	bool isModified;
+    bool isUpdated;
+} thread_info_t;
+
+struct benchmark {
+    pthread_mutex_t mutex;
+    math_service_pt math;
+    int nrOfSamples;
+    int nrOfThreads;
+    thread_info_t *threads;
+};
+
+static void benchmark_thread(thread_info_t *info);
+
+celix_status_t benchmark_create(benchmark_pt *benchmark) {
+	(*benchmark) = malloc(sizeof(struct benchmark));
+	(*benchmark)->math = NULL;
+	pthread_mutex_init(&(*benchmark)->mutex, NULL);
+    return CELIX_SUCCESS;
+}
+
+celix_status_t benchmark_destroy(benchmark_pt benchmark) {
+    //free threads array
+	free(benchmark);
+    return CELIX_SUCCESS;
+}
+
+benchmark_result_t benchmark_run(benchmark_pt benchmark, int nrOfThreads, int nrOfSamples) {
+	int i;
+	pthread_t threads[nrOfThreads];
+	thread_info_t infos[nrOfThreads];
+	benchmark_result_t result;
+	unsigned long elapsedTime = 0;
+
+	benchmark->threads = infos;
+	benchmark->nrOfSamples = nrOfSamples;
+    benchmark->nrOfThreads = nrOfThreads;
+
+	result.skips =0;
+    pthread_mutex_lock(&benchmark->mutex);
+	for (i = 0 ; i < nrOfThreads ; i += 1) {
+		infos[i].benchmark = benchmark;
+		infos[i].skips = 0;
+		infos[i].result = rand();
+		infos[i].isUpdated = false;
+		infos[i].isModified = false;
+		pthread_create(&threads[i], NULL, (void *)benchmark_thread,  &infos[i]);
+	}
+    pthread_mutex_unlock(&benchmark->mutex);
+
+	for (i = 0; i < nrOfThreads ; i += 1) {
+		pthread_join(threads[i], NULL);
+		elapsedTime += ((infos[i].end.tv_sec - infos[i].begin.tv_sec) * 1000000) + (infos[i].end.tv_usec - infos[i].begin.tv_usec);
+		result.skips += infos[i].skips;
+	}
+
+	result.averageCallTimeInNanoseconds = ((double)elapsedTime * 1000) / (nrOfSamples * nrOfThreads);
+	result.callFrequencyInMhz = ((double)(nrOfSamples * nrOfThreads) / elapsedTime);
+	result.nrOfThreads = nrOfThreads;
+	result.nrOfsamples = nrOfSamples;
+
+	return result;
+}
+
+static void benchmark_thread(thread_info_t *info) {
+	int i = 0;
+
+    math_service_pt local = info->benchmark->math;
+	int nrOfSamples = info->benchmark->nrOfSamples;
+	
+	gettimeofday(&info->begin, NULL);
+	while (i < nrOfSamples) {
+		if (!info->isModified) {
+            if (local != NULL) {
+                info->result = local->calc(local->handle, info->result, i);
+            } else {
+                info->skips += 1; //should not happen
+            }
+            i += 1;
+        } else {
+			local = info->benchmark->math;
+			info->isModified = false;
+		}
+	}
+	gettimeofday(&info->end, NULL);
+
+}
+
+char * benchmark_getName(benchmark_pt benchmark) {
+	return (char *)BENCHMARK_NAME;
+}
+
+celix_status_t benchmark_addMathService(benchmark_pt benchmark, math_service_pt mathService) {
+	int i;
+
+	pthread_mutex_lock(&benchmark->mutex);
+	benchmark->math = mathService;
+	pthread_mutex_unlock(&benchmark->mutex);
+
+	//inform threads to update servicd
+	for (i = 0 ; i < benchmark->nrOfSamples ; i += 1) {
+		benchmark->threads[i].isModified = true;
+	}	
+
+	//Wait till al thread are not in a modified state, e.g. update to date mathService and not using the old service
+	for (i = 0; i < benchmark->nrOfThreads ; i += 1) {
+		if (benchmark->threads[i].isModified) {
+			usleep(SLEEP_TIME);
+		}
+	}
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t benchmark_removeMathService(benchmark_pt benchmark, math_service_pt mathService) {
+	pthread_mutex_lock(&benchmark->mutex);
+	if (benchmark->math == mathService) {
+		benchmark->math = NULL;
+	} 
+	pthread_mutex_unlock(&benchmark->mutex);
+
+	//inform threads to update servicd
+    int i;
+	for (i = 0 ; i < benchmark->nrOfThreads ; i += 1) {
+		benchmark->threads[i].isModified = true;
+	}	
+
+	//Wait till al thread are not in a modified state, e.g. update to date mathService and not using the old service
+	for (i = 0; i < benchmark->nrOfThreads ; i += 1) {
+		if (benchmark->threads[i].isModified) {
+			usleep(SLEEP_TIME);
+		}
+	}
+
+	
+	return CELIX_SUCCESS;
+}
+
+double benchmark_getSampleFactor(benchmark_pt benchmark) {
+	return SAMPLE_FACTOR;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/mutex_benchmark/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/mutex_benchmark/CMakeLists.txt b/examples/locking/mutex_benchmark/CMakeLists.txt
new file mode 100644
index 0000000..b822ffa
--- /dev/null
+++ b/examples/locking/mutex_benchmark/CMakeLists.txt
@@ -0,0 +1,32 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+SET(BUNDLE_SYMBOLICNAME mutex_benchmark)
+SET(BUNDLE_VERSION 0.0.0)
+
+bundle(mutex_benchmark SOURCES
+	../benchmark/public/src/benchmark_activator
+	private/src/mutex_benchmark 
+)
+
+include_directories(public/include)
+include_directories(../benchmark/public/include)
+include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/shell/public/include")
+target_link_libraries(mutex_benchmark celix_framework)
+

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/mutex_benchmark/private/src/mutex_benchmark.c
----------------------------------------------------------------------
diff --git a/examples/locking/mutex_benchmark/private/src/mutex_benchmark.c b/examples/locking/mutex_benchmark/private/src/mutex_benchmark.c
new file mode 100644
index 0000000..3cacfb8
--- /dev/null
+++ b/examples/locking/mutex_benchmark/private/src/mutex_benchmark.c
@@ -0,0 +1,117 @@
+/*
+ * mutex_benchmark.c
+ *
+ *  Created on: Feb 13, 2014
+ *      Author: dl436
+ */
+
+#include <stdlib.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include "benchmark.h"
+
+static const char * const BENCHMARK_NAME = "MUTEX";
+static const double SAMPLE_FACTOR = 1;
+
+struct benchmark {
+	pthread_mutex_t mutex;
+	math_service_pt math;
+};
+
+typedef struct thread_info {
+	benchmark_pt benchmark;
+	int nrOfSamples;
+	unsigned int result;
+	struct timeval begin;
+	struct timeval end;
+	int skips;
+} thread_info_t;
+
+static void benchmark_thread(thread_info_t *info);
+
+celix_status_t benchmark_create(benchmark_pt *benchmark) {
+	(*benchmark) = malloc(sizeof(struct benchmark));
+	(*benchmark)->math = NULL;
+	pthread_mutex_init(&(*benchmark)->mutex, NULL);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t benchmark_destroy(benchmark_pt benchmark) {
+	free(benchmark);
+	return CELIX_SUCCESS;
+}
+
+benchmark_result_t benchmark_run(benchmark_pt benchmark, int nrOfThreads, int nrOfSamples) {
+	int i;
+	pthread_t threads[nrOfThreads];
+	thread_info_t infos[nrOfThreads];
+	benchmark_result_t result;
+	unsigned long elapsedTime = 0;
+
+	result.skips =0;
+
+	for (i = 0 ; i < nrOfThreads ; i += 1) {
+		infos[i].benchmark = benchmark;
+		infos[i].nrOfSamples = nrOfSamples;
+		infos[i].skips = 0;
+		infos[i].result = rand();
+		pthread_create(&threads[i], NULL, (void *)benchmark_thread,  &infos[i]);
+	}
+
+	for (i = 0; i < nrOfThreads ; i += 1) {
+		pthread_join(threads[i], NULL);
+		elapsedTime += ((infos[i].end.tv_sec - infos[i].begin.tv_sec) * 1000000) + (infos[i].end.tv_usec - infos[i].begin.tv_usec);
+		result.skips += infos[i].skips;
+	}
+
+	result.averageCallTimeInNanoseconds = ((double)elapsedTime * 1000) / (nrOfSamples * nrOfThreads);
+	result.callFrequencyInMhz = ((double)(nrOfSamples * nrOfThreads) / elapsedTime);
+	result.nrOfThreads = nrOfThreads;
+	result.nrOfsamples = nrOfSamples;
+
+	return result;
+}
+
+static void benchmark_thread(thread_info_t *info) {
+	int i;
+
+	gettimeofday(&info->begin, NULL);
+	for (i = 0; i < info->nrOfSamples; i += 1) {
+		pthread_mutex_lock(&info->benchmark->mutex);
+		if (info->benchmark->math != NULL) {
+			info->result = info->benchmark->math->calc(info->benchmark->math->handle, info->result, i);
+		} else {
+			info->skips += 1; //should not happen
+		}
+		pthread_mutex_unlock(&info->benchmark->mutex);
+	}
+	gettimeofday(&info->end, NULL);
+
+}
+
+char * benchmark_getName(benchmark_pt benchmark) {
+	return (char *)BENCHMARK_NAME;
+}
+
+celix_status_t benchmark_addMathService(benchmark_pt benchmark, math_service_pt mathService) {
+	pthread_mutex_lock(&benchmark->mutex);
+	benchmark->math = mathService;
+	pthread_mutex_unlock(&benchmark->mutex);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t benchmark_removeMathService(benchmark_pt benchmark, math_service_pt mathService) {
+	pthread_mutex_lock(&benchmark->mutex);
+	if (benchmark->math == mathService) {
+		benchmark->math = NULL;
+	}
+	pthread_mutex_unlock(&benchmark->mutex);
+	return CELIX_SUCCESS;
+
+}
+
+double benchmark_getSampleFactor(benchmark_pt benchmark) {
+	return SAMPLE_FACTOR;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/reference_benchmark/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/reference_benchmark/CMakeLists.txt b/examples/locking/reference_benchmark/CMakeLists.txt
new file mode 100644
index 0000000..592bb9c
--- /dev/null
+++ b/examples/locking/reference_benchmark/CMakeLists.txt
@@ -0,0 +1,32 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+SET(BUNDLE_SYMBOLICNAME reference_benchmark)
+SET(BUNDLE_VERSION 0.0.0)
+
+bundle(reference_benchmark SOURCES
+	../benchmark/public/src/benchmark_activator
+	private/src/reference_benchmark 
+)
+
+include_directories(public/include)
+include_directories(../benchmark/public/include)
+include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/shell/public/include")
+target_link_libraries(reference_benchmark celix_framework)
+

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/reference_benchmark/private/src/reference_benchmark.c
----------------------------------------------------------------------
diff --git a/examples/locking/reference_benchmark/private/src/reference_benchmark.c b/examples/locking/reference_benchmark/private/src/reference_benchmark.c
new file mode 100644
index 0000000..f4bb93f
--- /dev/null
+++ b/examples/locking/reference_benchmark/private/src/reference_benchmark.c
@@ -0,0 +1,116 @@
+/*
+ * mutex_benchmark.c
+ *
+ *  Created on: Feb 13, 2014
+ *      Author: dl436
+ */
+
+#include <stdlib.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include "benchmark.h"
+
+static const char * const BENCHMARK_NAME = "REFERENCE";
+static const double SAMPLE_FACTOR = 100;
+
+typedef struct thread_info {
+	benchmark_pt benchmark;
+	int nrOfSamples;
+	unsigned int result;
+	struct timeval begin;
+	struct timeval end;
+	int skips;
+} thread_info_t;
+
+static void benchmark_thread(thread_info_t *info);
+static int benchmark_calc(int arg1, int arg2);
+
+celix_status_t benchmark_create(benchmark_pt *benchmark) {
+	//do nothing
+	return CELIX_SUCCESS;
+}
+
+celix_status_t benchmark_destroy(benchmark_pt benchmark) {
+	//do nothing
+	return CELIX_SUCCESS;
+}
+
+benchmark_result_t benchmark_run(benchmark_pt benchmark, int nrOfThreads, int nrOfSamples) {
+	int i;
+	pthread_t threads[nrOfThreads];
+	thread_info_t infos[nrOfThreads];
+	benchmark_result_t result;
+	unsigned long elapsedTime = 0;
+
+	result.skips =0;
+
+	for (i = 0 ; i < nrOfThreads ; i += 1) {
+		infos[i].benchmark = benchmark;
+		infos[i].nrOfSamples = nrOfSamples;
+		infos[i].skips = 0;
+		infos[i].result = rand();
+		pthread_create(&threads[i], NULL, (void *)benchmark_thread,  &infos[i]);
+	}
+
+	for (i = 0; i < nrOfThreads ; i += 1) {
+		pthread_join(threads[i], NULL);
+		elapsedTime += ((infos[i].end.tv_sec - infos[i].begin.tv_sec) * 1000000) + (infos[i].end.tv_usec - infos[i].begin.tv_usec);
+		result.skips += infos[i].skips;
+	}
+
+	result.averageCallTimeInNanoseconds = elapsedTime;
+	result.averageCallTimeInNanoseconds *= 1000;
+	result.averageCallTimeInNanoseconds /= nrOfSamples;
+	result.averageCallTimeInNanoseconds /= nrOfThreads;
+	result.callFrequencyInMhz = ((double)(nrOfSamples * nrOfThreads) / elapsedTime);
+	result.nrOfThreads = nrOfThreads;
+	result.nrOfsamples = nrOfSamples;
+
+	return result;
+}
+
+static void benchmark_thread(thread_info_t *info) {
+	int i;
+
+	int result = info->result;
+	struct timeval *begin = &info->begin;
+	struct timeval *end = &info->end;
+	int nrOFSamples = info->nrOfSamples;
+
+
+	gettimeofday(begin, NULL);
+	for (i = 0; i < nrOFSamples; i += 1) {
+		result = benchmark_calc(result, i);
+	}
+	gettimeofday(end, NULL);
+
+	info->result = result;
+}
+
+char * benchmark_getName(benchmark_pt benchmark) {
+	return (char *)BENCHMARK_NAME;
+}
+
+celix_status_t benchmark_addMathService(benchmark_pt benchmark, math_service_pt mathService) {
+	//ignore service is not used
+	return CELIX_SUCCESS;
+}
+
+celix_status_t benchmark_removeMathService(benchmark_pt benchmark, math_service_pt mathService) {
+	//ignore service is not used
+	return CELIX_SUCCESS;
+
+}
+
+/*
+ * Same implementation as the math_service. This function is used a reference.
+ */
+static int benchmark_calc(int arg1, int arg2) {
+	return  arg1 * arg2 + arg2;
+}
+
+double benchmark_getSampleFactor(benchmark_pt benchmark) {
+	return SAMPLE_FACTOR;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/start_stop_benchmark/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/locking/start_stop_benchmark/CMakeLists.txt b/examples/locking/start_stop_benchmark/CMakeLists.txt
new file mode 100644
index 0000000..bca651e
--- /dev/null
+++ b/examples/locking/start_stop_benchmark/CMakeLists.txt
@@ -0,0 +1,32 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+SET(BUNDLE_SYMBOLICNAME stop_benchmark)
+SET(BUNDLE_VERSION 0.0.0)
+
+bundle(start_stop_benchmark SOURCES
+	../benchmark/public/src/benchmark_activator
+	private/src/start_stop_benchmark 
+)
+
+include_directories(public/include)
+include_directories(../benchmark/public/include)
+include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/shell/public/include")
+target_link_libraries(start_stop_benchmark celix_framework)
+

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/examples/locking/start_stop_benchmark/private/src/start_stop_benchmark.c
----------------------------------------------------------------------
diff --git a/examples/locking/start_stop_benchmark/private/src/start_stop_benchmark.c b/examples/locking/start_stop_benchmark/private/src/start_stop_benchmark.c
new file mode 100644
index 0000000..1d445c5
--- /dev/null
+++ b/examples/locking/start_stop_benchmark/private/src/start_stop_benchmark.c
@@ -0,0 +1,189 @@
+/*
+ * mutex_benchmark.c
+ *
+ *  Created on: Feb 13, 2014
+ *      Author: dl436
+ */
+
+#include <stdlib.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <stdio.h>
+
+#include "benchmark.h"
+
+static const char * const BENCHMARK_NAME = "INTR_CONT";
+static const double SAMPLE_FACTOR = 100;
+static const __useconds_t WAIT_TIME = 1; //100 * 1000;
+
+typedef enum benchmark_state {
+	BENCHMARK_STATE_INTERRUPTED,
+	BENCHMARK_STATE_RUNNING
+} benchmark_state_t;
+
+struct benchmark {
+	int nrOfThreads;
+	pthread_mutex_t mutex; //write protect for state
+	math_service_pt math;
+	benchmark_state_t state;
+	int threadsRunning;
+};
+
+typedef struct thread_info {
+	benchmark_pt benchmark;
+	int nrOfSamples;
+	unsigned int result;
+	struct timeval begin;
+	struct timeval end;
+	int skips;
+} thread_info_t;
+
+static void benchmark_thread(thread_info_t *info);
+static void benchmark_runSamples(thread_info_t *info, int *i, volatile benchmark_state_t *state);
+static void benchmark_interrupt(benchmark_pt benchmark);
+static void benchmark_continue(benchmark_pt benchmark);
+
+celix_status_t benchmark_create(benchmark_pt *benchmark) {
+	(*benchmark) = malloc(sizeof(struct benchmark));
+	(*benchmark)->math = NULL;
+	(*benchmark)->state = BENCHMARK_STATE_INTERRUPTED;
+	(*benchmark)->nrOfThreads = 0;
+	(*benchmark)->threadsRunning = 0;
+
+	pthread_mutex_init(&(*benchmark)->mutex, NULL);
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t benchmark_destroy(benchmark_pt benchmark) {
+	free(benchmark);
+
+	return CELIX_SUCCESS;
+}
+
+benchmark_result_t benchmark_run(benchmark_pt benchmark, int nrOfThreads, int nrOfSamples) {
+	int i;
+	pthread_t threads[nrOfThreads];
+	thread_info_t infos[nrOfThreads];
+	int isThreadRunning[nrOfThreads];
+	benchmark_result_t result;
+	unsigned long elapsedTime = 0;
+	result.skips =0;
+
+	for (i = 0 ; i < nrOfThreads ; i += 1) {
+		infos[i].benchmark = benchmark;
+		infos[i].nrOfSamples = nrOfSamples;
+		infos[i].skips = 0;
+		infos[i].result = rand();
+		pthread_create(&threads[i], NULL, (void *)benchmark_thread,  &infos[i]);
+	}
+
+	benchmark->nrOfThreads = nrOfThreads;
+
+	for (i = 0; i < nrOfThreads ; i += 1) {
+		pthread_join(threads[i], NULL);
+		elapsedTime += ((infos[i].end.tv_sec - infos[i].begin.tv_sec) * 1000000) + (infos[i].end.tv_usec - infos[i].begin.tv_usec);
+		result.skips += infos[i].skips;
+	}
+
+	benchmark->nrOfThreads = 0;
+
+	result.averageCallTimeInNanoseconds = elapsedTime;
+	result.averageCallTimeInNanoseconds *= 1000;
+	result.averageCallTimeInNanoseconds /= nrOfSamples;
+	result.averageCallTimeInNanoseconds /= nrOfThreads;
+	result.callFrequencyInMhz = ((double)(nrOfSamples * nrOfThreads) / elapsedTime);
+	result.nrOfThreads = nrOfThreads;
+	result.nrOfsamples = nrOfSamples;
+
+	return result;
+}
+
+static void benchmark_thread(thread_info_t *info) {
+	int i = 0;
+
+	gettimeofday(&info->begin, NULL);
+	while (i < info->nrOfSamples) {
+		if (info->benchmark->state == BENCHMARK_STATE_RUNNING ) {
+			//TODO race condition?? or not because of the mutex on changing the state
+			__sync_add_and_fetch(&info->benchmark->threadsRunning, 1);
+			benchmark_runSamples(info, &i, &info->benchmark->state);
+			__sync_sub_and_fetch(&info->benchmark->threadsRunning, 1);
+		} else {
+			usleep(WAIT_TIME);
+		}
+	}
+	gettimeofday(&info->end, NULL);
+
+}
+
+static void benchmark_runSamples(thread_info_t *info, int *i, volatile benchmark_state_t *state) {
+	int nrOfSamples = info->nrOfSamples;
+	unsigned int result = info->result;
+	math_service_pt math = info->benchmark->math;
+
+	for (; *i < nrOfSamples && *state == BENCHMARK_STATE_RUNNING; *i += 1) {
+		result = math->calc(math->handle, result, *i);
+	}
+
+	info->result = result;
+}
+
+char * benchmark_getName(benchmark_pt benchmark) {
+	return (char *)BENCHMARK_NAME;
+}
+
+static void benchmark_continue(benchmark_pt benchmark) {
+	benchmark->state = BENCHMARK_STATE_RUNNING;
+	unsigned long waitTime = 0;
+	while (benchmark->threadsRunning < benchmark->nrOfThreads) {
+		usleep(WAIT_TIME);
+		waitTime += WAIT_TIME;
+		if (waitTime > 1000 * 1000 * 2) {
+			printf("still waiting to stop, running threads are %i\n",
+					benchmark->threadsRunning);
+		}
+	}
+}
+
+static void benchmark_interrupt(benchmark_pt benchmark) {
+	int i = 0;
+	unsigned long waitTime = 0;
+	if (benchmark->state == BENCHMARK_STATE_RUNNING) {
+		benchmark->state = BENCHMARK_STATE_INTERRUPTED;
+		while (benchmark->threadsRunning > 0) {
+			usleep(WAIT_TIME);
+			waitTime += WAIT_TIME;
+			if (waitTime > 1000 * 1000 * 2) {
+				printf("still waiting to stop, running threads are %i\n",
+						benchmark->threadsRunning);
+			}
+		}
+	}
+}
+
+celix_status_t benchmark_addMathService(benchmark_pt benchmark, math_service_pt mathService) {
+	pthread_mutex_lock(&benchmark->mutex);
+	benchmark_interrupt(benchmark);
+	benchmark->math = mathService;
+	benchmark_continue(benchmark);
+	pthread_mutex_unlock(&benchmark->mutex);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t benchmark_removeMathService(benchmark_pt benchmark, math_service_pt mathService) {
+	pthread_mutex_lock(&benchmark->mutex);
+	if (benchmark->math == mathService) {
+		benchmark_interrupt(benchmark);
+		benchmark->math = NULL;
+		benchmark_continue(benchmark);
+	}
+	pthread_mutex_unlock(&benchmark->mutex);
+	return CELIX_SUCCESS;
+
+}
+
+double benchmark_getSampleFactor(benchmark_pt benchmark) {
+	return SAMPLE_FACTOR;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/framework/private/include/service_reference_private.h
----------------------------------------------------------------------
diff --git a/framework/private/include/service_reference_private.h b/framework/private/include/service_reference_private.h
index b297c14..114eae1 100644
--- a/framework/private/include/service_reference_private.h
+++ b/framework/private/include/service_reference_private.h
@@ -33,12 +33,17 @@
 struct serviceReference {
 	bundle_pt bundle;
 	struct serviceRegistration * registration;
+
+	size_t refCount;
+    celix_thread_mutex_t mutex; //protects refCount
 };
 
 celix_status_t serviceReference_create(bundle_pt bundle, service_registration_pt registration, service_reference_pt *reference);
-celix_status_t serviceReference_destroy(service_reference_pt *reference);
+
+void serviceReference_retain(service_reference_pt ref);
+void serviceReference_release(service_reference_pt ref);
 
 celix_status_t serviceReference_invalidate(service_reference_pt reference);
-celix_status_t serviceRefernce_isValid(service_reference_pt reference, bool *result);
+celix_status_t serviceReference_isValid(service_reference_pt reference, bool *result);
 
 #endif /* SERVICE_REFERENCE_PRIVATE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/framework/private/include/service_registration_private.h
----------------------------------------------------------------------
diff --git a/framework/private/include/service_registration_private.h b/framework/private/include/service_registration_private.h
index 8f31a14..081f996 100644
--- a/framework/private/include/service_registration_private.h
+++ b/framework/private/include/service_registration_private.h
@@ -51,11 +51,15 @@ struct serviceRegistration {
 
 	struct service *services;
 	int nrOfServices;
+
+	size_t refCount; //protected by mutex
 };
 
 service_registration_pt serviceRegistration_create(service_registry_pt registry, bundle_pt bundle, char * serviceName, long serviceId, void * serviceObject, properties_pt dictionary);
 service_registration_pt serviceRegistration_createServiceFactory(service_registry_pt registry, bundle_pt bundle, char * serviceName, long serviceId, void * serviceObject, properties_pt dictionary);
-celix_status_t serviceRegistration_destroy(service_registration_pt registration);
+
+void serviceRegistration_retain(service_registration_pt registration);
+void serviceRegistration_release(service_registration_pt registration);
 
 bool serviceRegistration_isValid(service_registration_pt registration);
 void serviceRegistration_invalidate(service_registration_pt registration);

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/framework/private/include/service_registry_private.h
----------------------------------------------------------------------
diff --git a/framework/private/include/service_registry_private.h b/framework/private/include/service_registry_private.h
index 7bda186..d89f28e 100644
--- a/framework/private/include/service_registry_private.h
+++ b/framework/private/include/service_registry_private.h
@@ -50,6 +50,7 @@ struct usageCount {
 	unsigned int count;
 	service_reference_pt reference;
 	void * service;
+	service_registration_pt registration;
 };
 
 typedef struct usageCount * usage_count_pt;

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/framework/private/src/properties.c
----------------------------------------------------------------------
diff --git a/framework/private/src/properties.c b/framework/private/src/properties.c
index 14455c4..271eed1 100644
--- a/framework/private/src/properties.c
+++ b/framework/private/src/properties.c
@@ -180,6 +180,28 @@ void properties_store(properties_pt properties, char * filename, char * header)
 	}
 }
 
+celix_status_t properties_copy(properties_pt properties, properties_pt *out) {
+	celix_status_t status = CELIX_SUCCESS;
+	properties_pt copy = properties_create();
+
+	if (copy != NULL) {
+		hash_map_iterator_pt iter = hashMapIterator_create(properties);
+		while (hashMapIterator_hasNext(iter)) {
+			hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+			char *key = hashMapEntry_getKey(entry);
+			char *value = hashMapEntry_getValue(entry);
+			properties_set(copy, key, value);
+		}
+		hashMapIterator_destroy(iter);
+	} else {
+		status = CELIX_ENOMEM;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		*out = copy;
+	}
+}
+
 char * properties_get(properties_pt properties, char * key) {
 	return hashMap_get(properties, key);
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/e0231e51/framework/private/src/service_reference.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_reference.c b/framework/private/src/service_reference.c
index 528b4be..24fdc99 100644
--- a/framework/private/src/service_reference.c
+++ b/framework/private/src/service_reference.c
@@ -28,6 +28,7 @@
 #include <constants.h>
 #include <stdint.h>
 #include <utils.h>
+#include <assert.h>
 
 #include "service_reference.h"
 
@@ -39,29 +40,53 @@
 #include "bundle.h"
 #include "celix_log.h"
 
-celix_status_t serviceReference_create(bundle_pt bundle, service_registration_pt registration, service_reference_pt *reference) {
+static void serviceReference_destroy(service_reference_pt);
+
+celix_status_t serviceReference_create(bundle_pt bundle, service_registration_pt registration, service_reference_pt *out) {
 	celix_status_t status = CELIX_SUCCESS;
 
-	*reference = malloc(sizeof(**reference));
-	if (!*reference) {
+	service_reference_pt ref = calloc(1, sizeof(*ref));
+	if (!ref) {
 		status = CELIX_ENOMEM;
 	} else {
-
-		(*reference)->bundle = bundle;
-		(*reference)->registration = registration;
+		ref->bundle = bundle;
+		ref->registration = registration;
+		celixThreadMutex_create(&ref->mutex, NULL);
+		ref->refCount = 1;
 	}
 
-	framework_logIfError(logger, status, NULL, "Cannot create service reference");
+	if (status == CELIX_SUCCESS) {
+		*out = ref;
+	} else {
+		framework_logIfError(logger, status, NULL, "Cannot create service reference");
+	}
 
 	return status;
 }
 
-celix_status_t serviceReference_destroy(service_reference_pt *reference) {
-	(*reference)->bundle = NULL;
-	(*reference)->registration = NULL;
-	free(*reference);
-	*reference = NULL;
-	return CELIX_SUCCESS;
+void serviceReference_retain(service_reference_pt ref) {
+    celixThreadMutex_lock(&ref->mutex);
+    ref->refCount += 1;
+    celixThreadMutex_unlock(&ref->mutex);
+}
+
+void serviceReference_release(service_reference_pt ref) {
+    celixThreadMutex_lock(&ref->mutex);
+    assert(ref->refCount > 0);
+    ref->refCount -= 1;
+    if (ref->refCount == 0) {
+        serviceReference_destroy(ref);
+    } else {
+        celixThreadMutex_unlock(&ref->mutex);
+    }
+}
+
+static void serviceReference_destroy(service_reference_pt ref) {
+	assert(ref->refCount == 0);
+    celixThreadMutex_destroy(&ref->mutex);
+	ref->bundle = NULL;
+	ref->registration = NULL;
+	free(ref);
 }
 
 celix_status_t serviceReference_getBundle(service_reference_pt reference, bundle_pt *bundle) {
@@ -109,7 +134,7 @@ celix_status_t serviceReference_invalidate(service_reference_pt reference) {
 	return CELIX_SUCCESS;
 }
 
-celix_status_t serviceRefernce_isValid(service_reference_pt reference, bool *result) {
+celix_status_t serviceReference_isValid(service_reference_pt reference, bool *result) {
 	(*result) = reference->registration != NULL;
 	return CELIX_SUCCESS;
 }
@@ -117,22 +142,8 @@ celix_status_t serviceRefernce_isValid(service_reference_pt reference, bool *res
 bool serviceReference_isAssignableTo(service_reference_pt reference, bundle_pt requester, char * serviceName) {
 	bool allow = true;
 
-	bundle_pt provider = reference->bundle;
-	if (requester == provider) {
-		return allow;
-	}
-//	wire_pt providerWire = module_getWire(bundle_getCurrentModule(provider), serviceName);
-//	wire_pt requesterWire = module_getWire(bundle_getCurrentModule(requester), serviceName);
-//
-//	if (providerWire == NULL && requesterWire != NULL) {
-//		allow = (bundle_getCurrentModule(provider) == wire_getExporter(requesterWire));
-//	} else if (providerWire != NULL && requesterWire != NULL) {
-//		allow = (wire_getExporter(providerWire) == wire_getExporter(requesterWire));
-//	} else if (providerWire != NULL && requesterWire == NULL) {
-//		allow = (wire_getExporter(providerWire) == bundle_getCurrentModule(requester));
-//	} else {
-//		allow = false;
-//	}
+	/*NOTE for now always true. It would be nice to be able to do somechecks if the services are really assignable.
+	 */
 
 	return allow;
 }


Mime
View raw message