diff options
author | Chris Sherlock <chris.sherlock79@gmail.com> | 2017-08-26 23:22:01 +1000 |
---|---|---|
committer | Chris Sherlock <chris.sherlock79@gmail.com> | 2017-09-02 15:06:01 +1000 |
commit | b05c58dadce72fa07f63aa35672f3a00f5ae7d5f (patch) | |
tree | aadf8e5f8ce92d765ea634f333da41fb1754705e | |
parent | 746a5f42c41252481b75d0e83ca182b100c23a5d (diff) |
sal workbench: added monitor - demonstrates mutex, cond vars and threads
Change-Id: Ia61653d5b10f96150df2bacc336b6961a0922c71
-rw-r--r-- | Repository.mk | 1 | ||||
-rw-r--r-- | sal/Executable_monitor.mk | 31 | ||||
-rw-r--r-- | sal/Module_sal.mk | 1 | ||||
-rw-r--r-- | sal/workben/osl/monitor.cxx | 140 |
4 files changed, 173 insertions, 0 deletions
diff --git a/Repository.mk b/Repository.mk index 3dc4e9c772d8..2ab6ac0f7518 100644 --- a/Repository.mk +++ b/Repository.mk @@ -90,6 +90,7 @@ $(eval $(call gb_Helper_register_executables,NONE, \ terminateprocess \ setgetenv \ signal \ + monitor \ )) $(eval $(call gb_Helper_register_executables_for_install,SDK,sdk, \ diff --git a/sal/Executable_monitor.mk b/sal/Executable_monitor.mk new file mode 100644 index 000000000000..23b22bede8c6 --- /dev/null +++ b/sal/Executable_monitor.mk @@ -0,0 +1,31 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_Executable_Executable,monitor)) + +$(eval $(call gb_Executable_set_include,monitor,\ + $$(INCLUDE) \ + -I$(SRCDIR)/sal/inc \ +)) + +$(eval $(call gb_Library_add_defs,monitor,\ + -DSAL_DLLIMPLEMENTATION \ +)) + +$(eval $(call gb_Executable_use_libraries,monitor,\ + sal \ +)) + +$(eval $(call gb_Executable_add_exception_objects,monitor,\ + sal/workben/osl/monitor \ +)) + +$(call gb_Executable_get_clean_target,monitor) : + rm -f $(WORKDIR)/LinkTarget/Executable/monitor +# vim: set ts=4 sw=4 et: diff --git a/sal/Module_sal.mk b/sal/Module_sal.mk index 32cb795cfb8c..8cecbd8d0068 100644 --- a/sal/Module_sal.mk +++ b/sal/Module_sal.mk @@ -32,6 +32,7 @@ $(eval $(call gb_Module_add_targets,sal,\ Executable_terminateprocess \ Executable_setgetenv \ Executable_signal \ + Executable_monitor \ )) $(eval $(call gb_Module_add_check_targets,sal,\ diff --git a/sal/workben/osl/monitor.cxx b/sal/workben/osl/monitor.cxx new file mode 100644 index 000000000000..8060883b67f7 --- /dev/null +++ b/sal/workben/osl/monitor.cxx @@ -0,0 +1,140 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include <sal/main.h> +#include <osl/mutex.h> +#include <osl/conditn.h> +#include <osl/thread.h> + +#include <cstdio> +#include <cassert> + +#define BUFFER_SIZE 10 + +bool queue[9]; +sal_uInt32 nItemCount = 0; + +oslCondition fullOrEmpty; +oslMutex queueMutex; +oslThread producer, consumer; + +void add(); +void remove(); + +void produce(void*); +void consume(void*); + +SAL_IMPLEMENT_MAIN() +{ + fprintf(stdout, "Producer/consumer problem - demonstrates mutex, condition variables and threads.\n"); + + queueMutex = osl_createMutex(); + fullOrEmpty = osl_createCondition(); + + while(true) + { + producer = osl_createThread(produce, nullptr); + consumer = osl_createThread(consume, nullptr); + + osl_joinWithThread(consumer); + } + + return 0; +} + +void produce(void* /* pData */) +{ + osl_setThreadName("producer"); + + while(true) + { + /* producer monitor - first acquire exclusive access to + the queue, if the queue is full then wait till there + is space made available. Once the queue is no longer + full, then notify that this is the case. + */ + osl_acquireMutex(queueMutex); + + while (nItemCount == BUFFER_SIZE-1) + osl_waitCondition(fullOrEmpty, nullptr); + + fprintf(stdout, "produce()\n"); + + add(); + + osl_setCondition(fullOrEmpty); + osl_releaseMutex(queueMutex); + + osl_yieldThread(); + } + + fprintf(stderr, "exit produce()!\n"); +} + +void consume(void* /* pData */) +{ + osl_setThreadName("consumer"); + + while(true) + { + /* consumer monitor - first acquire exclusive access to the + queue, if the queue is empty then wait till something is + produced. Once the queue is no longer empty, then notify + that this is the case. + */ + osl_acquireMutex(queueMutex); + + while (nItemCount == 0) + osl_waitCondition(fullOrEmpty, nullptr); + + fprintf(stdout, "consume()\n"); + + remove(); + + osl_setCondition(fullOrEmpty); + osl_releaseMutex(queueMutex); + + osl_yieldThread(); + } + + fprintf(stderr, "exit consume()!\n"); +} + +void add() +{ + queue[nItemCount] = true; + + fprintf(stdout, "Adding to queue - item %d added.\n", nItemCount); + + nItemCount++; + assert(nItemCount <= BUFFER_SIZE-1); +} + +void remove() +{ + queue[nItemCount] = false; + + fprintf(stdout, "Removing from queue - item %d removed.\n", nItemCount); + + nItemCount--; + assert(nItemCount >= 0); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |