Commit 2cdbf260 authored by Erich Keane's avatar Erich Keane

Replace glib threadpool usage with a 'dumb' thread implementation.

We are attempting to remove glib as a necessity for the build, so this
patch replaces the glib threadpool implementation with a 'dumb' dispatch
thread model.

It renames u_threadpool with ca_threadpool to be more internally consistent
with naming conventions.

Finally, it removes all glib build dependencies for non-Tizen build scripts.

Change-Id: Icc64b758ae6c00ff426adda1c74d8f86e56a8fc5
Signed-off-by: default avatarErich Keane <erich.keane@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/747Tested-by: default avatarjenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: default avatarJoseph Morrow <joseph.l.morrow@intel.com>
Reviewed-by: default avatarSashi Penta <sashi.kumar.penta@intel.com>
parent ee8702ab
......@@ -48,7 +48,7 @@ target_arch = ARGUMENTS.get('TARGET_ARCH', default_arch) # target arch
# True if binary needs to be installed on board. (Might need root permissions)
# set to 'no', 'false' or 0 for only compilation
require_upload = ARGUMENTS.get('UPLOAD', False)
require_upload = ARGUMENTS.get('UPLOAD', False)
if ARGUMENTS.get('TEST'):
logging_default = False
......@@ -205,8 +205,8 @@ Export('env')
######################################################################
if target_os == "yocto":
'''
This code injects Yocto cross-compilation tools+flags into scons'
build environment in order to invoke the relevant tools while
This code injects Yocto cross-compilation tools+flags into scons'
build environment in order to invoke the relevant tools while
performing a build.
'''
import os.path
......@@ -244,7 +244,7 @@ if target_os == "yocto":
env['TARGET_OS'] = 'linux'
'''
We want to preserve debug symbols to allow BitBake to generate both DEBUG and
RELEASE packages for OIC.
RELEASE packages for OIC.
'''
env['CCFLAGS'].append('-g')
Export('env')
......@@ -258,15 +258,36 @@ else:
else:
env.SConscript(target_os + '/SConscript')
env.SConscript('external_libs.scons')
# Delete the temp files of configuration
if env.GetOption('clean'):
dir = env.get('SRC_DIR')
if os.path.exists(dir + '/config.log'):
Execute(Delete(dir + '/config.log'))
if os.path.exists(dir + '/.sconsign.dblite'):
Execute(Delete(dir + '/.sconsign.dblite'))
if os.path.exists(dir + '/.sconf_temp'):
Execute(Delete(dir + '/.sconf_temp'))
######################################################################
# Check for PThreads support
######################################################################
import iotivityconfig
from iotivityconfig import *
conf = Configure(env,
custom_tests =
{
'CheckPThreadsSupport' : iotivityconfig.check_pthreads
} )
# Identify whether we have pthreads support, which is necessary for
# threading and mutexes. This will set the environment variable
# POSIX_SUPPORTED, 1 if it is supported, 0 otherwise
conf.CheckPThreadsSupport()
env = conf.Finish()
######################################################################
env.SConscript('external_libs.scons')
Return('env')
......@@ -23,20 +23,6 @@ if not android_ndk:
'''
Exit(1)
# check 'glib' library
src_dir = env.get('SRC_DIR')
if not os.path.exists(src_dir + '/extlibs/glib/glib-2.40.2'):
print '''
*********************************** Error: **************************************
* Android glib library does not exist. please download gnome glib to *
* extlibs/glib directory *
* To build Android glib libraries please follow the instructions as below : *
* Download Gnome Glib from http://ftp.gnome.org/pub/GNOME/sources/glib/2.40/ *
* Please go through build instructions at : *
* resource/csdk/connectivity/lib/android/glibpatch_Readme.txt *
*********************************************************************************
'''
Exit(1)
# Overwrite suffixes and prefixes
if env['HOST_OS'] == 'win32':
env['OBJSUFFIX'] = '.o'
......@@ -196,11 +182,11 @@ env.AppendUnique(CCFLAGS = ['-Wall', '-fPIC'])
env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
env.AppendUnique(LIBPATH = [src_dir + '/resource/csdk/connectivity/lib/android'])
env.AppendUnique(LIBS = ['log', 'glib-2.40.2', 'gthread-2.40.2', 'coap'])
env.AppendUnique(LIBS = ['log', 'coap'])
if env.get('SECURED') == '1':
env.AppendUnique(LIBS = ['tinydtls'])
# From android-5 (API > 20), all application must be built with flags '-fPIE' '-pie'.
# Due to the limitation of Scons, it's required to added it into the command line
# directly (otherwise, it will also be added when build share library)
......
......@@ -39,8 +39,6 @@ else:
env.AppendUnique(CCFLAGS = ['-g'])
env.AppendUnique(LINKFLAGS = ['-g'])
env.ParseConfig("pkg-config glib-2.0 gthread-2.0 --cflags --libs")
if target_os == 'darwin':
sys_root = '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX' + sys_version + '.sdk/'
else:
......@@ -56,4 +54,4 @@ env.AppendUnique(LINKFLAGS = ['-arch', target_arch, '-isysroot', sys_root])
if target_os == 'darwin':
flag = '-mmacosx-version-min=' + sys_version
env.AppendUnique(CCFLAGS = [flag])
env.AppendUnique(LINKFLAGS = [flag])
\ No newline at end of file
env.AppendUnique(LINKFLAGS = [flag])
......@@ -94,3 +94,17 @@ def check_cxx11_flags(context):
_inform_user_of_broken_gcc_headers(context, ret)
return ret
def check_pthreads(context):
"""
Check if pthreads are supported for this platform.
Sets POSIX_SUPPORTED based on the result.
"""
context.Message('Checking for POSIX Thread Support...')
config = factory.make_c_compiler_config(context)
ret = config.has_pthreads_support()
context.env['POSIX_SUPPORTED'] = ret
context.Result(ret)
return ret
......@@ -65,6 +65,16 @@ class Configuration:
'.cpp',
'CXXFLAGS')
def has_pthreads_support(self):
"""
Check if PThreads are supported by this system
Returns 1 if this system DOES support pthreads, 0
otherwise
"""
return self._context.TryCompile(self._pthreads_test_program(), '.c')
# --------------------------------------------------------------
# Check if flag is required to build the given test program.
#
......@@ -148,3 +158,21 @@ class Configuration:
# --------------------------------------------------------------
def _cxx11_flags(self):
raise NotImplementedError('unimplemented method')
# --------------------------------------------------------------
# Return a test program to be used when checking for PThreads
# support
#
# --------------------------------------------------------------
def _pthreads_test_program(self):
return """
#include <unistd.h>
#include <pthread.h>
int main()
{
#ifndef _POSIX_THREADS
# error POSIX Threads support not available
#endif
return 0;
}
"""
......@@ -21,10 +21,9 @@ env.AppendUnique(CFLAGS = ['-std=c99'])
env.AppendUnique(CCFLAGS = ['-Wall', '-fPIC'])
env.AppendUnique(LINKFLAGS = ['-ldl', '-lpthread'])
env.ParseConfig("pkg-config glib-2.0 gthread-2.0 --cflags --libs")
if env.get('TARGET_OS') == 'tizen':
env.AppendUnique(CCFLAGS = ['-D__TIZEN__', '-DSLP_SDK_LOG', '-D_GNU_SOURCE', '-DTIZEN_DEBUG_ENABLE'])
env.ParseConfig("pkg-config glib-2.0 gthread-2.0 --cflags --libs")
env.ParseConfig("pkg-config dlog --cflags --libs")
# Set arch flags
......
......@@ -49,12 +49,11 @@ if target_os not in ['windows', 'winrt']:
examples_env.AppendUnique(LIBS = ['-lpthread'])
examples_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
examples_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap'])
examples_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction',
'coap', 'rt'])
if env.get('SECURED') == '1':
examples_env.AppendUnique(LIBS = ['tinydtls'])
examples_env.ParseConfig('pkg-config --libs glib-2.0');
if target_os == 'android':
examples_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
examples_env.AppendUnique(LIBS = ['gnustl_static'])
......
......@@ -30,6 +30,9 @@ Import('env')
target_os = env.get('TARGET_OS')
src_dir = env.get('SRC_DIR')
if target_os not in ['arduino', 'darwin', 'ios']:
env.AppendUnique(LIBS=['rt'])
# Build libcoap
SConscript('csdk/connectivity/lib/libcoap-4.1.1/SConscript')
......
......@@ -2,8 +2,7 @@ Compiling Interface APIs FOR Android:
===================================
•Preconditons :
Please download the following
1) glib directory and keep at $(CA_HOME)/lib/android/glib-2.40.2
2) tinydlts library and keep at $(CA_HOME)/lib/tinydtls
1) tinydlts library and keep at $(CA_HOME)/lib/tinydtls
•Supported version : 5.0 ( Lollipop )
•Required NDK version : android-ndk-r10d ( https://developer.android.com/tools/sdk/ndk/index.html )
• Modify Makefile ( connectivity/build/android/Makefile )
......
......@@ -23,19 +23,6 @@ if not android_ndk:
'''
Exit(1)
# check 'glib' library
src_dir = env.get('SRC_DIR')
if not os.path.exists(src_dir + '/../../../../extlibs/glib/glib-2.40.2'):
print '''
*********************************** Error: **************************************
* Android glib library does not exist. please download gnome glib to *
* extlibs/glib directory *
* To build Android glib libraries please follow the instructions as below : *
* Download Gnome Glib from http://ftp.gnome.org/pub/GNOME/sources/glib/2.40/ *
* Please go through build instructions at : *
* lib/android/glibpatch_Readme.txt *
*********************************************************************************
'''
# Overwrite suffixes and prefixes
if env['HOST_OS'] == 'win32':
env['OBJSUFFIX'] = '.o'
......@@ -185,7 +172,7 @@ env.AppendUnique(CCFLAGS = ['-Wall', '-fPIC'])
env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
env.AppendUnique(LIBPATH = [src_dir + '/lib/android'])
env.AppendUnique(LIBS = ['log', 'glib-2.40.2', 'gthread-2.40.2', 'coap'])
env.AppendUnique(LIBS = ['log', 'coap'])
if env.get('SECURED') == '1':
env.AppendUnique(LIBS = ['tinydtls'])
......
......@@ -95,7 +95,7 @@ RELEASE_DIR = ./release
##
## file declaration
##
COMPONENT_SRCS := logger.c oic_logger.c oic_console_logger.c oic_malloc.c oic_string.c uqueue.c uarraylist.c umutex.c uthreadpool.c
COMPONENT_SRCS := logger.c oic_logger.c oic_console_logger.c oic_malloc.c oic_string.c uqueue.c uarraylist.c umutex.c cathreadpool_pthreads.c
COMPONENT_SRCS += caretransmission.c
COMPONENT_SRCS += caconnectivitymanager.c caremotehandler.c cainterfacecontroller.c camessagehandler.c caqueueingthread.c canetworkconfigurator.c caprotocolmessage.c
COMPONENT_SRCS += caadapterutils.c
......
......@@ -20,8 +20,6 @@ env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '__linux__'])
env.AppendUnique(CCFLAGS = ['-Wall', '-fPIC'])
env.AppendUnique(LINKFLAGS = ['-ldl', '-lpthread'])
env.ParseConfig("pkg-config --cflags --libs glib-2.0 gthread-2.0")
# Set arch flags
target_arch = env.get('TARGET_ARCH')
if target_arch in ['x86']:
......
......@@ -44,7 +44,7 @@ cp -f %{ROOTDIR}/con/src/libconnectivity_abstraction.a %{buildroot}/%{_libdir}
cp -f %{ROOTDIR}/con/lib/libcoap-4.1.1/libcoap.a %{buildroot}/%{_libdir}
cp -rf %{ROOTDIR}/con/api/cacommon.h* %{DEST_INC_DIR}/
cp -rf %{ROOTDIR}/con/inc/caadapterinterface.h* %{DEST_INC_DIR}/
cp -rf %{ROOTDIR}/con/common/inc/uthreadpool.h* %{DEST_INC_DIR}/
cp -rf %{ROOTDIR}/con/common/inc/cathreadpool.h* %{DEST_INC_DIR}/
cp -rf %{ROOTDIR}/con/inc/cawifiadapter.h* %{DEST_INC_DIR}/
cp -rf %{ROOTDIR}/con/inc/caethernetadapter.h* %{DEST_INC_DIR}/
cp -rf %{ROOTDIR}/con/inc/caedradapter.h* %{DEST_INC_DIR}/
......
......@@ -13,19 +13,10 @@ root_dir = './../'
ca_common_path = root_dir + 'common/'
ca_common_src_path = ca_common_path + 'src/'
no_glib = 'darwin,ios'
env.AppendUnique(CPPPATH = [
'common/inc/',
])
if ca_os == 'android':
main_dir = Dir('.').srcnode().abspath
glib_dir = main_dir + '/../../../../extlibs/glib/glib-2.40.2/'
env.AppendUnique(CPPPATH = [
glib_dir,
glib_dir + 'glib',
glib_dir + 'gthread'])
temp = env['CPPPATH']
header = ' '
......@@ -47,25 +38,23 @@ if ca_os == 'arduino':
platform_src = [
env.get('BUILD_DIR') + 'logger.c.o',
]
else:
if ca_os in no_glib:
platform_src = [
ca_common_src_path + 'logger.c',
ca_common_src_path + 'oic_logger.c',
ca_common_src_path + 'oic_console_logger.c',
ca_common_src_path + 'uthreadpool.c',
ca_common_src_path + 'camutex_pthread.c'
]
else:
platform_src = [
elif env['POSIX_SUPPORTED']:
platform_src = [
ca_common_src_path + 'logger.c',
ca_common_src_path + 'oic_logger.c',
ca_common_src_path + 'oic_console_logger.c',
ca_common_src_path + 'uthreadpool.c',
ca_common_src_path + 'camutex_glib.c'
ca_common_src_path + 'cathreadpool_pthreads.c',
ca_common_src_path + 'camutex_pthreads.c'
]
else:
platform_src = [
ca_common_src_path + 'logger.c',
ca_common_src_path + 'oic_logger.c',
ca_common_src_path + 'oic_console_logger.c'
]
env.AppendUnique(CA_SRC = ca_common_src)
env.AppendUnique(CA_SRC = platform_src)
......@@ -38,7 +38,7 @@ typedef struct ca_mutex_internal *ca_mutex;
typedef struct ca_cond_internal *ca_cond;
/**
* Enums for ca_cond_wait_until return values
* Enums for ca_cond_wait_for return values
*/
typedef enum
{
......@@ -124,20 +124,20 @@ void ca_cond_wait(ca_cond cond, ca_mutex mutex);
/**
* Waits until this thread woken up on @cond,
* but not longer than until the time specified by microseconds.
* but not longer than the interval specified by microseconds.
* The mutex is unlocked before falling asleep and locked again before resuming.
* If microseconds is 0 or under, ca_cond_wait_until() acts like ca_cond_wait().
* If microseconds is 0, ca_cond_wait_for() acts like ca_cond_wait().
*
* @param cond The condtion to be wait for to signal
* @param mutex The mutex which is currently locked from calling thread
* @param microseconds absolute time for waiting, microseconds
* @param microseconds relative time for waiting, microseconds
*
* @return CA_WAIT_SUCCESS if the condition was signaled.
* CA_WAIT_TIMEDDOUT if wait period exceeded
* CA_WAIT_INVAL for invalid parameters
*
*/
CAWaitResult_t ca_cond_wait_until(ca_cond cond, ca_mutex mutex, uint64_t microseconds);
CAWaitResult_t ca_cond_wait_for(ca_cond cond, ca_mutex mutex, uint64_t microseconds);
/**
* Free the condition.
......
......@@ -21,42 +21,36 @@
/**
* @file
*
* This file provides APIs related to thread pool.
* This file provides APIs related to thread pool. Implementations are provided
* by adding a new .c file for each implementation, and adding them conditionally
* via the SCONS build script. Currently, cathreadpool_pthreads.c is implemented,
* with cathreadpool_winthreads.c being considered. RTOS implementations should use
* a name that best describes the used technology, not the OS.
*/
#ifndef __UTHREAD_POOL_H_
#define __UTHREAD_POOL_H_
#include <glib.h>
#ifndef CATHREAD_POOL_H_
#define CATHREAD_POOL_H_
#include "cacommon.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#endif // __cplusplus
/**
* @var u_thread_func
* @brief Callback type can be registered to thread pool.
* Callback type can be registered to thread pool.
*/
typedef void (*u_thread_func)(void *);
typedef void (*ca_thread_func)(void *);
struct ca_thread_pool_details_t;
/**
* @struct u_thread_msg_t
* @brief Structure to maintain the data which needs to send to task function.
* Thread pool type.
*/
typedef struct
typedef struct ca_thread_pool
{
void *data;
u_thread_func func;
} u_thread_msg_t;
/**
* @var u_thread_pool_t
* @brief Thread pool type.
*/
typedef void *u_thread_pool_t;
struct ca_thread_pool_details_t* details;
}*ca_thread_pool_t;
/**
* This function creates a newly allocated thread pool.
......@@ -65,7 +59,7 @@ typedef void *u_thread_pool_t;
* @param thread_pool_handle Handle to newly create thread pool.
* @return Error code, CA_STATUS_OK if success, else error number.
*/
CAResult_t u_thread_pool_init(uint32_t num_of_threads, u_thread_pool_t *thread_pool_handle);
CAResult_t ca_thread_pool_init(int32_t num_of_threads, ca_thread_pool_t *thread_pool_handle);
/**
* This function adds a routine to be executed by the thread pool at some future time.
......@@ -77,7 +71,7 @@ CAResult_t u_thread_pool_init(uint32_t num_of_threads, u_thread_pool_t *thread_p
* @return CA_STATUS_OK on success.
* @return Error on failure.
*/
CAResult_t u_thread_pool_add_task(u_thread_pool_t thread_pool, u_thread_func method,
CAResult_t ca_thread_pool_add_task(ca_thread_pool_t thread_pool, ca_thread_func method,
void *data);
/**
......@@ -86,11 +80,11 @@ CAResult_t u_thread_pool_add_task(u_thread_pool_t thread_pool, u_thread_func met
*
* @param thread_pool The thread pool structure.
*/
void u_thread_pool_free(u_thread_pool_t thread_pool);
void ca_thread_pool_free(ca_thread_pool_t thread_pool);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* __UTHREAD_POOL_H_ */
#endif /* CATHREAD_POOL_H_ */
/* ****************************************************************
*
* Copyright 2014 Samsung Electronics All Rights Reserved.
*
*
*
* Licensed 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.
*
******************************************************************/
/**
* @file
* This file provides APIs related to mutex and semaphores.
*/
#include "camutex.h"
#include <glib.h>
#include <string.h>
#include "logger.h"
/**
* @def TAG
* @brief Logging tag for module name
*/
#define TAG PCF("UMUTEX")
ca_mutex ca_mutex_new(void)
{
GMutex *mutexLock = g_new(GMutex, 1);
g_mutex_init(mutexLock);
return (ca_mutex) mutexLock;
}
void ca_mutex_lock(ca_mutex mutex)
{
if (NULL == mutex)
{
OIC_LOG(ERROR, TAG , "ca_mutex_lock, Invalid mutex !");
return;
}
GMutex *mutexLock = (GMutex *) mutex;
g_mutex_lock(mutexLock);
}
bool ca_mutex_trylock(ca_mutex mutex)
{
if (NULL == mutex)
{
OIC_LOG(ERROR, TAG, "ca_mutex_trylock, Invalid mutex !");
return false;
}
GMutex *mutexLock = (GMutex *) mutex;
return(g_mutex_trylock(mutexLock));
}
void ca_mutex_unlock(ca_mutex mutex)
{
if (NULL == mutex)
{
OIC_LOG(ERROR, TAG, "ca_mutex_unlock, Invalid mutex !");
return;
}
GMutex *mutexLock = (GMutex *) mutex;
g_mutex_unlock(mutexLock);
}
bool ca_mutex_free(ca_mutex mutex)
{
if (NULL == mutex)
{
OIC_LOG(ERROR, TAG, "ca_mutex_free, Invalid mutex !");
return false;
}
GMutex *mutexLock = (GMutex *) mutex;
g_mutex_clear(mutexLock);
g_free(mutexLock);
return true;
}
ca_cond ca_cond_new(void)
{
GCond *condition = g_new(GCond, 1);
g_cond_init(condition);
return (ca_cond) condition;
}
void ca_cond_signal(ca_cond cond)
{
if (NULL == cond)
{
OIC_LOG(ERROR, TAG, "ca_cond_signal, Invalid condition !");
return;
}
GCond *condition = (GCond *) cond;
g_cond_signal(condition);
}
void ca_cond_broadcast(ca_cond cond)
{
if (NULL == cond)
{
OIC_LOG(ERROR, TAG, "ca_cond_broadcast, Invalid condition !");
return;
}
GCond *condition = (GCond *) cond;
g_cond_broadcast(condition);
}
void ca_cond_wait(ca_cond cond, ca_mutex mutex)
{
if (NULL == mutex)
{
OIC_LOG(ERROR, TAG, "ca_cond_wait, Invalid mutex !");
return;