Änderungen Gruppe 30_10_2022 V2
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
get_filename_component (VIDEOCORE_ROOT "../.." ABSOLUTE)
|
||||
include (${VIDEOCORE_ROOT}/makefiles/cmake/global_settings.cmake)
|
||||
|
||||
set (HEADERS
|
||||
vcos_assert.h
|
||||
vcos_atomic_flags.h
|
||||
vcos_blockpool.h
|
||||
vcos_cmd.h
|
||||
vcos_dlfcn.h
|
||||
vcos_event_flags.h
|
||||
vcos_event.h
|
||||
vcos.h
|
||||
vcos_init.h
|
||||
vcos_inttypes.h
|
||||
vcos_isr.h
|
||||
vcos_legacy_isr.h
|
||||
vcos_logging.h
|
||||
vcos_logging_control.h
|
||||
vcos_lowlevel_thread.h
|
||||
vcos_mem.h
|
||||
vcos_mempool.h
|
||||
vcos_msgqueue.h
|
||||
vcos_mutex.h
|
||||
vcos_named_semaphore.h
|
||||
vcos_once.h
|
||||
vcos_queue.h
|
||||
vcos_quickslow_mutex.h
|
||||
vcos_reentrant_mutex.h
|
||||
vcos_semaphore.h
|
||||
vcos_stdint.h
|
||||
vcos_string.h
|
||||
vcos_thread_attr.h
|
||||
vcos_thread.h
|
||||
vcos_timer.h
|
||||
vcos_tls.h
|
||||
vcos_types.h
|
||||
)
|
||||
|
||||
foreach (header ${HEADERS})
|
||||
configure_file ("${header}" "${VCOS_HEADERS_BUILD_DIR}/${header}" COPYONLY)
|
||||
endforeach ()
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCC)
|
||||
add_definitions (-ggdb -Werror -Wall)
|
||||
endif ()
|
||||
|
||||
if (CMAKE_COMPILER_2005)
|
||||
add_definitions (/WX /W4 /wd4127 /D_CRT_SECURE_NO_DEPRECATE)
|
||||
endif ()
|
||||
|
||||
include_directories (${VIDEOCORE_ROOT} ${VCOS_HEADERS_BUILD_DIR})
|
||||
|
||||
add_subdirectory (${RTOS})
|
||||
|
||||
set(VCOS_EXCLUDE_TESTS TRUE)
|
||||
if (NOT DEFINED VCOS_EXCLUDE_TESTS)
|
||||
add_testapp_subdirectory (test)
|
||||
endif (NOT DEFINED VCOS_EXCLUDE_TESTS)
|
||||
|
||||
if (WIN32)
|
||||
build_command (RELEASE_BUILD_CMD CONFIGURATION Release)
|
||||
build_command (DEBUG_BUILD_CMD CONFIGURATION Debug)
|
||||
configure_file (build_all.bat.in build_all.bat @ONLY)
|
||||
endif ()
|
||||
|
||||
#install (FILES ${HEADERS} DESTINATION include/interface/vcos)
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
set (HEADERS
|
||||
vcos_common.h
|
||||
vcos_generic_blockpool.h
|
||||
vcos_generic_event_flags.h
|
||||
vcos_generic_named_sem.h
|
||||
vcos_generic_quickslow_mutex.h
|
||||
vcos_generic_reentrant_mtx.h
|
||||
vcos_generic_tls.h
|
||||
vcos_joinable_thread_from_plain.h
|
||||
vcos_latch_from_sem.h
|
||||
vcos_mem_from_malloc.h
|
||||
vcos_mutexes_are_reentrant.h
|
||||
vcos_thread_reaper.h
|
||||
)
|
||||
|
||||
foreach (header ${HEADERS})
|
||||
configure_file ("${header}" "${VCOS_HEADERS_BUILD_DIR}/generic/${header}" COPYONLY)
|
||||
endforeach ()
|
||||
|
||||
install (FILES ${HEADERS} DESTINATION include/interface/vcos/generic)
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "interface/vcos/vcos.h"
|
||||
#ifdef __VIDEOCORE__
|
||||
#include "host_support/include/vc_debug_sym.h"
|
||||
#include "vcfw/vclib/vclib.h"
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
int vcos_verify_bkpts = 0;
|
||||
#ifdef __VIDEOCORE__
|
||||
VC_DEBUG_VAR(vcos_verify_bkpts);
|
||||
#endif
|
||||
|
||||
int vcos_verify_bkpts_enabled(void)
|
||||
{
|
||||
return vcos_verify_bkpts;
|
||||
}
|
||||
|
||||
int vcos_verify_bkpts_enable(int enable)
|
||||
{
|
||||
int old = vcos_verify_bkpts;
|
||||
vcos_verify_bkpts = enable;
|
||||
return old;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the fatal error handler.
|
||||
*/
|
||||
void vcos_abort(void)
|
||||
{
|
||||
VCOS_ALERT("vcos_abort: Halting");
|
||||
|
||||
#ifdef __VIDEOCORE__
|
||||
_bkpt();
|
||||
#endif
|
||||
|
||||
#if defined(VCOS_HAVE_BACKTRACE) && !defined(NDEBUG)
|
||||
vcos_backtrace_self();
|
||||
#endif
|
||||
|
||||
#ifdef __VIDEOCORE__
|
||||
/* Flush the cache to help with postmortem RAM-dump debugging */
|
||||
vclib_cache_flush();
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_RASPBERRYPI
|
||||
extern void pattern(int);
|
||||
while(1)
|
||||
pattern(8);
|
||||
#endif
|
||||
|
||||
/* Insert chosen fatal error handler here */
|
||||
#if defined __VIDEOCORE__ && !defined(NDEBUG)
|
||||
while(1); /* allow us to attach a debugger after the fact and see where we came from. */
|
||||
#else
|
||||
abort(); /* on vc this ends up in _exit_halt which doesn't give us any stack backtrace */
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,722 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This file provides a generic command line interface which allows
|
||||
* vcos internals to be manipulated and/or displayed.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ---- Include Files ---------------------------------------------------- */
|
||||
|
||||
#include "interface/vcos/vcos.h"
|
||||
|
||||
#ifdef HAVE_VCOS_VERSION
|
||||
#include "interface/vcos/vcos_build_info.h"
|
||||
#endif
|
||||
|
||||
#ifdef _VIDEOCORE
|
||||
#include "vcfw/logging/logging.h"
|
||||
#endif
|
||||
|
||||
/* ---- Public Variables ------------------------------------------------- */
|
||||
|
||||
/* ---- Private Constants and Types -------------------------------------- */
|
||||
|
||||
#define VCOS_LOG_CATEGORY (&vcos_cmd_log_category)
|
||||
VCOS_LOG_CAT_T vcos_cmd_log_category;
|
||||
|
||||
/* ---- Private Variables ------------------------------------------------ */
|
||||
|
||||
static struct VCOS_CMD_GLOBALS_T
|
||||
{
|
||||
VCOS_MUTEX_T lock;
|
||||
VCOS_ONCE_T initialized;
|
||||
|
||||
unsigned num_cmd_entries;
|
||||
unsigned num_cmd_alloc;
|
||||
VCOS_CMD_T *cmd_entry;
|
||||
|
||||
VCOS_LOG_CAT_T *log_category;
|
||||
} cmd_globals;
|
||||
|
||||
#ifdef HAVE_VCOS_VERSION
|
||||
/* Keep the static strings in the image from being dropped by
|
||||
* the linker.
|
||||
*/
|
||||
extern const char *vcos_get_build_strings(unsigned id);
|
||||
const char *(*vcos_keep_static_strings)(unsigned);
|
||||
#endif
|
||||
|
||||
/* ---- Private Function Prototypes -------------------------------------- */
|
||||
|
||||
static VCOS_STATUS_T help_cmd( VCOS_CMD_PARAM_T *param );
|
||||
|
||||
/* ---- Functions ------------------------------------------------------- */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Walks through the commands looking for a particular command
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static VCOS_CMD_T *find_cmd( VCOS_CMD_T *cmd_entry, const char *name )
|
||||
{
|
||||
VCOS_CMD_T *scan_entry = cmd_entry;
|
||||
|
||||
while ( scan_entry->name != NULL )
|
||||
{
|
||||
if ( vcos_strcmp( scan_entry->name, name ) == 0 )
|
||||
{
|
||||
return scan_entry;
|
||||
}
|
||||
scan_entry++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Saves away
|
||||
* each line individually.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void vcos_cmd_always_log_output( VCOS_LOG_CAT_T *log_category )
|
||||
{
|
||||
cmd_globals.log_category = log_category;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Walks through a buffer containing newline separated lines, and logs
|
||||
* each line individually.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static void cmd_log_results( VCOS_CMD_PARAM_T *param )
|
||||
{
|
||||
char *start;
|
||||
char *end;
|
||||
|
||||
start = end = param->result_buf;
|
||||
|
||||
while ( *start != '\0' )
|
||||
{
|
||||
while (( *end != '\0' ) && ( *end != '\n' ))
|
||||
end++;
|
||||
|
||||
if ( *end == '\n' )
|
||||
{
|
||||
*end++ = '\0';
|
||||
}
|
||||
|
||||
if ( cmd_globals.log_category != NULL )
|
||||
{
|
||||
if ( vcos_is_log_enabled( cmd_globals.log_category, VCOS_LOG_INFO ))
|
||||
{
|
||||
vcos_log_impl( cmd_globals.log_category, VCOS_LOG_INFO, "%s", start );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vcos_log_info( "%s", start );
|
||||
}
|
||||
|
||||
start = end;
|
||||
}
|
||||
|
||||
/* Since we logged the buffer, reset the pointer back to the beginning. */
|
||||
|
||||
param->result_ptr = param->result_buf;
|
||||
param->result_buf[0] = '\0';
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Since we may have limited output space, we create a generic routine
|
||||
* which tries to use the result space, but will switch over to using
|
||||
* logging if the output is too large.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void vcos_cmd_vprintf( VCOS_CMD_PARAM_T *param, const char *fmt, va_list args )
|
||||
{
|
||||
int bytes_written;
|
||||
int bytes_remaining;
|
||||
|
||||
bytes_remaining = (int)(param->result_size - ( param->result_ptr - param->result_buf ));
|
||||
|
||||
bytes_written = vcos_vsnprintf( param->result_ptr, bytes_remaining, fmt, args );
|
||||
|
||||
if ( cmd_globals.log_category != NULL )
|
||||
{
|
||||
/* We're going to log each line as we encounter it. If the buffer
|
||||
* doesn't end in a newline, then we'll wait for one first.
|
||||
*/
|
||||
|
||||
if ( (( bytes_written + 1 ) >= bytes_remaining )
|
||||
|| ( param->result_ptr[ bytes_written - 1 ] == '\n' ))
|
||||
{
|
||||
cmd_log_results( param );
|
||||
}
|
||||
else
|
||||
{
|
||||
param->result_ptr += bytes_written;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (( bytes_written + 1 ) >= bytes_remaining )
|
||||
{
|
||||
/* Output doesn't fit - switch over to logging */
|
||||
|
||||
param->use_log = 1;
|
||||
|
||||
*param->result_ptr = '\0'; /* Zap the partial line that didn't fit above. */
|
||||
|
||||
cmd_log_results( param ); /* resets result_ptr */
|
||||
|
||||
bytes_written = vcos_vsnprintf( param->result_ptr, bytes_remaining, fmt, args );
|
||||
}
|
||||
param->result_ptr += bytes_written;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Prints the output.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void vcos_cmd_printf( VCOS_CMD_PARAM_T *param, const char *fmt, ... )
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start( args, fmt );
|
||||
vcos_cmd_vprintf( param, fmt, args );
|
||||
va_end( args );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Prints the arguments which were on the command line prior to ours.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static void print_argument_prefix( VCOS_CMD_PARAM_T *param )
|
||||
{
|
||||
int arg_idx;
|
||||
|
||||
for ( arg_idx = 0; ¶m->argv_orig[arg_idx] != param->argv; arg_idx++ )
|
||||
{
|
||||
vcos_cmd_printf( param, "%s ", param->argv_orig[arg_idx] );
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Prints an error message, prefixed by the command chain required to get
|
||||
* to where we're at.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void vcos_cmd_error( VCOS_CMD_PARAM_T *param, const char *fmt, ... )
|
||||
{
|
||||
va_list args;
|
||||
|
||||
print_argument_prefix( param );
|
||||
|
||||
va_start( args, fmt );
|
||||
vcos_cmd_vprintf( param, fmt, args );
|
||||
va_end( args );
|
||||
vcos_cmd_printf( param, "\n" );
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* usage - prints command usage for an array of commands.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
static void usage( VCOS_CMD_PARAM_T *param, VCOS_CMD_T *cmd_entry )
|
||||
{
|
||||
int cmd_idx;
|
||||
int nameWidth = 0;
|
||||
int argsWidth = 0;
|
||||
VCOS_CMD_T *scan_entry;
|
||||
|
||||
vcos_cmd_printf( param, "Usage: " );
|
||||
print_argument_prefix( param );
|
||||
vcos_cmd_printf( param, "command [args ...]\n" );
|
||||
vcos_cmd_printf( param, "\n" );
|
||||
vcos_cmd_printf( param, "Where command is one of the following:\n" );
|
||||
|
||||
for ( cmd_idx = 0; cmd_entry[cmd_idx].name != NULL; cmd_idx++ )
|
||||
{
|
||||
int aw;
|
||||
int nw;
|
||||
|
||||
scan_entry = &cmd_entry[cmd_idx];
|
||||
|
||||
nw = vcos_strlen( scan_entry->name );
|
||||
aw = vcos_strlen( scan_entry->args );
|
||||
|
||||
if ( nw > nameWidth )
|
||||
{
|
||||
nameWidth = nw;
|
||||
}
|
||||
if ( aw > argsWidth )
|
||||
{
|
||||
argsWidth = aw;
|
||||
}
|
||||
}
|
||||
|
||||
for ( cmd_idx = 0; cmd_entry[cmd_idx].name != NULL; cmd_idx++ )
|
||||
{
|
||||
scan_entry = &cmd_entry[cmd_idx];
|
||||
|
||||
vcos_cmd_printf( param, " %-*s %-*s - %s\n",
|
||||
nameWidth, scan_entry->name,
|
||||
argsWidth, scan_entry->args,
|
||||
scan_entry->descr );
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Prints the usage for the current command.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
void vcos_cmd_usage( VCOS_CMD_PARAM_T *param )
|
||||
{
|
||||
VCOS_CMD_T *cmd_entry;
|
||||
|
||||
cmd_entry = param->cmd_entry;
|
||||
|
||||
if ( cmd_entry->sub_cmd_entry != NULL )
|
||||
{
|
||||
/* This command is command with sub-commands */
|
||||
|
||||
usage( param, param->cmd_entry->sub_cmd_entry );
|
||||
}
|
||||
else
|
||||
{
|
||||
vcos_cmd_printf( param, "Usage: " );
|
||||
print_argument_prefix( param );
|
||||
vcos_cmd_printf( param, "%s %s - %s\n",
|
||||
param->argv[0],
|
||||
param->cmd_entry->args,
|
||||
param->cmd_entry->descr );
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Command to print out the help
|
||||
*
|
||||
* This help command is only called from the main menu.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static VCOS_STATUS_T help_cmd( VCOS_CMD_PARAM_T *param )
|
||||
{
|
||||
VCOS_CMD_T *found_entry;
|
||||
|
||||
#if 0
|
||||
{
|
||||
int arg_idx;
|
||||
|
||||
vcos_log_trace( "%s: argc = %d", __func__, param->argc );
|
||||
for ( arg_idx = 0; arg_idx < param->argc; arg_idx++ )
|
||||
{
|
||||
vcos_log_trace( "%s: argv[%d] = '%s'", __func__, arg_idx, param->argv[arg_idx] );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If there is an argument after the word help, then we want to print
|
||||
* help for that command.
|
||||
*/
|
||||
|
||||
if ( param->argc == 1 )
|
||||
{
|
||||
if ( param->cmd_parent_entry == cmd_globals.cmd_entry )
|
||||
{
|
||||
/* Bare help - print the command usage for the root */
|
||||
|
||||
usage( param, cmd_globals.cmd_entry );
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
|
||||
/* For all other cases help requires an argument */
|
||||
|
||||
vcos_cmd_error( param, "%s requires an argument", param->argv[0] );
|
||||
return VCOS_EINVAL;
|
||||
}
|
||||
|
||||
/* We were given an argument. */
|
||||
|
||||
if (( found_entry = find_cmd( param->cmd_parent_entry, param->argv[1] )) != NULL )
|
||||
{
|
||||
/* Make it look like the command that was specified is the one that's
|
||||
* currently running
|
||||
*/
|
||||
|
||||
param->cmd_entry = found_entry;
|
||||
param->argv[0] = param->argv[1];
|
||||
param->argv++;
|
||||
param->argc--;
|
||||
|
||||
vcos_cmd_usage( param );
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
|
||||
vcos_cmd_error( param, "- unrecognized command: '%s'", param->argv[1] );
|
||||
return VCOS_ENOENT;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Command to print out the version/build information.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef HAVE_VCOS_VERSION
|
||||
|
||||
static VCOS_STATUS_T version_cmd( VCOS_CMD_PARAM_T *param )
|
||||
{
|
||||
static const char* copyright = "Copyright (c) 2011 Broadcom";
|
||||
|
||||
vcos_cmd_printf( param, "%s %s\n%s\nversion %s\nhost %s",
|
||||
vcos_get_build_date(),
|
||||
vcos_get_build_time(),
|
||||
copyright,
|
||||
vcos_get_build_version(),
|
||||
vcos_get_build_hostname() );
|
||||
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Internal commands
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static VCOS_CMD_T cmd_help = { "help", "[command]", help_cmd, NULL, "Prints command help information" };
|
||||
|
||||
#ifdef HAVE_VCOS_VERSION
|
||||
static VCOS_CMD_T cmd_version = { "version", "", version_cmd, NULL, "Prints build/version information" };
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Walks the command table and executes the commands
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static VCOS_STATUS_T execute_cmd( VCOS_CMD_PARAM_T *param, VCOS_CMD_T *cmd_entry )
|
||||
{
|
||||
const char *cmdStr;
|
||||
VCOS_CMD_T *found_entry;
|
||||
|
||||
#if 0
|
||||
{
|
||||
int arg_idx;
|
||||
|
||||
vcos_cmd_printf( param, "%s: argc = %d", __func__, param->argc );
|
||||
for ( arg_idx = 0; arg_idx < param->argc; arg_idx++ )
|
||||
{
|
||||
vcos_cmd_printf( param, " argv[%d] = '%s'", arg_idx, param->argv[arg_idx] );
|
||||
}
|
||||
vcos_cmd_printf( param, "\n" );
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( param->argc <= 1 )
|
||||
{
|
||||
/* No command specified */
|
||||
|
||||
vcos_cmd_error( param, "%s - no command specified", param->argv[0] );
|
||||
return VCOS_EINVAL;
|
||||
}
|
||||
|
||||
/* argv[0] is the command/program that caused us to get invoked, so we strip
|
||||
* it off.
|
||||
*/
|
||||
|
||||
param->argc--;
|
||||
param->argv++;
|
||||
param->cmd_parent_entry = cmd_entry;
|
||||
|
||||
/* Not the help command, scan for the command and execute it. */
|
||||
|
||||
cmdStr = param->argv[0];
|
||||
|
||||
if (( found_entry = find_cmd( cmd_entry, cmdStr )) != NULL )
|
||||
{
|
||||
if ( found_entry->sub_cmd_entry != NULL )
|
||||
{
|
||||
return execute_cmd( param, found_entry->sub_cmd_entry );
|
||||
}
|
||||
|
||||
param->cmd_entry = found_entry;
|
||||
return found_entry->cmd_fn( param );
|
||||
}
|
||||
|
||||
/* Unrecognized command - check to see if it was the help command */
|
||||
|
||||
if ( vcos_strcmp( cmdStr, cmd_help.name ) == 0 )
|
||||
{
|
||||
return help_cmd( param );
|
||||
}
|
||||
|
||||
vcos_cmd_error( param, "- unrecognized command: '%s'", cmdStr );
|
||||
return VCOS_ENOENT;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Initializes the command line parser.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static void vcos_cmd_init( void )
|
||||
{
|
||||
vcos_mutex_create( &cmd_globals.lock, "vcos_cmd" );
|
||||
|
||||
cmd_globals.num_cmd_entries = 0;
|
||||
cmd_globals.num_cmd_alloc = 0;
|
||||
cmd_globals.cmd_entry = NULL;
|
||||
|
||||
#ifdef HAVE_VCOS_VERSION
|
||||
vcos_keep_static_strings = vcos_get_build_strings;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Shuts down the command line parser.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void vcos_cmd_shutdown( void )
|
||||
{
|
||||
vcos_mutex_delete( &cmd_globals.lock );
|
||||
|
||||
vcos_free( cmd_globals.cmd_entry );
|
||||
cmd_globals.cmd_entry = NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Command line processor.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
VCOS_STATUS_T vcos_cmd_execute( int argc, char **argv, size_t result_size, char *result_buf )
|
||||
{
|
||||
VCOS_STATUS_T rc = VCOS_EINVAL;
|
||||
VCOS_CMD_PARAM_T param;
|
||||
|
||||
vcos_once( &cmd_globals.initialized, vcos_cmd_init );
|
||||
|
||||
param.argc = argc;
|
||||
param.argv = param.argv_orig = argv;
|
||||
|
||||
param.use_log = 0;
|
||||
param.result_size = result_size;
|
||||
param.result_ptr = result_buf;
|
||||
param.result_buf = result_buf;
|
||||
|
||||
result_buf[0] = '\0';
|
||||
|
||||
vcos_mutex_lock( &cmd_globals.lock );
|
||||
|
||||
rc = execute_cmd( ¶m, cmd_globals.cmd_entry );
|
||||
|
||||
if ( param.use_log )
|
||||
{
|
||||
cmd_log_results( ¶m );
|
||||
vcos_snprintf( result_buf, result_size, "results logged" );
|
||||
}
|
||||
else
|
||||
if ( cmd_globals.log_category != NULL )
|
||||
{
|
||||
if ( result_buf[0] != '\0' )
|
||||
{
|
||||
/* There is a partial line still buffered. */
|
||||
|
||||
vcos_cmd_printf( ¶m, "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
vcos_mutex_unlock( &cmd_globals.lock );
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Registers a command entry with the command line processor
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
VCOS_STATUS_T vcos_cmd_register( VCOS_CMD_T *cmd_entry )
|
||||
{
|
||||
VCOS_STATUS_T rc;
|
||||
VCOS_UNSIGNED new_num_cmd_alloc;
|
||||
VCOS_CMD_T *new_cmd_entry;
|
||||
VCOS_CMD_T *old_cmd_entry;
|
||||
VCOS_CMD_T *scan_entry;
|
||||
|
||||
vcos_once( &cmd_globals.initialized, vcos_cmd_init );
|
||||
|
||||
vcos_assert( cmd_entry != NULL );
|
||||
vcos_assert( cmd_entry->name != NULL );
|
||||
|
||||
vcos_log_trace( "%s: cmd '%s'", __FUNCTION__, cmd_entry->name );
|
||||
|
||||
vcos_assert( cmd_entry->args != NULL );
|
||||
vcos_assert(( cmd_entry->cmd_fn != NULL ) || ( cmd_entry->sub_cmd_entry != NULL ));
|
||||
vcos_assert( cmd_entry->descr != NULL );
|
||||
|
||||
/* We expect vcos_cmd_init to be called before vcos_logging_init, so we
|
||||
* need to defer registering our logging category until someplace
|
||||
* like right here.
|
||||
*/
|
||||
|
||||
if ( vcos_cmd_log_category.name == NULL )
|
||||
{
|
||||
/*
|
||||
* If you're using the command interface, you pretty much always want
|
||||
* log messages from this file to show up. So we change the default
|
||||
* from ERROR to be the more reasonable INFO level.
|
||||
*/
|
||||
|
||||
vcos_log_set_level(&vcos_cmd_log_category, VCOS_LOG_INFO);
|
||||
vcos_log_register("vcos_cmd", &vcos_cmd_log_category);
|
||||
|
||||
/* We register a help command so that it shows up in the usage. */
|
||||
|
||||
vcos_cmd_register( &cmd_help );
|
||||
#ifdef HAVE_VCOS_VERSION
|
||||
vcos_cmd_register( &cmd_version );
|
||||
#endif
|
||||
}
|
||||
|
||||
vcos_mutex_lock( &cmd_globals.lock );
|
||||
|
||||
if ( cmd_globals.num_cmd_entries >= cmd_globals.num_cmd_alloc )
|
||||
{
|
||||
if ( cmd_globals.num_cmd_alloc == 0 )
|
||||
{
|
||||
/* We haven't allocated a table yet */
|
||||
}
|
||||
|
||||
/* The number 8 is rather arbitrary. */
|
||||
|
||||
new_num_cmd_alloc = cmd_globals.num_cmd_alloc + 8;
|
||||
|
||||
/* The + 1 is to ensure that we always have a NULL entry at the end. */
|
||||
|
||||
new_cmd_entry = (VCOS_CMD_T *)vcos_calloc( new_num_cmd_alloc + 1, sizeof( *cmd_entry ), "vcos_cmd_entries" );
|
||||
if ( new_cmd_entry == NULL )
|
||||
{
|
||||
rc = VCOS_ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
memcpy( new_cmd_entry, cmd_globals.cmd_entry, cmd_globals.num_cmd_entries * sizeof( *cmd_entry ));
|
||||
cmd_globals.num_cmd_alloc = new_num_cmd_alloc;
|
||||
old_cmd_entry = cmd_globals.cmd_entry;
|
||||
cmd_globals.cmd_entry = new_cmd_entry;
|
||||
vcos_free( old_cmd_entry );
|
||||
}
|
||||
|
||||
if ( cmd_globals.num_cmd_entries == 0 )
|
||||
{
|
||||
/* This is the first command being registered */
|
||||
|
||||
cmd_globals.cmd_entry[0] = *cmd_entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Keep the list in alphabetical order. We start at the end and work backwards
|
||||
* shuffling entries up one until we find an insertion point.
|
||||
*/
|
||||
|
||||
for ( scan_entry = &cmd_globals.cmd_entry[cmd_globals.num_cmd_entries - 1];
|
||||
scan_entry >= cmd_globals.cmd_entry; scan_entry-- )
|
||||
{
|
||||
if ( vcos_strcmp( cmd_entry->name, scan_entry->name ) > 0 )
|
||||
{
|
||||
/* We found an insertion point. */
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
scan_entry[1] = scan_entry[0];
|
||||
}
|
||||
scan_entry[1] = *cmd_entry;
|
||||
}
|
||||
cmd_globals.num_cmd_entries++;
|
||||
|
||||
rc = VCOS_SUCCESS;
|
||||
|
||||
out:
|
||||
|
||||
vcos_mutex_unlock( &cmd_globals.lock );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Registers multiple commands.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
VCOS_STATUS_T vcos_cmd_register_multiple( VCOS_CMD_T *cmd_entry )
|
||||
{
|
||||
VCOS_STATUS_T status;
|
||||
|
||||
while ( cmd_entry->name != NULL )
|
||||
{
|
||||
if (( status = vcos_cmd_register( cmd_entry )) != VCOS_SUCCESS )
|
||||
{
|
||||
return status;
|
||||
}
|
||||
cmd_entry++;
|
||||
}
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - common postamble code
|
||||
=============================================================================*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Postamble code included by the platform-specific header files
|
||||
*/
|
||||
|
||||
#define VCOS_THREAD_PRI_DEFAULT VCOS_THREAD_PRI_NORMAL
|
||||
|
||||
#if !defined(VCOS_THREAD_PRI_INCREASE)
|
||||
#error Which way to thread priorities go?
|
||||
#endif
|
||||
|
||||
#if VCOS_THREAD_PRI_INCREASE < 0
|
||||
/* smaller numbers are higher priority */
|
||||
#define VCOS_THREAD_PRI_LESS(x) ((x)<VCOS_THREAD_PRI_MAX?(x)+1:VCOS_THREAD_PRI_MAX)
|
||||
#define VCOS_THREAD_PRI_MORE(x) ((x)>VCOS_THREAD_PRI_MIN?(x)-1:VCOS_THREAD_PRI_MIN)
|
||||
#else
|
||||
/* bigger numbers are lower priority */
|
||||
#define VCOS_THREAD_PRI_MORE(x) ((x)<VCOS_THREAD_PRI_MAX?(x)+1:VCOS_THREAD_PRI_MAX)
|
||||
#define VCOS_THREAD_PRI_LESS(x) ((x)>VCOS_THREAD_PRI_MIN?(x)-1:VCOS_THREAD_PRI_MIN)
|
||||
#endif
|
||||
|
||||
/* Convenience for Brits: */
|
||||
#define VCOS_APPLICATION_INITIALISE VCOS_APPLICATION_INITIALIZE
|
||||
|
||||
/*
|
||||
* Check for constant definitions
|
||||
*/
|
||||
#ifndef VCOS_TICKS_PER_SECOND
|
||||
#error VCOS_TICKS_PER_SECOND not defined
|
||||
#endif
|
||||
|
||||
#if !defined(VCOS_THREAD_PRI_MIN) || !defined(VCOS_THREAD_PRI_MAX)
|
||||
#error Priority range not defined
|
||||
#endif
|
||||
|
||||
#if !defined(VCOS_THREAD_PRI_HIGHEST) || !defined(VCOS_THREAD_PRI_LOWEST) || !defined(VCOS_THREAD_PRI_NORMAL)
|
||||
#error Priority ordering not defined
|
||||
#endif
|
||||
|
||||
#if !defined(VCOS_CAN_SET_STACK_ADDR)
|
||||
#error Can stack addresses be set on this platform? Please set this macro to either 0 or 1.
|
||||
#endif
|
||||
|
||||
#if (_VCOS_AFFINITY_CPU0|_VCOS_AFFINITY_CPU1) & (~_VCOS_AFFINITY_MASK)
|
||||
#error _VCOS_AFFINITY_CPUxxx values are not consistent with _VCOS_AFFINITY_MASK
|
||||
#endif
|
||||
|
||||
/** Append to the end of a singly-linked queue, O(1). Works with
|
||||
* any structure where list has members 'head' and 'tail' and
|
||||
* item has a 'next' pointer.
|
||||
*/
|
||||
#define VCOS_QUEUE_APPEND_TAIL(list, item) {\
|
||||
(item)->next = NULL;\
|
||||
if (!(list)->head) {\
|
||||
(list)->head = (list)->tail = (item); \
|
||||
} else {\
|
||||
(list)->tail->next = (item); \
|
||||
(list)->tail = (item); \
|
||||
} \
|
||||
}
|
||||
|
||||
#ifndef VCOS_HAVE_TIMER
|
||||
VCOSPRE_ void VCOSPOST_ vcos_timer_init(void);
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
The symbol vcos_deprecated_code may be defined at most once, by the inclusion of "vcos_deprecated.h" in vcos_init.c.
|
||||
Any other inclusions of this header will cause the linker to warn about multiple definitions of vcos_deprecated_code, for example:
|
||||
[ldvc] (Warning) "vcos_deprecated_code" is multiply defined in libs/vcos_threadx/vcos_init.c.o and libs/xxxxx/xxxxx.c.o
|
||||
If you see a build message like this then the configuration you are building is using deprecated code.
|
||||
Contact the person named in the accompanying comment for advice - do not remove the inclusion.
|
||||
*/
|
||||
|
||||
int vcos_deprecated_code;
|
||||
+568
@@ -0,0 +1,568 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define VCOS_LOG_CATEGORY (&vcos_blockpool_log)
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "interface/vcos/vcos.h"
|
||||
#include "interface/vcos/generic/vcos_generic_blockpool.h"
|
||||
|
||||
#define VCOS_BLOCKPOOL_FOURCC(a,b,c,d) ((a) | (b << 8) | (c << 16) | (d << 24))
|
||||
#define VCOS_BLOCKPOOL_MAGIC VCOS_BLOCKPOOL_FOURCC('v', 'b', 'p', 'l')
|
||||
#define VCOS_BLOCKPOOL_SUBPOOL_MAGIC VCOS_BLOCKPOOL_FOURCC('v', 's', 'p', 'l')
|
||||
|
||||
#define VCOS_BLOCKPOOL_SUBPOOL_FLAG_NONE (0)
|
||||
#define VCOS_BLOCKPOOL_SUBPOOL_FLAG_OWNS_MEM (1 << 0)
|
||||
#define VCOS_BLOCKPOOL_SUBPOOL_FLAG_EXTENSION (1 << 1)
|
||||
|
||||
/* Uncomment to enable really verbose debug messages */
|
||||
/* #define VCOS_BLOCKPOOL_DEBUGGING */
|
||||
/* Whether to overwrite freed blocks with 0xBD */
|
||||
#ifdef VCOS_BLOCKPOOL_DEBUGGING
|
||||
#define VCOS_BLOCKPOOL_OVERWRITE_ON_FREE 1
|
||||
#define VCOS_BLOCKPOOL_DEBUG_MEMSET_MAX_SIZE (UINT32_MAX)
|
||||
#else
|
||||
#define VCOS_BLOCKPOOL_OVERWRITE_ON_FREE 0
|
||||
#define VCOS_BLOCKPOOL_DEBUG_MEMSET_MAX_SIZE (2 * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
#ifdef VCOS_BLOCKPOOL_DEBUGGING
|
||||
#define VCOS_BLOCKPOOL_ASSERT vcos_demand
|
||||
#define VCOS_BLOCKPOOL_TRACE_LEVEL VCOS_LOG_TRACE
|
||||
#define VCOS_BLOCKPOOL_DEBUG_LOG(s, ...) vcos_log_trace("%s: " s, VCOS_FUNCTION, __VA_ARGS__)
|
||||
#undef VCOS_BLOCKPOOL_OVERWRITE_ON_FREE
|
||||
#define VCOS_BLOCKPOOL_OVERWRITE_ON_FREE 1
|
||||
#else
|
||||
#define VCOS_BLOCKPOOL_ASSERT vcos_demand
|
||||
#define VCOS_BLOCKPOOL_TRACE_LEVEL VCOS_LOG_ERROR
|
||||
#define VCOS_BLOCKPOOL_DEBUG_LOG(s, ...)
|
||||
#endif
|
||||
|
||||
#define ASSERT_POOL(p) \
|
||||
VCOS_BLOCKPOOL_ASSERT((p) && (p)->magic == VCOS_BLOCKPOOL_MAGIC);
|
||||
|
||||
#define ASSERT_SUBPOOL(p) \
|
||||
VCOS_BLOCKPOOL_ASSERT((p) && (p)->magic == VCOS_BLOCKPOOL_SUBPOOL_MAGIC && \
|
||||
p->start >= p->mem);
|
||||
|
||||
#if defined(VCOS_LOGGING_ENABLED)
|
||||
static VCOS_LOG_CAT_T vcos_blockpool_log =
|
||||
VCOS_LOG_INIT("vcos_blockpool", VCOS_BLOCKPOOL_TRACE_LEVEL);
|
||||
#endif
|
||||
|
||||
static void vcos_generic_blockpool_subpool_init(
|
||||
VCOS_BLOCKPOOL_T *pool, VCOS_BLOCKPOOL_SUBPOOL_T *subpool,
|
||||
void *mem, size_t pool_size, VCOS_UNSIGNED num_blocks, int align,
|
||||
uint32_t flags)
|
||||
{
|
||||
VCOS_BLOCKPOOL_HEADER_T *block;
|
||||
VCOS_BLOCKPOOL_HEADER_T *end;
|
||||
|
||||
vcos_unused(flags);
|
||||
|
||||
vcos_log_trace(
|
||||
"%s: pool %p subpool %p mem %p pool_size %d " \
|
||||
"num_blocks %d align %d flags %x",
|
||||
VCOS_FUNCTION,
|
||||
pool, subpool, mem, (uint32_t) pool_size,
|
||||
num_blocks, align, flags);
|
||||
|
||||
subpool->magic = VCOS_BLOCKPOOL_SUBPOOL_MAGIC;
|
||||
subpool->mem = mem;
|
||||
|
||||
/* The block data pointers must be aligned according to align and the
|
||||
* block header pre-preceeds the first block data.
|
||||
* For large alignments there may be wasted space between subpool->mem
|
||||
* and the first block header.
|
||||
*/
|
||||
subpool->start = (char *) subpool->mem + sizeof(VCOS_BLOCKPOOL_HEADER_T);
|
||||
subpool->start = (void*)
|
||||
VCOS_BLOCKPOOL_ROUND_UP((unsigned long) subpool->start, align);
|
||||
subpool->start = (char *) subpool->start - sizeof(VCOS_BLOCKPOOL_HEADER_T);
|
||||
|
||||
vcos_assert(subpool->start >= subpool->mem);
|
||||
|
||||
vcos_log_trace("%s: mem %p subpool->start %p" \
|
||||
" pool->block_size %d pool->block_data_size %d",
|
||||
VCOS_FUNCTION, mem, subpool->start,
|
||||
(int) pool->block_size, (int) pool->block_data_size);
|
||||
|
||||
subpool->num_blocks = num_blocks;
|
||||
subpool->available_blocks = num_blocks;
|
||||
subpool->free_list = NULL;
|
||||
subpool->owner = pool;
|
||||
|
||||
/* Initialise to a predictable bit pattern unless the pool is so big
|
||||
* that the delay would be noticable. */
|
||||
if (pool_size < VCOS_BLOCKPOOL_DEBUG_MEMSET_MAX_SIZE)
|
||||
memset(subpool->mem, 0xBC, pool_size); /* For debugging */
|
||||
|
||||
block = (VCOS_BLOCKPOOL_HEADER_T*) subpool->start;
|
||||
end = (VCOS_BLOCKPOOL_HEADER_T*)
|
||||
((char *) subpool->start + (pool->block_size * num_blocks));
|
||||
subpool->end = end;
|
||||
|
||||
/* Initialise the free list for this subpool */
|
||||
while (block < end)
|
||||
{
|
||||
block->owner.next = subpool->free_list;
|
||||
subpool->free_list = block;
|
||||
block = (VCOS_BLOCKPOOL_HEADER_T*)((char*) block + pool->block_size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VCOS_STATUS_T vcos_generic_blockpool_init(VCOS_BLOCKPOOL_T *pool,
|
||||
VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size,
|
||||
void *start, VCOS_UNSIGNED pool_size, VCOS_UNSIGNED align,
|
||||
VCOS_UNSIGNED flags, const char *name)
|
||||
{
|
||||
VCOS_STATUS_T status = VCOS_SUCCESS;
|
||||
|
||||
vcos_unused(name);
|
||||
vcos_unused(flags);
|
||||
|
||||
vcos_log_trace(
|
||||
"%s: pool %p num_blocks %d block_size %d start %p pool_size %d name %p",
|
||||
VCOS_FUNCTION, pool, num_blocks, block_size, start, pool_size, name);
|
||||
|
||||
vcos_demand(pool);
|
||||
vcos_demand(start);
|
||||
vcos_assert((block_size > 0));
|
||||
vcos_assert(num_blocks > 0);
|
||||
|
||||
if (! align)
|
||||
align = VCOS_BLOCKPOOL_ALIGN_DEFAULT;
|
||||
|
||||
if (align & 0x3)
|
||||
{
|
||||
vcos_log_error("%s: invalid alignment %d", VCOS_FUNCTION, align);
|
||||
return VCOS_EINVAL;
|
||||
}
|
||||
|
||||
if (VCOS_BLOCKPOOL_SIZE(num_blocks, block_size, align) > pool_size)
|
||||
{
|
||||
vcos_log_error("%s: Pool is too small" \
|
||||
" num_blocks %d block_size %d align %d"
|
||||
" pool_size %d required size %d", VCOS_FUNCTION,
|
||||
num_blocks, block_size, align,
|
||||
pool_size, (int) VCOS_BLOCKPOOL_SIZE(num_blocks, block_size, align));
|
||||
return VCOS_ENOMEM;
|
||||
}
|
||||
|
||||
status = vcos_mutex_create(&pool->mutex, "vcos blockpool mutex");
|
||||
if (status != VCOS_SUCCESS)
|
||||
return status;
|
||||
|
||||
pool->block_data_size = block_size;
|
||||
|
||||
/* TODO - create flag that if set forces the header to be in its own cache
|
||||
* line */
|
||||
pool->block_size = VCOS_BLOCKPOOL_ROUND_UP(pool->block_data_size +
|
||||
(align >= 4096 ? 32 : 0) +
|
||||
sizeof(VCOS_BLOCKPOOL_HEADER_T), align);
|
||||
|
||||
pool->magic = VCOS_BLOCKPOOL_MAGIC;
|
||||
pool->num_subpools = 1;
|
||||
pool->num_extension_blocks = 0;
|
||||
pool->align = align;
|
||||
memset(pool->subpools, 0, sizeof(pool->subpools));
|
||||
|
||||
vcos_generic_blockpool_subpool_init(pool, &pool->subpools[0], start,
|
||||
pool_size, num_blocks, align, VCOS_BLOCKPOOL_SUBPOOL_FLAG_NONE);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
VCOS_STATUS_T vcos_generic_blockpool_create_on_heap(VCOS_BLOCKPOOL_T *pool,
|
||||
VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size, VCOS_UNSIGNED align,
|
||||
VCOS_UNSIGNED flags, const char *name)
|
||||
{
|
||||
VCOS_STATUS_T status = VCOS_SUCCESS;
|
||||
size_t size = VCOS_BLOCKPOOL_SIZE(num_blocks, block_size, align);
|
||||
void* mem = vcos_malloc(size, name);
|
||||
|
||||
vcos_log_trace("%s: num_blocks %d block_size %d name %s",
|
||||
VCOS_FUNCTION, num_blocks, block_size, name);
|
||||
|
||||
if (! mem)
|
||||
return VCOS_ENOMEM;
|
||||
|
||||
status = vcos_generic_blockpool_init(pool, num_blocks,
|
||||
block_size, mem, size, align, flags, name);
|
||||
|
||||
if (status != VCOS_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
pool->subpools[0].flags |= VCOS_BLOCKPOOL_SUBPOOL_FLAG_OWNS_MEM;
|
||||
return status;
|
||||
|
||||
fail:
|
||||
free(mem);
|
||||
return status;
|
||||
}
|
||||
|
||||
VCOS_STATUS_T vcos_generic_blockpool_extend(VCOS_BLOCKPOOL_T *pool,
|
||||
VCOS_UNSIGNED num_extensions, VCOS_UNSIGNED num_blocks)
|
||||
{
|
||||
VCOS_UNSIGNED i;
|
||||
ASSERT_POOL(pool);
|
||||
|
||||
vcos_log_trace("%s: pool %p num_extensions %d num_blocks %d",
|
||||
VCOS_FUNCTION, pool, num_extensions, num_blocks);
|
||||
|
||||
/* Extend may only be called once */
|
||||
if (pool->num_subpools > 1)
|
||||
return VCOS_EACCESS;
|
||||
|
||||
if (num_extensions < 1 ||
|
||||
num_extensions > VCOS_BLOCKPOOL_MAX_SUBPOOLS - 1)
|
||||
return VCOS_EINVAL;
|
||||
|
||||
if (num_blocks < 1)
|
||||
return VCOS_EINVAL;
|
||||
|
||||
pool->num_subpools += num_extensions;
|
||||
pool->num_extension_blocks = num_blocks;
|
||||
|
||||
/* Mark these subpools as valid but unallocated */
|
||||
for (i = 1; i < pool->num_subpools; ++i)
|
||||
{
|
||||
pool->subpools[i].magic = VCOS_BLOCKPOOL_SUBPOOL_MAGIC;
|
||||
pool->subpools[i].start = NULL;
|
||||
pool->subpools[i].mem = NULL;
|
||||
}
|
||||
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
|
||||
void *vcos_generic_blockpool_alloc(VCOS_BLOCKPOOL_T *pool)
|
||||
{
|
||||
VCOS_UNSIGNED i;
|
||||
void* ret = NULL;
|
||||
VCOS_BLOCKPOOL_SUBPOOL_T *subpool = NULL;
|
||||
|
||||
ASSERT_POOL(pool);
|
||||
vcos_mutex_lock(&pool->mutex);
|
||||
|
||||
/* Starting with the main pool try and find a free block */
|
||||
for (i = 0; i < pool->num_subpools; ++i)
|
||||
{
|
||||
if (pool->subpools[i].start && pool->subpools[i].available_blocks > 0)
|
||||
{
|
||||
subpool = &pool->subpools[i];
|
||||
break; /* Found a subpool with free blocks */
|
||||
}
|
||||
}
|
||||
|
||||
if (! subpool)
|
||||
{
|
||||
/* All current subpools are full, try to allocate a new one */
|
||||
for (i = 1; i < pool->num_subpools; ++i)
|
||||
{
|
||||
if (! pool->subpools[i].start)
|
||||
{
|
||||
VCOS_BLOCKPOOL_SUBPOOL_T *s = &pool->subpools[i];
|
||||
size_t size = VCOS_BLOCKPOOL_SIZE(pool->num_extension_blocks,
|
||||
pool->block_data_size, pool->align);
|
||||
void *mem = vcos_malloc(size, pool->name);
|
||||
if (mem)
|
||||
{
|
||||
vcos_log_trace("%s: Allocated subpool %d", VCOS_FUNCTION, i);
|
||||
vcos_generic_blockpool_subpool_init(pool, s, mem, size,
|
||||
pool->num_extension_blocks,
|
||||
pool->align,
|
||||
VCOS_BLOCKPOOL_SUBPOOL_FLAG_OWNS_MEM |
|
||||
VCOS_BLOCKPOOL_SUBPOOL_FLAG_EXTENSION);
|
||||
subpool = s;
|
||||
break; /* Created a subpool */
|
||||
}
|
||||
else
|
||||
{
|
||||
vcos_log_warn("%s: Failed to allocate subpool", VCOS_FUNCTION);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (subpool)
|
||||
{
|
||||
/* Remove from free list */
|
||||
VCOS_BLOCKPOOL_HEADER_T* nb = subpool->free_list;
|
||||
|
||||
vcos_assert(subpool->free_list);
|
||||
subpool->free_list = nb->owner.next;
|
||||
|
||||
/* Owner is pool so free can be called without passing pool
|
||||
* as a parameter */
|
||||
nb->owner.subpool = subpool;
|
||||
|
||||
ret = nb + 1; /* Return pointer to block data */
|
||||
--(subpool->available_blocks);
|
||||
}
|
||||
vcos_mutex_unlock(&pool->mutex);
|
||||
VCOS_BLOCKPOOL_DEBUG_LOG("pool %p subpool %p ret %p", pool, subpool, ret);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
vcos_assert(ret > subpool->start);
|
||||
vcos_assert(ret < subpool->end);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *vcos_generic_blockpool_calloc(VCOS_BLOCKPOOL_T *pool)
|
||||
{
|
||||
void* ret = vcos_generic_blockpool_alloc(pool);
|
||||
if (ret)
|
||||
memset(ret, 0, pool->block_data_size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void vcos_generic_blockpool_free(void *block)
|
||||
{
|
||||
VCOS_BLOCKPOOL_DEBUG_LOG("block %p", block);
|
||||
if (block)
|
||||
{
|
||||
VCOS_BLOCKPOOL_HEADER_T* hdr = (VCOS_BLOCKPOOL_HEADER_T*) block - 1;
|
||||
VCOS_BLOCKPOOL_SUBPOOL_T *subpool = hdr->owner.subpool;
|
||||
VCOS_BLOCKPOOL_T *pool = NULL;
|
||||
|
||||
ASSERT_SUBPOOL(subpool);
|
||||
pool = subpool->owner;
|
||||
ASSERT_POOL(pool);
|
||||
|
||||
vcos_mutex_lock(&pool->mutex);
|
||||
vcos_assert((unsigned) subpool->available_blocks < subpool->num_blocks);
|
||||
|
||||
/* Change ownership of block to be the free list */
|
||||
hdr->owner.next = subpool->free_list;
|
||||
subpool->free_list = hdr;
|
||||
++(subpool->available_blocks);
|
||||
|
||||
if (VCOS_BLOCKPOOL_OVERWRITE_ON_FREE)
|
||||
memset(block, 0xBD, pool->block_data_size); /* For debugging */
|
||||
|
||||
if ( (subpool->flags & VCOS_BLOCKPOOL_SUBPOOL_FLAG_EXTENSION) &&
|
||||
subpool->available_blocks == subpool->num_blocks)
|
||||
{
|
||||
VCOS_BLOCKPOOL_DEBUG_LOG("%s: freeing subpool %p mem %p", VCOS_FUNCTION,
|
||||
subpool, subpool->mem);
|
||||
/* Free the sub-pool if it was dynamically allocated */
|
||||
vcos_free(subpool->mem);
|
||||
subpool->mem = NULL;
|
||||
subpool->start = NULL;
|
||||
}
|
||||
vcos_mutex_unlock(&pool->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
VCOS_UNSIGNED vcos_generic_blockpool_available_count(VCOS_BLOCKPOOL_T *pool)
|
||||
{
|
||||
VCOS_UNSIGNED ret = 0;
|
||||
VCOS_UNSIGNED i;
|
||||
|
||||
ASSERT_POOL(pool);
|
||||
vcos_mutex_lock(&pool->mutex);
|
||||
for (i = 0; i < pool->num_subpools; ++i)
|
||||
{
|
||||
VCOS_BLOCKPOOL_SUBPOOL_T *subpool = &pool->subpools[i];
|
||||
ASSERT_SUBPOOL(subpool);
|
||||
|
||||
/* Assume the malloc of sub pool would succeed */
|
||||
if (subpool->start)
|
||||
ret += subpool->available_blocks;
|
||||
else
|
||||
ret += pool->num_extension_blocks;
|
||||
}
|
||||
vcos_mutex_unlock(&pool->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
VCOS_UNSIGNED vcos_generic_blockpool_used_count(VCOS_BLOCKPOOL_T *pool)
|
||||
{
|
||||
VCOS_UNSIGNED ret = 0;
|
||||
VCOS_UNSIGNED i;
|
||||
|
||||
ASSERT_POOL(pool);
|
||||
vcos_mutex_lock(&pool->mutex);
|
||||
|
||||
for (i = 0; i < pool->num_subpools; ++i)
|
||||
{
|
||||
VCOS_BLOCKPOOL_SUBPOOL_T *subpool = &pool->subpools[i];
|
||||
ASSERT_SUBPOOL(subpool);
|
||||
if (subpool->start)
|
||||
ret += (subpool->num_blocks - subpool->available_blocks);
|
||||
}
|
||||
vcos_mutex_unlock(&pool->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void vcos_generic_blockpool_delete(VCOS_BLOCKPOOL_T *pool)
|
||||
{
|
||||
vcos_log_trace("%s: pool %p", VCOS_FUNCTION, pool);
|
||||
|
||||
if (pool)
|
||||
{
|
||||
VCOS_UNSIGNED i;
|
||||
|
||||
ASSERT_POOL(pool);
|
||||
for (i = 0; i < pool->num_subpools; ++i)
|
||||
{
|
||||
VCOS_BLOCKPOOL_SUBPOOL_T *subpool = &pool->subpools[i];
|
||||
ASSERT_SUBPOOL(subpool);
|
||||
if (subpool->mem)
|
||||
{
|
||||
/* For debugging */
|
||||
memset(subpool->mem,
|
||||
0xBE,
|
||||
VCOS_BLOCKPOOL_SIZE(subpool->num_blocks,
|
||||
pool->block_data_size, pool->align));
|
||||
|
||||
if (subpool->flags & VCOS_BLOCKPOOL_SUBPOOL_FLAG_OWNS_MEM)
|
||||
vcos_free(subpool->mem);
|
||||
subpool->mem = NULL;
|
||||
subpool->start = NULL;
|
||||
}
|
||||
}
|
||||
vcos_mutex_delete(&pool->mutex);
|
||||
memset(pool, 0xBE, sizeof(VCOS_BLOCKPOOL_T)); /* For debugging */
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t vcos_generic_blockpool_elem_to_handle(void *block)
|
||||
{
|
||||
uint32_t ret = -1;
|
||||
uint32_t index = -1;
|
||||
VCOS_BLOCKPOOL_HEADER_T *hdr = NULL;
|
||||
VCOS_BLOCKPOOL_T *pool = NULL;
|
||||
VCOS_BLOCKPOOL_SUBPOOL_T *subpool = NULL;
|
||||
uint32_t subpool_id;
|
||||
|
||||
vcos_assert(block);
|
||||
hdr = (VCOS_BLOCKPOOL_HEADER_T*) block - 1;
|
||||
subpool = hdr->owner.subpool;
|
||||
ASSERT_SUBPOOL(subpool);
|
||||
|
||||
pool = subpool->owner;
|
||||
ASSERT_POOL(pool);
|
||||
vcos_mutex_lock(&pool->mutex);
|
||||
|
||||
/* The handle is the index into the array of blocks combined
|
||||
* with the subpool id.
|
||||
*/
|
||||
index = ((size_t) hdr - (size_t) subpool->start) / pool->block_size;
|
||||
vcos_assert(index < subpool->num_blocks);
|
||||
|
||||
subpool_id = ((char*) subpool - (char*) &pool->subpools[0]) /
|
||||
sizeof(VCOS_BLOCKPOOL_SUBPOOL_T);
|
||||
|
||||
vcos_assert(subpool_id < VCOS_BLOCKPOOL_MAX_SUBPOOLS);
|
||||
vcos_assert(subpool_id < pool->num_subpools);
|
||||
ret = VCOS_BLOCKPOOL_HANDLE_CREATE(index, subpool_id);
|
||||
|
||||
vcos_log_trace("%s: index %d subpool_id %d handle 0x%08x",
|
||||
VCOS_FUNCTION, index, subpool_id, ret);
|
||||
|
||||
vcos_mutex_unlock(&pool->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *vcos_generic_blockpool_elem_from_handle(
|
||||
VCOS_BLOCKPOOL_T *pool, uint32_t handle)
|
||||
{
|
||||
VCOS_BLOCKPOOL_SUBPOOL_T *subpool;
|
||||
uint32_t subpool_id;
|
||||
uint32_t index;
|
||||
void *ret = NULL;
|
||||
|
||||
|
||||
ASSERT_POOL(pool);
|
||||
vcos_mutex_lock(&pool->mutex);
|
||||
subpool_id = VCOS_BLOCKPOOL_HANDLE_GET_SUBPOOL(handle);
|
||||
|
||||
if (subpool_id < pool->num_subpools)
|
||||
{
|
||||
index = VCOS_BLOCKPOOL_HANDLE_GET_INDEX(handle);
|
||||
subpool = &pool->subpools[subpool_id];
|
||||
if (pool->subpools[subpool_id].magic == VCOS_BLOCKPOOL_SUBPOOL_MAGIC &&
|
||||
pool->subpools[subpool_id].mem && index < subpool->num_blocks)
|
||||
{
|
||||
VCOS_BLOCKPOOL_HEADER_T *hdr = (VCOS_BLOCKPOOL_HEADER_T*)
|
||||
((size_t) subpool->start + (index * pool->block_size));
|
||||
|
||||
if (hdr->owner.subpool == subpool) /* Check block is allocated */
|
||||
ret = hdr + 1;
|
||||
}
|
||||
}
|
||||
vcos_mutex_unlock(&pool->mutex);
|
||||
|
||||
vcos_log_trace("%s: pool %p handle 0x%08x elem %p", VCOS_FUNCTION, pool,
|
||||
handle, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t vcos_generic_blockpool_is_valid_elem(
|
||||
VCOS_BLOCKPOOL_T *pool, const void *block)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
const char *pool_end;
|
||||
VCOS_UNSIGNED i = 0;
|
||||
|
||||
ASSERT_POOL(pool);
|
||||
if (((size_t) block) & 0x3)
|
||||
return 0;
|
||||
|
||||
vcos_mutex_lock(&pool->mutex);
|
||||
|
||||
for (i = 0; i < pool->num_subpools; ++i)
|
||||
{
|
||||
VCOS_BLOCKPOOL_SUBPOOL_T *subpool = &pool->subpools[i];
|
||||
ASSERT_SUBPOOL(subpool);
|
||||
|
||||
if (subpool->mem && subpool->start)
|
||||
{
|
||||
pool_end = (const char*)subpool->start +
|
||||
(subpool->num_blocks * pool->block_size);
|
||||
|
||||
if ((const char*)block > (const char*)subpool->start &&
|
||||
(const char*)block < pool_end)
|
||||
{
|
||||
const VCOS_BLOCKPOOL_HEADER_T *hdr = (
|
||||
const VCOS_BLOCKPOOL_HEADER_T*) block - 1;
|
||||
|
||||
/* If the block has a header where the owner points to the pool then
|
||||
* it's a valid block. */
|
||||
ret = (hdr->owner.subpool == subpool && subpool->owner == pool);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
vcos_mutex_unlock(&pool->mutex);
|
||||
return ret;
|
||||
}
|
||||
+294
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - event flags implemented via a semaphore
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_GENERIC_BLOCKPOOL_H
|
||||
#define VCOS_GENERIC_BLOCKPOOL_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This provides a generic, thread safe implementation of a VCOS block pool
|
||||
* fixed size memory allocator.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
|
||||
/** Bits 0 to (VCOS_BLOCKPOOL_SUBPOOL_BITS - 1) are used to store the
|
||||
* subpool id. */
|
||||
#define VCOS_BLOCKPOOL_SUBPOOL_BITS 3
|
||||
#define VCOS_BLOCKPOOL_MAX_SUBPOOLS (1 << VCOS_BLOCKPOOL_SUBPOOL_BITS)
|
||||
|
||||
/* Make zero an invalid handle at the cost of decreasing the maximum
|
||||
* number of blocks (2^28) by 1. Alternatively, a spare bit could be
|
||||
* used to indicated valid blocks but there are likely to be better
|
||||
* uses for spare bits. e.g. allowing more subpools
|
||||
*/
|
||||
#define INDEX_OFFSET 1
|
||||
|
||||
#define VCOS_BLOCKPOOL_HANDLE_GET_INDEX(h) \
|
||||
(((h) >> VCOS_BLOCKPOOL_SUBPOOL_BITS) - INDEX_OFFSET)
|
||||
|
||||
#define VCOS_BLOCKPOOL_HANDLE_GET_SUBPOOL(h) \
|
||||
((h) & ((1 << VCOS_BLOCKPOOL_SUBPOOL_BITS) - 1))
|
||||
|
||||
#define VCOS_BLOCKPOOL_HANDLE_CREATE(i,s) \
|
||||
((((i) + INDEX_OFFSET) << VCOS_BLOCKPOOL_SUBPOOL_BITS) | (s))
|
||||
|
||||
#define VCOS_BLOCKPOOL_INVALID_HANDLE 0
|
||||
#define VCOS_BLOCKPOOL_ALIGN_DEFAULT sizeof(unsigned long)
|
||||
#define VCOS_BLOCKPOOL_FLAG_NONE 0
|
||||
|
||||
typedef struct VCOS_BLOCKPOOL_HEADER_TAG
|
||||
{
|
||||
/* Blocks either refer to to the pool if they are allocated
|
||||
* or the free list if they are available.
|
||||
*/
|
||||
union {
|
||||
struct VCOS_BLOCKPOOL_HEADER_TAG *next;
|
||||
struct VCOS_BLOCKPOOL_SUBPOOL_TAG* subpool;
|
||||
} owner;
|
||||
} VCOS_BLOCKPOOL_HEADER_T;
|
||||
|
||||
typedef struct VCOS_BLOCKPOOL_SUBPOOL_TAG
|
||||
{
|
||||
/** VCOS_BLOCKPOOL_SUBPOOL_MAGIC */
|
||||
uint32_t magic;
|
||||
VCOS_BLOCKPOOL_HEADER_T* free_list;
|
||||
/* The start of the pool memory */
|
||||
void *mem;
|
||||
/* Address of the first block header */
|
||||
void *start;
|
||||
/* The end of the subpool */
|
||||
void *end;
|
||||
/** The number of blocks in this sub-pool */
|
||||
VCOS_UNSIGNED num_blocks;
|
||||
/** Current number of available blocks in this sub-pool */
|
||||
VCOS_UNSIGNED available_blocks;
|
||||
/** Pointers to the pool that owns this sub-pool */
|
||||
struct VCOS_BLOCKPOOL_TAG* owner;
|
||||
/** Define properties such as memory ownership */
|
||||
uint32_t flags;
|
||||
} VCOS_BLOCKPOOL_SUBPOOL_T;
|
||||
|
||||
typedef struct VCOS_BLOCKPOOL_TAG
|
||||
{
|
||||
/** VCOS_BLOCKPOOL_MAGIC */
|
||||
uint32_t magic;
|
||||
/** Thread safety for Alloc, Free, Delete, Stats */
|
||||
VCOS_MUTEX_T mutex;
|
||||
/** Alignment of block data pointers */
|
||||
VCOS_UNSIGNED align;
|
||||
/** Flags for future use e.g. cache options */
|
||||
VCOS_UNSIGNED flags;
|
||||
/** The size of the block data */
|
||||
size_t block_data_size;
|
||||
/** Block size inc overheads */
|
||||
size_t block_size;
|
||||
/** Name for debugging */
|
||||
const char *name;
|
||||
/* The number of subpools that may be used */
|
||||
VCOS_UNSIGNED num_subpools;
|
||||
/** Number of blocks in each dynamically allocated subpool */
|
||||
VCOS_UNSIGNED num_extension_blocks;
|
||||
/** Array of subpools. Subpool zero is is not deleted until the pool is
|
||||
* destroed. If the index of the pool is < num_subpools and
|
||||
* subpool[index.mem] is null then the subpool entry is valid but
|
||||
* "not currently allocated" */
|
||||
VCOS_BLOCKPOOL_SUBPOOL_T subpools[VCOS_BLOCKPOOL_MAX_SUBPOOLS];
|
||||
} VCOS_BLOCKPOOL_T;
|
||||
|
||||
#define VCOS_BLOCKPOOL_ROUND_UP(x,s) (((x) + ((s) - 1)) & ~((s) - 1))
|
||||
/**
|
||||
* Calculates the size in bytes required for a block pool containing
|
||||
* num_blocks of size block_size plus any overheads.
|
||||
*
|
||||
* The block pool header (VCOS_BLOCKPOOL_T) is allocated separately
|
||||
*
|
||||
* Overheads:
|
||||
* block_size + header must be rounded up to meet the required alignment
|
||||
* The start of the first block may need to be up to align bytes
|
||||
* into the given buffer because statically allocated buffers within structures
|
||||
* are not guaranteed to be aligned as required.
|
||||
*/
|
||||
#define VCOS_BLOCKPOOL_SIZE(num_blocks, block_size, align) \
|
||||
((VCOS_BLOCKPOOL_ROUND_UP((block_size) + (align >= 4096 ? 32 : 0) + sizeof(VCOS_BLOCKPOOL_HEADER_T), \
|
||||
(align)) * (num_blocks)) + (align))
|
||||
|
||||
/**
|
||||
* Sanity check to verify whether a handle is potentially a blockpool handle
|
||||
* when the pool pointer is not available.
|
||||
*
|
||||
* If the pool pointer is availabe use vcos_blockpool_elem_to_handle instead.
|
||||
*
|
||||
* @param handle the handle to verify
|
||||
* @param max_blocks the expected maximum number of block in the pool
|
||||
* that the handle belongs to.
|
||||
*/
|
||||
#define VCOS_BLOCKPOOL_IS_VALID_HANDLE_FORMAT(handle, max_blocks) \
|
||||
((handle) != VCOS_BLOCKPOOL_INVALID_HANDLE \
|
||||
&& VCOS_BLOCKPOOL_HANDLE_GET_INDEX((handle)) < (max_blocks))
|
||||
|
||||
VCOSPRE_
|
||||
VCOS_STATUS_T VCOSPOST_ vcos_generic_blockpool_init(VCOS_BLOCKPOOL_T *pool,
|
||||
VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size,
|
||||
void *start, VCOS_UNSIGNED pool_size,
|
||||
VCOS_UNSIGNED align, VCOS_UNSIGNED flags,
|
||||
const char *name);
|
||||
|
||||
VCOSPRE_
|
||||
VCOS_STATUS_T VCOSPOST_ vcos_generic_blockpool_create_on_heap(
|
||||
VCOS_BLOCKPOOL_T *pool, VCOS_UNSIGNED num_blocks,
|
||||
VCOS_UNSIGNED block_size,
|
||||
VCOS_UNSIGNED align, VCOS_UNSIGNED flags,
|
||||
const char *name);
|
||||
|
||||
VCOSPRE_
|
||||
VCOS_STATUS_T VCOSPOST_ vcos_generic_blockpool_extend(VCOS_BLOCKPOOL_T *pool,
|
||||
VCOS_UNSIGNED num_extensions, VCOS_UNSIGNED num_blocks);
|
||||
|
||||
VCOSPRE_ void VCOSPOST_ *vcos_generic_blockpool_alloc(VCOS_BLOCKPOOL_T *pool);
|
||||
|
||||
VCOSPRE_ void VCOSPOST_ *vcos_generic_blockpool_calloc(VCOS_BLOCKPOOL_T *pool);
|
||||
|
||||
VCOSPRE_ void VCOSPOST_ vcos_generic_blockpool_free(void *block);
|
||||
|
||||
VCOSPRE_
|
||||
VCOS_UNSIGNED VCOSPOST_ vcos_generic_blockpool_available_count(
|
||||
VCOS_BLOCKPOOL_T *pool);
|
||||
|
||||
VCOSPRE_
|
||||
VCOS_UNSIGNED VCOSPOST_ vcos_generic_blockpool_used_count(
|
||||
VCOS_BLOCKPOOL_T *pool);
|
||||
|
||||
VCOSPRE_ void VCOSPOST_ vcos_generic_blockpool_delete(VCOS_BLOCKPOOL_T *pool);
|
||||
|
||||
VCOSPRE_ uint32_t VCOSPOST_ vcos_generic_blockpool_elem_to_handle(void *block);
|
||||
|
||||
VCOSPRE_ void VCOSPOST_
|
||||
*vcos_generic_blockpool_elem_from_handle(
|
||||
VCOS_BLOCKPOOL_T *pool, uint32_t handle);
|
||||
|
||||
VCOSPRE_ uint32_t VCOSPOST_
|
||||
vcos_generic_blockpool_is_valid_elem(
|
||||
VCOS_BLOCKPOOL_T *pool, const void *block);
|
||||
#if defined(VCOS_INLINE_BODIES)
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_blockpool_init(VCOS_BLOCKPOOL_T *pool,
|
||||
VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size,
|
||||
void *start, VCOS_UNSIGNED pool_size,
|
||||
VCOS_UNSIGNED align, VCOS_UNSIGNED flags, const char *name)
|
||||
{
|
||||
return vcos_generic_blockpool_init(pool, num_blocks, block_size,
|
||||
start, pool_size, align, flags, name);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_blockpool_create_on_heap(VCOS_BLOCKPOOL_T *pool,
|
||||
VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size,
|
||||
VCOS_UNSIGNED align, VCOS_UNSIGNED flags, const char *name)
|
||||
{
|
||||
return vcos_generic_blockpool_create_on_heap(
|
||||
pool, num_blocks, block_size, align, flags, name);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T VCOSPOST_ vcos_blockpool_extend(VCOS_BLOCKPOOL_T *pool,
|
||||
VCOS_UNSIGNED num_extensions, VCOS_UNSIGNED num_blocks)
|
||||
{
|
||||
return vcos_generic_blockpool_extend(pool, num_extensions, num_blocks);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void *vcos_blockpool_alloc(VCOS_BLOCKPOOL_T *pool)
|
||||
{
|
||||
return vcos_generic_blockpool_alloc(pool);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void *vcos_blockpool_calloc(VCOS_BLOCKPOOL_T *pool)
|
||||
{
|
||||
return vcos_generic_blockpool_calloc(pool);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_blockpool_free(void *block)
|
||||
{
|
||||
vcos_generic_blockpool_free(block);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_UNSIGNED vcos_blockpool_available_count(VCOS_BLOCKPOOL_T *pool)
|
||||
{
|
||||
return vcos_generic_blockpool_available_count(pool);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_UNSIGNED vcos_blockpool_used_count(VCOS_BLOCKPOOL_T *pool)
|
||||
{
|
||||
return vcos_generic_blockpool_used_count(pool);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_blockpool_delete(VCOS_BLOCKPOOL_T *pool)
|
||||
{
|
||||
vcos_generic_blockpool_delete(pool);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
uint32_t vcos_blockpool_elem_to_handle(void *block)
|
||||
{
|
||||
return vcos_generic_blockpool_elem_to_handle(block);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void *vcos_blockpool_elem_from_handle(VCOS_BLOCKPOOL_T *pool, uint32_t handle)
|
||||
{
|
||||
return vcos_generic_blockpool_elem_from_handle(pool, handle);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
uint32_t vcos_blockpool_is_valid_elem(VCOS_BLOCKPOOL_T *pool, const void *block)
|
||||
{
|
||||
return vcos_generic_blockpool_is_valid_elem(pool, block);
|
||||
}
|
||||
#endif /* VCOS_INLINE_BODIES */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* VCOS_GENERIC_BLOCKPOOL_H */
|
||||
|
||||
+320
@@ -0,0 +1,320 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - event flags implemented via mutexes
|
||||
=============================================================================*/
|
||||
|
||||
#include "interface/vcos/vcos.h"
|
||||
#include "interface/vcos/generic/vcos_generic_event_flags.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/** A structure created by a thread that waits on the event flags
|
||||
* for a particular combination of flags to arrive.
|
||||
*/
|
||||
typedef struct VCOS_EVENT_WAITER_T
|
||||
{
|
||||
VCOS_UNSIGNED requested_events; /**< The events wanted */
|
||||
VCOS_UNSIGNED actual_events; /**< Actual events found */
|
||||
VCOS_UNSIGNED op; /**< The event operation to be used */
|
||||
VCOS_STATUS_T return_status; /**< The return status the waiter should pass back */
|
||||
VCOS_EVENT_FLAGS_T *flags; /**< Pointer to the original 'flags' structure */
|
||||
VCOS_THREAD_T *thread; /**< Thread waiting */
|
||||
struct VCOS_EVENT_WAITER_T *next;
|
||||
} VCOS_EVENT_WAITER_T;
|
||||
|
||||
#ifndef NDEBUG
|
||||
static int waiter_list_valid(VCOS_EVENT_FLAGS_T *flags);
|
||||
#endif
|
||||
static void event_flags_timer_expired(void *cxt);
|
||||
|
||||
VCOS_STATUS_T vcos_generic_event_flags_create(VCOS_EVENT_FLAGS_T *flags, const char *name)
|
||||
{
|
||||
VCOS_STATUS_T rc;
|
||||
if ((rc=vcos_mutex_create(&flags->lock, name)) != VCOS_SUCCESS)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
flags->events = 0;
|
||||
flags->waiters.head = flags->waiters.tail = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
void vcos_generic_event_flags_set(VCOS_EVENT_FLAGS_T *flags,
|
||||
VCOS_UNSIGNED bitmask,
|
||||
VCOS_OPTION op)
|
||||
{
|
||||
vcos_assert(flags);
|
||||
vcos_mutex_lock(&flags->lock);
|
||||
if (op == VCOS_OR)
|
||||
{
|
||||
flags->events |= bitmask;
|
||||
}
|
||||
else if (op == VCOS_AND)
|
||||
{
|
||||
flags->events &= bitmask;
|
||||
}
|
||||
else
|
||||
{
|
||||
vcos_assert(0);
|
||||
}
|
||||
|
||||
/* Now wake up any threads that have now become signalled. */
|
||||
if (flags->waiters.head != NULL)
|
||||
{
|
||||
VCOS_UNSIGNED consumed_events = 0;
|
||||
VCOS_EVENT_WAITER_T **pcurrent_waiter = &flags->waiters.head;
|
||||
VCOS_EVENT_WAITER_T *prev_waiter = NULL;
|
||||
|
||||
/* Walk the chain of tasks suspend on this event flag group to determine
|
||||
* if any of their requests can be satisfied.
|
||||
*/
|
||||
while ((*pcurrent_waiter) != NULL)
|
||||
{
|
||||
VCOS_EVENT_WAITER_T *curr_waiter = *pcurrent_waiter;
|
||||
|
||||
/* Determine if this request has been satisfied */
|
||||
|
||||
/* First, find the event flags in common. */
|
||||
VCOS_UNSIGNED waiter_satisfied = flags->events & curr_waiter->requested_events;
|
||||
|
||||
/* Second, determine if all the event flags must match */
|
||||
if (curr_waiter->op & VCOS_AND)
|
||||
{
|
||||
/* All requested events must be present */
|
||||
waiter_satisfied = (waiter_satisfied == curr_waiter->requested_events);
|
||||
}
|
||||
|
||||
/* Wake this one up? */
|
||||
if (waiter_satisfied)
|
||||
{
|
||||
|
||||
if (curr_waiter->op & VCOS_CONSUME)
|
||||
{
|
||||
consumed_events |= curr_waiter->requested_events;
|
||||
}
|
||||
|
||||
/* remove this block from the list, taking care at the end */
|
||||
*pcurrent_waiter = curr_waiter->next;
|
||||
if (curr_waiter->next == NULL)
|
||||
flags->waiters.tail = prev_waiter;
|
||||
|
||||
vcos_assert(waiter_list_valid(flags));
|
||||
|
||||
curr_waiter->return_status = VCOS_SUCCESS;
|
||||
curr_waiter->actual_events = flags->events;
|
||||
|
||||
_vcos_thread_sem_post(curr_waiter->thread);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* move to next element in the list */
|
||||
prev_waiter = *pcurrent_waiter;
|
||||
pcurrent_waiter = &(curr_waiter->next);
|
||||
}
|
||||
}
|
||||
|
||||
flags->events &= ~consumed_events;
|
||||
|
||||
}
|
||||
|
||||
vcos_mutex_unlock(&flags->lock);
|
||||
}
|
||||
|
||||
void vcos_generic_event_flags_delete(VCOS_EVENT_FLAGS_T *flags)
|
||||
{
|
||||
vcos_mutex_delete(&flags->lock);
|
||||
}
|
||||
|
||||
extern VCOS_STATUS_T vcos_generic_event_flags_get(VCOS_EVENT_FLAGS_T *flags,
|
||||
VCOS_UNSIGNED bitmask,
|
||||
VCOS_OPTION op,
|
||||
VCOS_UNSIGNED suspend,
|
||||
VCOS_UNSIGNED *retrieved_bits)
|
||||
{
|
||||
VCOS_EVENT_WAITER_T waitreq;
|
||||
VCOS_STATUS_T rc = VCOS_EAGAIN;
|
||||
int satisfied = 0;
|
||||
|
||||
vcos_assert(flags);
|
||||
|
||||
/* default retrieved bits to 0 */
|
||||
*retrieved_bits = 0;
|
||||
|
||||
vcos_mutex_lock(&flags->lock);
|
||||
switch (op & VCOS_EVENT_FLAG_OP_MASK)
|
||||
{
|
||||
case VCOS_AND:
|
||||
if ((flags->events & bitmask) == bitmask)
|
||||
{
|
||||
*retrieved_bits = flags->events;
|
||||
rc = VCOS_SUCCESS;
|
||||
satisfied = 1;
|
||||
if (op & VCOS_CONSUME)
|
||||
flags->events &= ~bitmask;
|
||||
}
|
||||
break;
|
||||
|
||||
case VCOS_OR:
|
||||
if (flags->events & bitmask)
|
||||
{
|
||||
*retrieved_bits = flags->events;
|
||||
rc = VCOS_SUCCESS;
|
||||
satisfied = 1;
|
||||
if (op & VCOS_CONSUME)
|
||||
flags->events &= ~bitmask;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
vcos_assert(0);
|
||||
rc = VCOS_EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!satisfied && suspend)
|
||||
{
|
||||
/* Have to go to sleep.
|
||||
*
|
||||
* Append to tail so we get FIFO ordering.
|
||||
*/
|
||||
waitreq.requested_events = bitmask;
|
||||
waitreq.op = op;
|
||||
waitreq.return_status = VCOS_EAGAIN;
|
||||
waitreq.flags = flags;
|
||||
waitreq.actual_events = 0;
|
||||
waitreq.thread = vcos_thread_current();
|
||||
waitreq.next = 0;
|
||||
vcos_assert(waitreq.thread != (VCOS_THREAD_T*)-1);
|
||||
VCOS_QUEUE_APPEND_TAIL(&flags->waiters, &waitreq);
|
||||
|
||||
if (suspend != (VCOS_UNSIGNED)-1)
|
||||
_vcos_task_timer_set(event_flags_timer_expired, &waitreq, suspend);
|
||||
|
||||
vcos_mutex_unlock(&flags->lock);
|
||||
/* go to sleep and wait to be signalled or timeout */
|
||||
|
||||
_vcos_thread_sem_wait();
|
||||
|
||||
*retrieved_bits = waitreq.actual_events;
|
||||
rc = waitreq.return_status;
|
||||
|
||||
/* cancel the timer - do not do this while holding the mutex as it
|
||||
* might be waiting for the timeout function to complete, which will
|
||||
* try to take the mutex.
|
||||
*/
|
||||
if (suspend != (VCOS_UNSIGNED)-1)
|
||||
_vcos_task_timer_cancel();
|
||||
}
|
||||
else
|
||||
{
|
||||
vcos_mutex_unlock(&flags->lock);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/** Called when a get call times out. Remove this thread's
|
||||
* entry from the waiting queue, then resume the thread.
|
||||
*/
|
||||
static void event_flags_timer_expired(void *cxt)
|
||||
{
|
||||
VCOS_EVENT_WAITER_T *waitreq = (VCOS_EVENT_WAITER_T *)cxt;
|
||||
VCOS_EVENT_FLAGS_T *flags = waitreq->flags;
|
||||
VCOS_EVENT_WAITER_T **plist;
|
||||
VCOS_EVENT_WAITER_T *prev = NULL;
|
||||
VCOS_THREAD_T *thread = 0;
|
||||
|
||||
vcos_assert(flags);
|
||||
|
||||
vcos_mutex_lock(&flags->lock);
|
||||
|
||||
/* walk the list of waiting threads on this event group, and remove
|
||||
* the one that has expired.
|
||||
*
|
||||
* FIXME: could use doubly-linked list if lots of threads are found
|
||||
* to be waiting on a single event flag instance.
|
||||
*/
|
||||
plist = &flags->waiters.head;
|
||||
while (*plist != NULL)
|
||||
{
|
||||
if (*plist == waitreq)
|
||||
{
|
||||
int at_end;
|
||||
/* found it */
|
||||
thread = (*plist)->thread;
|
||||
at_end = ((*plist)->next == NULL);
|
||||
|
||||
/* link past */
|
||||
*plist = (*plist)->next;
|
||||
if (at_end)
|
||||
flags->waiters.tail = prev;
|
||||
|
||||
break;
|
||||
}
|
||||
prev = *plist;
|
||||
plist = &(*plist)->next;
|
||||
}
|
||||
vcos_assert(waiter_list_valid(flags));
|
||||
|
||||
vcos_mutex_unlock(&flags->lock);
|
||||
|
||||
if (thread)
|
||||
{
|
||||
_vcos_thread_sem_post(thread);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
static int waiter_list_valid(VCOS_EVENT_FLAGS_T *flags)
|
||||
{
|
||||
int valid;
|
||||
/* Either both head and tail are NULL, or neither are NULL */
|
||||
if (flags->waiters.head == NULL)
|
||||
{
|
||||
valid = (flags->waiters.tail == NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
valid = (flags->waiters.tail != NULL);
|
||||
}
|
||||
|
||||
/* If head and tail point at the same non-NULL element, then there
|
||||
* is only one element in the list.
|
||||
*/
|
||||
if (flags->waiters.head && (flags->waiters.head == flags->waiters.tail))
|
||||
{
|
||||
valid = (flags->waiters.head->next == NULL);
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
#endif
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - event flags implemented via a semaphore
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_GENERIC_EVENT_FLAGS_H
|
||||
#define VCOS_GENERIC_EVENT_FLAGS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This provides event flags (as per Nucleus Event Groups) based on a
|
||||
* mutex, a semaphore (per waiting thread) and a timer (per waiting
|
||||
* thread).
|
||||
*
|
||||
* The data structure is a 32 bit unsigned int (the current set of
|
||||
* flags) and a linked list of clients waiting to be 'satisfied'.
|
||||
*
|
||||
* The mutex merely locks access to the data structure. If a client
|
||||
* calls vcos_event_flags_get() and the requested bits are not already
|
||||
* present, it then sleeps on its per-thread semaphore after adding
|
||||
* this semaphore to the queue waiting. It also sets up a timer.
|
||||
*
|
||||
* The per-thread semaphore and timer are actually stored in the
|
||||
* thread context (joinable thread). In future it may become necessary
|
||||
* to support non-VCOS threads by using thread local storage to
|
||||
* create these objects and associate them with the thread.
|
||||
*/
|
||||
|
||||
struct VCOS_EVENT_WAITER_T;
|
||||
|
||||
typedef struct VCOS_EVENT_FLAGS_T
|
||||
{
|
||||
VCOS_UNSIGNED events; /**< Events currently set */
|
||||
VCOS_MUTEX_T lock; /**< Serialize access */
|
||||
struct
|
||||
{
|
||||
struct VCOS_EVENT_WAITER_T *head; /**< List of threads waiting */
|
||||
struct VCOS_EVENT_WAITER_T *tail; /**< List of threads waiting */
|
||||
} waiters;
|
||||
} VCOS_EVENT_FLAGS_T;
|
||||
|
||||
#define VCOS_OR 1
|
||||
#define VCOS_AND 2
|
||||
#define VCOS_CONSUME 4
|
||||
#define VCOS_OR_CONSUME (VCOS_OR | VCOS_CONSUME)
|
||||
#define VCOS_AND_CONSUME (VCOS_AND | VCOS_CONSUME)
|
||||
#define VCOS_EVENT_FLAG_OP_MASK (VCOS_OR|VCOS_AND)
|
||||
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_generic_event_flags_create(VCOS_EVENT_FLAGS_T *flags, const char *name);
|
||||
VCOSPRE_ void VCOSPOST_ vcos_generic_event_flags_set(VCOS_EVENT_FLAGS_T *flags,
|
||||
VCOS_UNSIGNED events,
|
||||
VCOS_OPTION op);
|
||||
VCOSPRE_ void VCOSPOST_ vcos_generic_event_flags_delete(VCOS_EVENT_FLAGS_T *);
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_generic_event_flags_get(VCOS_EVENT_FLAGS_T *flags,
|
||||
VCOS_UNSIGNED requested_events,
|
||||
VCOS_OPTION op,
|
||||
VCOS_UNSIGNED suspend,
|
||||
VCOS_UNSIGNED *retrieved_events);
|
||||
|
||||
#ifdef VCOS_INLINE_BODIES
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_event_flags_create(VCOS_EVENT_FLAGS_T *flags, const char *name) {
|
||||
return vcos_generic_event_flags_create(flags, name);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_event_flags_set(VCOS_EVENT_FLAGS_T *flags,
|
||||
VCOS_UNSIGNED events,
|
||||
VCOS_OPTION op) {
|
||||
vcos_generic_event_flags_set(flags, events, op);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_event_flags_delete(VCOS_EVENT_FLAGS_T *f) {
|
||||
vcos_generic_event_flags_delete(f);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_event_flags_get(VCOS_EVENT_FLAGS_T *flags,
|
||||
VCOS_UNSIGNED requested_events,
|
||||
VCOS_OPTION op,
|
||||
VCOS_UNSIGNED suspend,
|
||||
VCOS_UNSIGNED *retrieved_events) {
|
||||
return vcos_generic_event_flags_get(flags, requested_events, op, suspend, retrieved_events);
|
||||
}
|
||||
|
||||
#endif /* VCOS_INLINE_BODIES */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+268
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define VCOS_LOG_CATEGORY (&vcos_named_sem_log_cat)
|
||||
|
||||
#include "interface/vcos/vcos.h"
|
||||
#include "interface/vcos/generic/vcos_generic_named_sem.h"
|
||||
#include "interface/vcos/vcos_blockpool.h"
|
||||
|
||||
#if defined(VCOS_LOGGING_ENABLED)
|
||||
static VCOS_LOG_CAT_T vcos_named_sem_log_cat =
|
||||
VCOS_LOG_INIT("vcos_named_sem", VCOS_LOG_ERROR);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Named semaphores, primarily for VCFW.
|
||||
*
|
||||
* Does not actually work across processes; merely emulate the API.
|
||||
*
|
||||
* The client initialises a VCOS_NAMED_SEMAPHORE_T, but this merely
|
||||
* points at the real underlying VCOS_NAMED_SEMAPHORE_IMPL_T.
|
||||
*
|
||||
* semaphore_t ---\
|
||||
* ----- semaphore_impl_t
|
||||
* semaphore_t ---/
|
||||
* /
|
||||
* semaphore_t -/
|
||||
*
|
||||
*/
|
||||
|
||||
/* Maintain a block pool of semaphore implementations */
|
||||
#define NUM_SEMS 16
|
||||
|
||||
/* Allow the pool to expand to MAX_SEMS in size */
|
||||
#define MAX_SEMS 512
|
||||
|
||||
/** Each actual real semaphore is stored in one of these. Clients just
|
||||
* get a structure with a pointer to this in it.
|
||||
*
|
||||
* It also contains a doubly linked list tracking the semaphores in-use.
|
||||
*/
|
||||
typedef struct VCOS_NAMED_SEMAPHORE_IMPL_T
|
||||
{
|
||||
VCOS_SEMAPHORE_T sem; /**< Actual underlying semaphore */
|
||||
char name[VCOS_NAMED_SEMAPHORE_NAMELEN]; /**< Name of semaphore, copied */
|
||||
unsigned refs; /**< Reference count */
|
||||
struct VCOS_NAMED_SEMAPHORE_IMPL_T *next; /**< Next in the in-use list */
|
||||
struct VCOS_NAMED_SEMAPHORE_IMPL_T *prev; /**< Previous in the in-use list */
|
||||
} VCOS_NAMED_SEMAPHORE_IMPL_T;
|
||||
|
||||
static VCOS_MUTEX_T lock;
|
||||
static VCOS_NAMED_SEMAPHORE_IMPL_T* sems_in_use = NULL;
|
||||
static int sems_in_use_count = 0;
|
||||
static int sems_total_ref_count = 0;
|
||||
|
||||
static VCOS_BLOCKPOOL_T sems_pool;
|
||||
static char pool_mem[VCOS_BLOCKPOOL_SIZE(
|
||||
NUM_SEMS, sizeof(VCOS_NAMED_SEMAPHORE_IMPL_T), VCOS_BLOCKPOOL_ALIGN_DEFAULT)];
|
||||
|
||||
VCOS_STATUS_T _vcos_named_semaphore_init()
|
||||
{
|
||||
VCOS_STATUS_T status;
|
||||
|
||||
status = vcos_blockpool_init(&sems_pool,
|
||||
NUM_SEMS, sizeof(VCOS_NAMED_SEMAPHORE_IMPL_T),
|
||||
pool_mem, sizeof(pool_mem),
|
||||
VCOS_BLOCKPOOL_ALIGN_DEFAULT, 0, "vcos named semaphores");
|
||||
|
||||
if (status != VCOS_SUCCESS)
|
||||
goto fail_blockpool;
|
||||
|
||||
status = vcos_blockpool_extend(&sems_pool, VCOS_BLOCKPOOL_MAX_SUBPOOLS - 1,
|
||||
(MAX_SEMS - NUM_SEMS) / (VCOS_BLOCKPOOL_MAX_SUBPOOLS - 1));
|
||||
if (status != VCOS_SUCCESS)
|
||||
goto fail_extend;
|
||||
|
||||
status = vcos_mutex_create(&lock, "vcosnmsem");
|
||||
if (status != VCOS_SUCCESS)
|
||||
goto fail_mutex;
|
||||
|
||||
return status;
|
||||
|
||||
fail_mutex:
|
||||
fail_extend:
|
||||
vcos_blockpool_delete(&sems_pool);
|
||||
fail_blockpool:
|
||||
return status;
|
||||
}
|
||||
|
||||
void _vcos_named_semaphore_deinit(void)
|
||||
{
|
||||
vcos_blockpool_delete(&sems_pool);
|
||||
vcos_mutex_delete(&lock);
|
||||
sems_in_use = NULL;
|
||||
}
|
||||
|
||||
VCOS_STATUS_T
|
||||
vcos_generic_named_semaphore_create(VCOS_NAMED_SEMAPHORE_T *sem,
|
||||
const char *name, VCOS_UNSIGNED count)
|
||||
{
|
||||
VCOS_STATUS_T status = VCOS_ENOSPC;
|
||||
int name_len, cmp = -1;
|
||||
VCOS_NAMED_SEMAPHORE_IMPL_T *impl;
|
||||
VCOS_NAMED_SEMAPHORE_IMPL_T *new_impl;
|
||||
|
||||
vcos_log_trace("%s: sem %p name %s count %d", __FUNCTION__,
|
||||
sem, (name ? name : "null"), count);
|
||||
|
||||
vcos_assert(name);
|
||||
|
||||
vcos_mutex_lock(&lock);
|
||||
name_len = vcos_strlen(name);
|
||||
if (name_len >= VCOS_NAMED_SEMAPHORE_NAMELEN)
|
||||
{
|
||||
vcos_assert(0);
|
||||
status = VCOS_EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* do we already have this semaphore? */
|
||||
impl = sems_in_use;
|
||||
while (impl && (cmp = vcos_strcmp(name, impl->name)) < 0)
|
||||
impl = impl->next;
|
||||
|
||||
if (impl && cmp == 0)
|
||||
{
|
||||
/* Semaphore is already in use so just increase the ref count */
|
||||
impl->refs++;
|
||||
sems_total_ref_count++;
|
||||
sem->actual = impl;
|
||||
sem->sem = &impl->sem;
|
||||
status = VCOS_SUCCESS;
|
||||
vcos_log_trace(
|
||||
"%s: ref count %d name %s total refs %d num sems %d",
|
||||
__FUNCTION__, impl->refs, impl->name,
|
||||
sems_total_ref_count, sems_in_use_count);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* search for unused semaphore */
|
||||
new_impl = vcos_blockpool_calloc(&sems_pool);
|
||||
if (new_impl)
|
||||
{
|
||||
status = vcos_semaphore_create(&new_impl->sem, name, count);
|
||||
if (status == VCOS_SUCCESS)
|
||||
{
|
||||
new_impl->refs = 1;
|
||||
sems_total_ref_count++;
|
||||
sems_in_use_count++;
|
||||
memcpy(new_impl->name, name, name_len + 1); /* already checked length! */
|
||||
sem->actual = new_impl;
|
||||
sem->sem = &new_impl->sem;
|
||||
|
||||
/* Insert into the sorted list
|
||||
* impl is either NULL or the first element where
|
||||
* name > impl->name.
|
||||
*/
|
||||
if (impl)
|
||||
{
|
||||
new_impl->prev = impl->prev;
|
||||
impl->prev = new_impl;
|
||||
new_impl->next = impl;
|
||||
|
||||
if (new_impl->prev)
|
||||
new_impl->prev->next = new_impl;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Appending to the tail of the list / empty list */
|
||||
VCOS_NAMED_SEMAPHORE_IMPL_T *tail = sems_in_use;
|
||||
while(tail && tail->next)
|
||||
tail = tail->next;
|
||||
|
||||
if (tail)
|
||||
{
|
||||
tail->next = new_impl;
|
||||
new_impl->prev = tail;
|
||||
}
|
||||
}
|
||||
|
||||
if (sems_in_use == impl)
|
||||
{
|
||||
/* Inserted at head or list was empty */
|
||||
sems_in_use = new_impl;
|
||||
}
|
||||
|
||||
vcos_log_trace(
|
||||
"%s: new ref actual %p prev %p next %p count %d name %s " \
|
||||
"total refs %d num sems %d",
|
||||
__FUNCTION__,
|
||||
new_impl, new_impl->prev, new_impl->next,
|
||||
new_impl->refs, new_impl->name,
|
||||
sems_total_ref_count, sems_in_use_count);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
vcos_mutex_unlock(&lock);
|
||||
if (status != VCOS_SUCCESS)
|
||||
{
|
||||
vcos_log_error("%s: failed to create named semaphore name %s status %d " \
|
||||
"total refs %d num sems %d",
|
||||
__FUNCTION__, (name ? name : "NULL"), status,
|
||||
sems_total_ref_count, sems_in_use_count);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void vcos_named_semaphore_delete(VCOS_NAMED_SEMAPHORE_T *sem)
|
||||
{
|
||||
VCOS_NAMED_SEMAPHORE_IMPL_T *actual = sem->actual;
|
||||
vcos_mutex_lock(&lock);
|
||||
|
||||
/* if this fires, the semaphore has already been deleted */
|
||||
vcos_assert(actual->refs);
|
||||
|
||||
vcos_log_trace(
|
||||
"%s: actual %p ref count %d name %s prev %p next %p total refs %d num sems %d",
|
||||
__FUNCTION__, actual, actual->refs, actual->name,
|
||||
actual->prev, actual->next,
|
||||
sems_total_ref_count, sems_in_use_count);
|
||||
|
||||
sems_total_ref_count--;
|
||||
if (--actual->refs == 0)
|
||||
{
|
||||
sems_in_use_count--;
|
||||
if (actual->prev)
|
||||
actual->prev->next = actual->next;
|
||||
|
||||
if (actual->next)
|
||||
actual->next->prev = actual->prev;
|
||||
|
||||
if (sems_in_use == actual)
|
||||
sems_in_use = actual->next;
|
||||
|
||||
vcos_semaphore_delete(&actual->sem);
|
||||
sem->actual = NULL;
|
||||
sem->sem = NULL;
|
||||
vcos_blockpool_free(actual);
|
||||
}
|
||||
vcos_mutex_unlock(&lock);
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - named semaphores
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_GENERIC_NAMED_SEM_H
|
||||
#define VCOS_GENERIC_NAMED_SEM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Generic support for named semaphores, using regular ones. This is only
|
||||
* suitable for emulating them on an embedded MMUless system, since there is
|
||||
* no support for opening semaphores across process boundaries.
|
||||
*
|
||||
*/
|
||||
|
||||
#define VCOS_NAMED_SEMAPHORE_NAMELEN 64
|
||||
|
||||
/* In theory we could use the name facility provided within Nucleus. However, this
|
||||
* is hard to do as semaphores are constantly being created and destroyed; we
|
||||
* would need to stop everything while allocating the memory for the semaphore
|
||||
* list and then walking it. So keep our own list.
|
||||
*/
|
||||
typedef struct VCOS_NAMED_SEMAPHORE_T
|
||||
{
|
||||
struct VCOS_NAMED_SEMAPHORE_IMPL_T *actual; /**< There are 'n' named semaphores per 1 actual semaphore */
|
||||
VCOS_SEMAPHORE_T *sem; /**< Pointer to actual underlying semaphore */
|
||||
} VCOS_NAMED_SEMAPHORE_T;
|
||||
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_
|
||||
vcos_generic_named_semaphore_create(VCOS_NAMED_SEMAPHORE_T *sem, const char *name, VCOS_UNSIGNED count);
|
||||
|
||||
VCOSPRE_ void VCOSPOST_ vcos_named_semaphore_delete(VCOS_NAMED_SEMAPHORE_T *sem);
|
||||
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ _vcos_named_semaphore_init(void);
|
||||
VCOSPRE_ void VCOSPOST_ _vcos_named_semaphore_deinit(void);
|
||||
|
||||
#if defined(VCOS_INLINE_BODIES)
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_named_semaphore_create(VCOS_NAMED_SEMAPHORE_T *sem, const char *name, VCOS_UNSIGNED count) {
|
||||
return vcos_generic_named_semaphore_create(sem, name, count);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_named_semaphore_wait(VCOS_NAMED_SEMAPHORE_T *sem) {
|
||||
vcos_semaphore_wait(sem->sem);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_named_semaphore_trywait(VCOS_NAMED_SEMAPHORE_T *sem) {
|
||||
return vcos_semaphore_trywait(sem->sem);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_named_semaphore_post(VCOS_NAMED_SEMAPHORE_T *sem) {
|
||||
vcos_semaphore_post(sem->sem);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - reentrant mutexes created from regular ones.
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_GENERIC_QUICKSLOW_MUTEX_H
|
||||
#define VCOS_GENERIC_QUICKSLOW_MUTEX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Quickslow Mutexes implemented as regular ones (i.e. quick and slow modes are the same).
|
||||
*
|
||||
*/
|
||||
|
||||
typedef VCOS_MUTEX_T VCOS_QUICKSLOW_MUTEX_T;
|
||||
|
||||
#if defined(VCOS_INLINE_BODIES)
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_quickslow_mutex_create(VCOS_QUICKSLOW_MUTEX_T *m, const char *name)
|
||||
{
|
||||
return vcos_mutex_create(m, name);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_quickslow_mutex_delete(VCOS_QUICKSLOW_MUTEX_T *m)
|
||||
{
|
||||
vcos_mutex_delete(m);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_quickslow_mutex_lock(VCOS_QUICKSLOW_MUTEX_T *m)
|
||||
{
|
||||
while (vcos_mutex_lock(m) == VCOS_EAGAIN);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_quickslow_mutex_unlock(VCOS_QUICKSLOW_MUTEX_T *m)
|
||||
{
|
||||
vcos_mutex_unlock(m);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_quickslow_mutex_lock_quick(VCOS_QUICKSLOW_MUTEX_T *m)
|
||||
{
|
||||
while (vcos_mutex_lock(m) == VCOS_EAGAIN);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_quickslow_mutex_unlock_quick(VCOS_QUICKSLOW_MUTEX_T *m)
|
||||
{
|
||||
vcos_mutex_unlock(m);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "interface/vcos/vcos.h"
|
||||
#include "interface/vcos/vcos_reentrant_mutex.h"
|
||||
|
||||
VCOS_STATUS_T vcos_generic_reentrant_mutex_create(VCOS_REENTRANT_MUTEX_T *m, const char *name)
|
||||
{
|
||||
m->count = 0;
|
||||
m->owner = 0;
|
||||
return vcos_mutex_create(&m->mutex, name);
|
||||
}
|
||||
|
||||
void vcos_generic_reentrant_mutex_delete(VCOS_REENTRANT_MUTEX_T *m)
|
||||
{
|
||||
vcos_assert(m->count == 0);
|
||||
vcos_mutex_delete(&m->mutex);
|
||||
}
|
||||
|
||||
void vcos_generic_reentrant_mutex_lock(VCOS_REENTRANT_MUTEX_T *m)
|
||||
{
|
||||
VCOS_THREAD_T *thread = vcos_thread_current();
|
||||
vcos_assert(m);
|
||||
|
||||
vcos_assert(thread != 0);
|
||||
|
||||
if (m->owner != thread)
|
||||
{
|
||||
vcos_mutex_lock(&m->mutex);
|
||||
m->owner = thread;
|
||||
vcos_assert(m->count == 0);
|
||||
}
|
||||
m->count++;
|
||||
}
|
||||
|
||||
void vcos_generic_reentrant_mutex_unlock(VCOS_REENTRANT_MUTEX_T *m)
|
||||
{
|
||||
vcos_assert(m->count != 0);
|
||||
vcos_assert(m->owner == vcos_thread_current());
|
||||
m->count--;
|
||||
if (m->count == 0)
|
||||
{
|
||||
m->owner = 0;
|
||||
vcos_mutex_unlock(&m->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - reentrant mutexes created from regular ones.
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_GENERIC_REENTRANT_MUTEX_H
|
||||
#define VCOS_GENERIC_REENTRANT_MUTEX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Reentrant Mutexes from regular ones.
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct VCOS_REENTRANT_MUTEX_T
|
||||
{
|
||||
VCOS_MUTEX_T mutex;
|
||||
VCOS_THREAD_T *owner;
|
||||
unsigned count;
|
||||
} VCOS_REENTRANT_MUTEX_T;
|
||||
|
||||
/* Extern definitions of functions that do the actual work */
|
||||
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_generic_reentrant_mutex_create(VCOS_REENTRANT_MUTEX_T *m, const char *name);
|
||||
|
||||
VCOSPRE_ void VCOSPOST_ vcos_generic_reentrant_mutex_delete(VCOS_REENTRANT_MUTEX_T *m);
|
||||
|
||||
VCOSPRE_ void VCOSPOST_ vcos_generic_reentrant_mutex_lock(VCOS_REENTRANT_MUTEX_T *m);
|
||||
|
||||
VCOSPRE_ void VCOSPOST_ vcos_generic_reentrant_mutex_unlock(VCOS_REENTRANT_MUTEX_T *m);
|
||||
|
||||
/* Inline forwarding functions */
|
||||
|
||||
#if defined(VCOS_INLINE_BODIES)
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_reentrant_mutex_create(VCOS_REENTRANT_MUTEX_T *m, const char *name) {
|
||||
return vcos_generic_reentrant_mutex_create(m,name);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_reentrant_mutex_delete(VCOS_REENTRANT_MUTEX_T *m) {
|
||||
vcos_generic_reentrant_mutex_delete(m);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_reentrant_mutex_lock(VCOS_REENTRANT_MUTEX_T *m) {
|
||||
vcos_generic_reentrant_mutex_lock(m);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_reentrant_mutex_unlock(VCOS_REENTRANT_MUTEX_T *m) {
|
||||
vcos_generic_reentrant_mutex_unlock(m);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*****************************************************************************
|
||||
* Copyright 2012 Broadcom Corporation. All rights reserved.
|
||||
*
|
||||
* This program is the proprietary software of Broadcom Corporation and/or
|
||||
* its licensors, and may only be used, duplicated, modified or distributed
|
||||
* pursuant to the terms and conditions of a separate, written license
|
||||
* agreement executed between you and Broadcom (an "Authorized License").
|
||||
* Except as set forth in an Authorized License, Broadcom grants no license
|
||||
* (express or implied), right to use, or waiver of any kind with respect to
|
||||
* the Software, and Broadcom expressly reserves all rights in and to the
|
||||
* Software and all intellectual property rights therein. IF YOU HAVE NO
|
||||
* AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY
|
||||
* WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE ALL USE OF
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* Except as expressly set forth in the Authorized License,
|
||||
* 1. This program, including its structure, sequence and organization,
|
||||
* constitutes the valuable trade secrets of Broadcom, and you shall use
|
||||
* all reasonable efforts to protect the confidentiality thereof, and to
|
||||
* use this information only in connection with your use of Broadcom
|
||||
* integrated circuit products.
|
||||
* 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
|
||||
* AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
|
||||
* WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
|
||||
* RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL
|
||||
* IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS,
|
||||
* QUIET ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE TO DESCRIPTION. YOU
|
||||
* ASSUME THE ENTIRE RISK ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
|
||||
* 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
|
||||
* LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT,
|
||||
* OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO
|
||||
* YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS
|
||||
* OF THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER
|
||||
* IS GREATER. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF
|
||||
* ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "interface/vcos/vcos.h"
|
||||
|
||||
#if defined( __KERNEL__ )
|
||||
#include <linux/string.h>
|
||||
#include <linux/module.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
/** Like vsnprintf, except it places the output at the specified offset.
|
||||
* Output is truncated to fit in buflen bytes, and is guaranteed to be NUL-terminated.
|
||||
* Returns the string length before/without truncation.
|
||||
*/
|
||||
size_t vcos_safe_vsprintf(char *buf, size_t buflen, size_t offset, const char *fmt, va_list ap)
|
||||
{
|
||||
size_t space = (offset < buflen) ? (buflen - offset) : 0;
|
||||
|
||||
offset += vcos_vsnprintf(buf ? (buf + offset) : NULL, space, fmt, ap);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/** Like snprintf, except it places the output at the specified offset.
|
||||
* Output is truncated to fit in buflen bytes, and is guaranteed to be NUL-terminated.
|
||||
* Returns the string length before/without truncation.
|
||||
*/
|
||||
size_t vcos_safe_sprintf(char *buf, size_t buflen, size_t offset, const char *fmt, ...)
|
||||
{
|
||||
size_t space = (offset < buflen) ? (buflen - offset) : 0;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
offset += vcos_vsnprintf(buf ? (buf + offset) : NULL, space, fmt, ap);
|
||||
|
||||
va_end(ap);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/** Copies string src to dst at the specified offset.
|
||||
* Output is truncated to fit in dstlen bytes, i.e. the string is at most
|
||||
* (buflen - 1) characters long. Unlike strncpy, exactly one NUL is written
|
||||
* to dst, which is always NUL-terminated.
|
||||
* Returns the string length before/without truncation.
|
||||
*/
|
||||
size_t vcos_safe_strcpy(char *dst, const char *src, size_t dstlen, size_t offset)
|
||||
{
|
||||
if (offset < dstlen)
|
||||
{
|
||||
const char *p = src;
|
||||
char *endp = dst + dstlen -1;
|
||||
|
||||
dst += offset;
|
||||
|
||||
for (; *p!='\0' && dst != endp; dst++, p++)
|
||||
*dst = *p;
|
||||
*dst = '\0';
|
||||
}
|
||||
offset += strlen(src);
|
||||
|
||||
return offset;
|
||||
}
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - generic thread local storage
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_GENERIC_TLS_H
|
||||
#define VCOS_GENERIC_TLS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "interface/vcos/vcos_types.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Do an emulation of Thread Local Storage. The platform needs to
|
||||
* provide a way to set and get a per-thread pointer which is
|
||||
* where the TLS data itself is stored.
|
||||
*
|
||||
*
|
||||
* Each thread that wants to join in this scheme needs to call
|
||||
* vcos_tls_thread_register().
|
||||
*
|
||||
* The platform needs to support the macros/functions
|
||||
* _vcos_tls_thread_ptr_set() and _vcos_tls_thread_ptr_get().
|
||||
*/
|
||||
|
||||
#ifndef VCOS_WANT_TLS_EMULATION
|
||||
#error Should not be included unless TLS emulation is defined
|
||||
#endif
|
||||
|
||||
/** Number of slots to reserve per thread. This results in an overhead
|
||||
* of this many words per thread.
|
||||
*/
|
||||
#define VCOS_TLS_MAX_SLOTS 4
|
||||
|
||||
/** TLS key. Allocating one of these reserves the client one of the
|
||||
* available slots.
|
||||
*/
|
||||
typedef VCOS_UNSIGNED VCOS_TLS_KEY_T;
|
||||
|
||||
/** TLS per-thread structure. Each thread gets one of these
|
||||
* if TLS emulation (rather than native TLS support) is
|
||||
* being used.
|
||||
*/
|
||||
typedef struct VCOS_TLS_THREAD_T
|
||||
{
|
||||
void *slots[VCOS_TLS_MAX_SLOTS];
|
||||
} VCOS_TLS_THREAD_T;
|
||||
|
||||
/*
|
||||
* Internal APIs
|
||||
*/
|
||||
|
||||
/** Register this thread's TLS storage area. */
|
||||
VCOSPRE_ void VCOSPOST_ vcos_tls_thread_register(VCOS_TLS_THREAD_T *);
|
||||
|
||||
/** Create a new TLS key */
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_generic_tls_create(VCOS_TLS_KEY_T *key);
|
||||
|
||||
/** Delete a TLS key */
|
||||
VCOSPRE_ void VCOSPOST_ vcos_generic_tls_delete(VCOS_TLS_KEY_T tls);
|
||||
|
||||
/** Initialise the TLS library */
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_tls_init(void);
|
||||
|
||||
/** Deinitialise the TLS library */
|
||||
VCOSPRE_ void VCOSPOST_ vcos_tls_deinit(void);
|
||||
|
||||
#if defined(VCOS_INLINE_BODIES)
|
||||
|
||||
#undef VCOS_ASSERT_LOGGING_DISABLE
|
||||
#define VCOS_ASSERT_LOGGING_DISABLE 1
|
||||
|
||||
/*
|
||||
* Implementations of public API functions
|
||||
*/
|
||||
|
||||
/** Set the given value. Since everything is per-thread, there is no need
|
||||
* for any locking.
|
||||
*/
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_tls_set(VCOS_TLS_KEY_T tls, void *v) {
|
||||
VCOS_TLS_THREAD_T *tlsdata = _vcos_tls_thread_ptr_get();
|
||||
vcos_assert(tlsdata); /* Fires if this thread has not been registered */
|
||||
if (tls<VCOS_TLS_MAX_SLOTS)
|
||||
{
|
||||
tlsdata->slots[tls] = v;
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
vcos_assert(0);
|
||||
return VCOS_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the given value. No locking required.
|
||||
*/
|
||||
VCOS_INLINE_IMPL
|
||||
void *vcos_tls_get(VCOS_TLS_KEY_T tls) {
|
||||
VCOS_TLS_THREAD_T *tlsdata = _vcos_tls_thread_ptr_get();
|
||||
vcos_assert(tlsdata); /* Fires if this thread has not been registered */
|
||||
if (tls<VCOS_TLS_MAX_SLOTS)
|
||||
{
|
||||
return tlsdata->slots[tls];
|
||||
}
|
||||
else
|
||||
{
|
||||
vcos_assert(0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_tls_create(VCOS_TLS_KEY_T *key) {
|
||||
return vcos_generic_tls_create(key);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_tls_delete(VCOS_TLS_KEY_T tls) {
|
||||
vcos_generic_tls_delete(tls);
|
||||
}
|
||||
|
||||
#undef VCOS_ASSERT_LOGGING_DISABLE
|
||||
#define VCOS_ASSERT_LOGGING_DISABLE 0
|
||||
|
||||
#endif /* VCOS_INLINE_BODIES */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
The following header is included in order to provide one instance of the symbol vcos_deprecated_code.
|
||||
Any other inclusions of this header (or "vcos_deprecated_code.inc" for assembly language) will cause the linker to warn
|
||||
about multiple definitions of vcos_deprecated_code.
|
||||
The idea is to include this header file for the source files which are deprecated.
|
||||
Therefore the above warnning in a build indicates that the build is using deprecated code!
|
||||
Contact the person named in the accompanying comment for advice - do not remove the inclusion.
|
||||
*/
|
||||
#include "vcos_deprecated.h"
|
||||
|
||||
#include "interface/vcos/vcos.h"
|
||||
|
||||
static int init_refcount;
|
||||
|
||||
VCOS_STATUS_T vcos_init(void)
|
||||
{
|
||||
VCOS_STATUS_T st = VCOS_SUCCESS;
|
||||
|
||||
vcos_global_lock();
|
||||
|
||||
if (init_refcount++ == 0)
|
||||
st = vcos_platform_init();
|
||||
|
||||
vcos_global_unlock();
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
void vcos_deinit(void)
|
||||
{
|
||||
vcos_global_lock();
|
||||
|
||||
vcos_assert(init_refcount > 0);
|
||||
|
||||
if (init_refcount > 0 && --init_refcount == 0)
|
||||
vcos_platform_deinit();
|
||||
|
||||
vcos_global_unlock();
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ > 2)
|
||||
|
||||
void vcos_ctor(void) __attribute__((constructor, used));
|
||||
|
||||
void vcos_ctor(void)
|
||||
{
|
||||
vcos_init();
|
||||
}
|
||||
|
||||
void vcos_dtor(void) __attribute__((destructor, used));
|
||||
|
||||
void vcos_dtor(void)
|
||||
{
|
||||
vcos_deinit();
|
||||
}
|
||||
|
||||
#endif
|
||||
Vendored
+229
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - implementation: joinable thread from plain
|
||||
=============================================================================*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for platforms creating the joinable thread from a lowlevel
|
||||
* thread.
|
||||
*
|
||||
* In addition to the actual thread, the following are also created:
|
||||
*
|
||||
* - a semaphore to wait on when joining the thread
|
||||
* - a semaphore to support counted suspend/resume (used by event group)
|
||||
* - a per-thread timer (used by event group, but could be removed)
|
||||
*/
|
||||
|
||||
#ifndef VCOS_JOINABLE_THREAD_FROM_PLAIN_H
|
||||
#define VCOS_JOINABLE_THREAD_FROM_PLAIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_SEMAPHORE_H
|
||||
#include "interface/vcos/vcos_semaphore.h"
|
||||
#endif
|
||||
#ifndef VCOS_LOWLEVEL_THREAD_H
|
||||
#include "interface/vcos/vcos_lowlevel_thread.h"
|
||||
#endif
|
||||
#ifndef VCOS_TIMER_H
|
||||
#include "interface/vcos/vcos_timer.h"
|
||||
#endif
|
||||
|
||||
#ifdef VCOS_WANT_TLS_EMULATION
|
||||
#include "interface/vcos/generic/vcos_generic_tls.h"
|
||||
#endif
|
||||
|
||||
#define VCOS_THREAD_MAGIC 0x56436a74
|
||||
|
||||
#define VCOS_THREAD_VALID(t) (t->magic == VCOS_THREAD_MAGIC)
|
||||
#define VCOS_HAVE_THREAD_AT_EXIT 1
|
||||
|
||||
/** Thread attribute structure. Clients should not manipulate this directly, but
|
||||
* should instead use the provided functions.
|
||||
*/
|
||||
typedef struct VCOS_THREAD_ATTR_T
|
||||
{
|
||||
void *ta_stackaddr;
|
||||
VCOS_UNSIGNED ta_stacksz;
|
||||
VCOS_UNSIGNED ta_priority;
|
||||
VCOS_UNSIGNED ta_affinity;
|
||||
VCOS_UNSIGNED ta_timeslice;
|
||||
VCOS_UNSIGNED legacy;
|
||||
VCOS_UNSIGNED ta_autostart;
|
||||
} VCOS_THREAD_ATTR_T;
|
||||
|
||||
/** Each thread gets a timer, which is for internal VCOS use.
|
||||
*/
|
||||
typedef struct _VCOS_THREAD_TIMER_T
|
||||
{
|
||||
VCOS_TIMER_T timer;
|
||||
void (*pfn)(void *);
|
||||
void *cxt;
|
||||
} _VCOS_THREAD_TIMER_T;
|
||||
|
||||
typedef void (*VCOS_THREAD_EXIT_HANDLER_T)(void *);
|
||||
/** Called at thread exit.
|
||||
*/
|
||||
typedef struct VCOS_THREAD_EXIT_T
|
||||
{
|
||||
VCOS_THREAD_EXIT_HANDLER_T pfn;
|
||||
void *cxt;
|
||||
} VCOS_THREAD_EXIT_T;
|
||||
#define VCOS_MAX_EXIT_HANDLERS 8
|
||||
|
||||
/* The name field isn't used for anything, so we can just copy the
|
||||
* the pointer. Nucleus makes its own copy.
|
||||
*/
|
||||
typedef const char * VCOS_LLTHREAD_T_NAME;
|
||||
#define _VCOS_LLTHREAD_NAME(dst,src) (dst)=(src)
|
||||
|
||||
/*
|
||||
* Simulated TLS support
|
||||
*/
|
||||
|
||||
|
||||
/** Thread structure.
|
||||
*
|
||||
* \warning Do not access the members of this structure directly!
|
||||
*/
|
||||
typedef struct VCOS_THREAD_T
|
||||
{
|
||||
VCOS_LLTHREAD_T thread; /**< The underlying thread */
|
||||
char name[16]; /**< The name */
|
||||
unsigned int magic; /**< For debug */
|
||||
void *exit_data; /**< Exit data passed out in vcos_joinable_thread_exit() */
|
||||
void *stack; /**< Stack, if not supplied by caller */
|
||||
VCOS_SEMAPHORE_T wait; /**< Semaphore to wait on at join */
|
||||
VCOS_SEMAPHORE_T suspend; /**< Semaphore to wait on for counted suspend */
|
||||
int16_t joined; /**< Joined yet? For debug. */
|
||||
VCOS_UNSIGNED legacy; /**< Use (argc,argv) for entry point arguments */
|
||||
void *(*entry)(void*); /**< Entry point */
|
||||
void *arg; /**< Argument passed to entry point */
|
||||
void *(*term)(void*); /**< Termination function, used by reaper */
|
||||
void *term_arg; /**< Argument passed to termination function */
|
||||
_VCOS_THREAD_TIMER_T _timer; /**< Internal timer, mainly for event groups */
|
||||
#ifdef VCOS_WANT_TLS_EMULATION
|
||||
VCOS_TLS_THREAD_T _tls; /**< TLS data when native TLS not available, or NULL */
|
||||
#endif
|
||||
/** Array of functions to call at thread exit */
|
||||
VCOS_THREAD_EXIT_T at_exit[VCOS_MAX_EXIT_HANDLERS];
|
||||
|
||||
struct VCOS_THREAD_T *next; /**< For linked lists of threads */
|
||||
} VCOS_THREAD_T;
|
||||
|
||||
#if defined(VCOS_INLINE_BODIES)
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_thread_attr_setstack(VCOS_THREAD_ATTR_T *attrs, void *addr, VCOS_UNSIGNED stacksz) {
|
||||
attrs->ta_stackaddr = addr;
|
||||
attrs->ta_stacksz = stacksz;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_thread_attr_setstacksize(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED stacksz) {
|
||||
attrs->ta_stacksz = stacksz;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_thread_attr_setpriority(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED pri) {
|
||||
attrs->ta_priority = pri;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_thread_attr_setaffinity(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED affinity) {
|
||||
attrs->ta_affinity = affinity;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_thread_attr_settimeslice(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED ts) {
|
||||
attrs->ta_timeslice = ts;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void _vcos_thread_attr_setlegacyapi(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED legacy) {
|
||||
attrs->legacy = legacy;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_thread_attr_setautostart(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED autostart) {
|
||||
attrs->ta_autostart = autostart;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_THREAD_T *vcos_thread_current(void) {
|
||||
VCOS_THREAD_T *ret = (VCOS_THREAD_T*)vcos_llthread_current();
|
||||
/*If we're called from a non-vcos thread, this assert will fail.
|
||||
*XXX FIXME why is this commented out?
|
||||
*vcos_assert(ret->magic == VCOS_THREAD_MAGIC);
|
||||
*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
int vcos_thread_running(VCOS_THREAD_T *thread) {
|
||||
return vcos_llthread_running(&thread->thread);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_thread_resume(VCOS_THREAD_T *thread) {
|
||||
vcos_llthread_resume(&thread->thread);
|
||||
}
|
||||
|
||||
#endif /* VCOS_INLINE_BODIES */
|
||||
|
||||
/**
|
||||
* \brief Create a VCOS_THREAD_T for the current thread. This is so we can have
|
||||
* VCOS_THREAD_Ts even for threads not originally created by VCOS (eg the
|
||||
* thread that calls vcos_init)
|
||||
*/
|
||||
extern VCOS_STATUS_T _vcos_thread_create_attach(VCOS_THREAD_T *thread,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* \brief Deletes the VCOS_THREAD_T, but does not wait for the underlying
|
||||
* thread to exit. This will cleanup everything created by
|
||||
* _vcos_thread_create_attach
|
||||
*/
|
||||
extern void _vcos_thread_delete(VCOS_THREAD_T *thread);
|
||||
|
||||
/** Register a function to be called when the current thread exits.
|
||||
*/
|
||||
extern VCOS_STATUS_T vcos_thread_at_exit(void (*pfn)(void*), void *cxt);
|
||||
|
||||
/** Deregister a previously registered at-exit function.
|
||||
*/
|
||||
extern void vcos_thread_deregister_at_exit(void (*pfn)(void*), void *cxt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* VCOS_JOINABLE_THREAD_FROM_PLAIN_H */
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - Construct a latch from a semaphore
|
||||
=============================================================================*/
|
||||
|
||||
/** FIXME: rename to vcos_mutex_from_sem.c
|
||||
*/
|
||||
|
||||
typedef struct VCOS_MUTEX_T {
|
||||
VCOS_SEMAPHORE_T sem;
|
||||
struct VCOS_THREAD_T *owner;
|
||||
} VCOS_MUTEX_T;
|
||||
|
||||
extern VCOS_STATUS_T vcos_generic_mutex_create(VCOS_MUTEX_T *latch, const char *name);
|
||||
extern void vcos_generic_mutex_delete(VCOS_MUTEX_T *latch);
|
||||
extern VCOS_STATUS_T vcos_generic_mutex_lock(VCOS_MUTEX_T *latch);
|
||||
extern void vcos_generic_mutex_unlock(VCOS_MUTEX_T *latch);
|
||||
|
||||
#if defined(VCOS_INLINE_BODIES)
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_mutex_create(VCOS_MUTEX_T *latch, const char *name) {
|
||||
return vcos_generic_mutex_create(latch,name);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_mutex_delete(VCOS_MUTEX_T *latch) {
|
||||
vcos_generic_mutex_delete(latch);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_mutex_lock(VCOS_MUTEX_T *latch) {
|
||||
return vcos_generic_mutex_lock(latch);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_mutex_unlock(VCOS_MUTEX_T *latch) {
|
||||
vcos_generic_mutex_unlock(latch);
|
||||
}
|
||||
|
||||
#endif /* VCOS_INLINE_BODIES */
|
||||
|
||||
@@ -0,0 +1,587 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
Categorized logging for VCOS - a generic implementation.
|
||||
=============================================================================*/
|
||||
|
||||
#include "interface/vcos/vcos.h"
|
||||
#include "interface/vcos/vcos_ctype.h"
|
||||
#include "interface/vcos/vcos_string.h"
|
||||
#include "interface/vcos/vcos_inttypes.h"
|
||||
|
||||
static VCOS_MUTEX_T lock;
|
||||
static int warned_loglevel; /* only warn about invalid log level once */
|
||||
static VCOS_VLOG_IMPL_FUNC_T vcos_vlog_impl_func = vcos_vlog_default_impl;
|
||||
|
||||
#define VCOS_LOG_CATEGORY (&dflt_log_category)
|
||||
static VCOS_LOG_CAT_T dflt_log_category;
|
||||
VCOS_LOG_CAT_T *vcos_logging_categories = NULL;
|
||||
static int inited;
|
||||
|
||||
#if VCOS_HAVE_CMD
|
||||
|
||||
/*
|
||||
* For kernel or videocore purposes, we generally want the log command. For
|
||||
* user-space apps, they might want to provide their own log command, so we
|
||||
* don't include the built in on.
|
||||
*
|
||||
* So pthreads/vcos_platform.h defines VCOS_WANT_LOG_CMD to be 0. It is
|
||||
* undefined elsewhere.
|
||||
*/
|
||||
|
||||
# if !defined( VCOS_WANT_LOG_CMD )
|
||||
# define VCOS_WANT_LOG_CMD 1
|
||||
# endif
|
||||
#else
|
||||
# define VCOS_WANT_LOG_CMD 0
|
||||
#endif
|
||||
|
||||
/* For now, do not link logging categories into linked lists
|
||||
* as it breaks when people unload shared libraries without
|
||||
* getting the counts right.
|
||||
*/
|
||||
#ifdef __VIDEOCORE__
|
||||
#define REGISTER_CATEGORIES 1
|
||||
#else
|
||||
#define REGISTER_CATEGORIES 0
|
||||
#endif
|
||||
|
||||
#if VCOS_WANT_LOG_CMD
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Does a vcos_assert(0), which is useful to test logging.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
VCOS_STATUS_T vcos_log_assert_cmd( VCOS_CMD_PARAM_T *param )
|
||||
{
|
||||
(void)param;
|
||||
|
||||
#if defined( NDEBUG ) && !defined( VCOS_RELEASE_ASSERTS )
|
||||
vcos_log_error( "vcos_asserts have been compiled out" );
|
||||
vcos_cmd_printf( param, "vcos_asserts have been compiled out - did a vcos_log_error instead\n" );
|
||||
#else
|
||||
vcos_assert(0);
|
||||
vcos_cmd_printf( param, "Executed vcos_assert(0)\n" );
|
||||
#endif
|
||||
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Sets a vcos logging level
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
VCOS_STATUS_T vcos_log_set_cmd( VCOS_CMD_PARAM_T *param )
|
||||
{
|
||||
VCOS_LOG_CAT_T *cat;
|
||||
char *name;
|
||||
char *levelStr;
|
||||
VCOS_LOG_LEVEL_T level;
|
||||
VCOS_STATUS_T status;
|
||||
|
||||
if ( param->argc != 3 )
|
||||
{
|
||||
vcos_cmd_usage( param );
|
||||
return VCOS_EINVAL;
|
||||
}
|
||||
|
||||
name = param->argv[1];
|
||||
levelStr = param->argv[2];
|
||||
|
||||
if ( vcos_string_to_log_level( levelStr, &level ) != VCOS_SUCCESS )
|
||||
{
|
||||
vcos_cmd_printf( param, "Unrecognized logging level: '%s'\n", levelStr );
|
||||
return VCOS_EINVAL;
|
||||
}
|
||||
|
||||
vcos_mutex_lock(&lock);
|
||||
|
||||
status = VCOS_SUCCESS;
|
||||
for ( cat = vcos_logging_categories; cat != NULL; cat = cat->next )
|
||||
{
|
||||
if ( vcos_strcmp( name, cat->name ) == 0 )
|
||||
{
|
||||
cat->level = level;
|
||||
vcos_cmd_printf( param, "Category %s level set to %s\n", name, levelStr );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( cat == NULL )
|
||||
{
|
||||
vcos_cmd_printf( param, "Unrecognized category: '%s'\n", name );
|
||||
status = VCOS_ENOENT;
|
||||
}
|
||||
|
||||
vcos_mutex_unlock(&lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Prints out the current settings for a given category (or all cvategories)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
VCOS_STATUS_T vcos_log_status_cmd( VCOS_CMD_PARAM_T *param )
|
||||
{
|
||||
VCOS_LOG_CAT_T *cat;
|
||||
VCOS_STATUS_T status;
|
||||
|
||||
vcos_mutex_lock(&lock);
|
||||
|
||||
if ( param->argc == 1)
|
||||
{
|
||||
int nw;
|
||||
int nameWidth = 0;
|
||||
|
||||
/* Print information about all of the categories. */
|
||||
|
||||
for ( cat = vcos_logging_categories; cat != NULL; cat = cat->next )
|
||||
{
|
||||
nw = (int)strlen( cat->name );
|
||||
|
||||
if ( nw > nameWidth )
|
||||
{
|
||||
nameWidth = nw;
|
||||
}
|
||||
}
|
||||
|
||||
for ( cat = vcos_logging_categories; cat != NULL; cat = cat->next )
|
||||
{
|
||||
vcos_cmd_printf( param, "%-*s - %s\n", nameWidth, cat->name, vcos_log_level_to_string( cat->level ));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Print information about a particular category */
|
||||
|
||||
for ( cat = vcos_logging_categories; cat != NULL; cat = cat->next )
|
||||
{
|
||||
if ( vcos_strcmp( cat->name, param->argv[1] ) == 0 )
|
||||
{
|
||||
vcos_cmd_printf( param, "%s - %s\n", cat->name, vcos_log_level_to_string( cat->level ));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( cat == NULL )
|
||||
{
|
||||
vcos_cmd_printf( param, "Unrecognized logging category: '%s'\n", param->argv[1] );
|
||||
status = VCOS_ENOENT;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
status = VCOS_SUCCESS;
|
||||
out:
|
||||
vcos_mutex_unlock(&lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Prints out the current settings for a given category (or all cvategories)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
VCOS_STATUS_T vcos_log_test_cmd( VCOS_CMD_PARAM_T *param )
|
||||
{
|
||||
if ( param->argc == 1 )
|
||||
{
|
||||
static int seq_num = 100;
|
||||
|
||||
/* No additional arguments - generate a message with an incrementing number */
|
||||
|
||||
vcos_log_error( "Test message %d", seq_num );
|
||||
|
||||
seq_num++;
|
||||
vcos_cmd_printf( param, "Logged 'Test message %d'\n", seq_num );
|
||||
}
|
||||
else
|
||||
{
|
||||
int arg_idx;
|
||||
|
||||
/* Arguments supplied - log these */
|
||||
|
||||
for ( arg_idx = 0; arg_idx < param->argc; arg_idx++ )
|
||||
{
|
||||
vcos_log_error( "argv[%d] = '%s'", arg_idx, param->argv[arg_idx] );
|
||||
}
|
||||
vcos_cmd_printf( param, "Logged %d line(s) of test data\n", param->argc );
|
||||
}
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Internal commands
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static VCOS_CMD_T log_cmd_entry[] =
|
||||
{
|
||||
{ "assert", "", vcos_log_assert_cmd, NULL, "Does a vcos_assert(0) to test logging" },
|
||||
{ "set", "category level", vcos_log_set_cmd, NULL, "Sets the vcos logging level for a category" },
|
||||
{ "status", "[category]", vcos_log_status_cmd, NULL, "Prints the vcos log status for a (or all) categories" },
|
||||
{ "test", "[arbitrary text]", vcos_log_test_cmd, NULL, "Does a vcos_log to test logging" },
|
||||
|
||||
{ NULL, NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static VCOS_CMD_T cmd_log =
|
||||
{ "log", "command [args]", NULL, log_cmd_entry, "Commands related to vcos logging" };
|
||||
|
||||
#endif
|
||||
|
||||
void vcos_logging_init(void)
|
||||
{
|
||||
if (inited)
|
||||
{
|
||||
/* FIXME: should print a warning or something here */
|
||||
return;
|
||||
}
|
||||
vcos_mutex_create(&lock, "vcos_log");
|
||||
|
||||
vcos_log_platform_init();
|
||||
|
||||
vcos_log_register("default", &dflt_log_category);
|
||||
|
||||
#if VCOS_WANT_LOG_CMD
|
||||
vcos_cmd_register( &cmd_log );
|
||||
#endif
|
||||
|
||||
vcos_assert(!inited);
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
/** Read an alphanumeric token, returning True if we succeeded.
|
||||
*/
|
||||
|
||||
static int read_tok(char *tok, size_t toklen, const char **pstr, char sep)
|
||||
{
|
||||
const char *str = *pstr;
|
||||
size_t n = 0;
|
||||
char ch;
|
||||
|
||||
/* skip past any whitespace */
|
||||
while (str[0] && isspace((int)(str[0])))
|
||||
str++;
|
||||
|
||||
while ((ch = *str) != '\0' &&
|
||||
ch != sep &&
|
||||
(isalnum((int)ch) || (ch == '_')) &&
|
||||
n != toklen-1)
|
||||
{
|
||||
tok[n++] = ch;
|
||||
str++;
|
||||
}
|
||||
|
||||
/* did it work out? */
|
||||
if (ch == '\0' || ch == sep)
|
||||
{
|
||||
if (ch) str++; /* move to next token if not at end */
|
||||
/* yes */
|
||||
tok[n] = '\0';
|
||||
*pstr = str;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char *vcos_log_level_to_string( VCOS_LOG_LEVEL_T level )
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case VCOS_LOG_UNINITIALIZED: return "uninit";
|
||||
case VCOS_LOG_NEVER: return "never";
|
||||
case VCOS_LOG_ERROR: return "error";
|
||||
case VCOS_LOG_WARN: return "warn";
|
||||
case VCOS_LOG_INFO: return "info";
|
||||
case VCOS_LOG_TRACE: return "trace";
|
||||
}
|
||||
return "???";
|
||||
}
|
||||
|
||||
VCOS_STATUS_T vcos_string_to_log_level( const char *str, VCOS_LOG_LEVEL_T *level )
|
||||
{
|
||||
if (strcmp(str,"error") == 0)
|
||||
*level = VCOS_LOG_ERROR;
|
||||
else if (strcmp(str,"never") == 0)
|
||||
*level = VCOS_LOG_NEVER;
|
||||
else if (strcmp(str,"warn") == 0)
|
||||
*level = VCOS_LOG_WARN;
|
||||
else if (strcmp(str,"warning") == 0)
|
||||
*level = VCOS_LOG_WARN;
|
||||
else if (strcmp(str,"info") == 0)
|
||||
*level = VCOS_LOG_INFO;
|
||||
else if (strcmp(str,"trace") == 0)
|
||||
*level = VCOS_LOG_TRACE;
|
||||
else
|
||||
return VCOS_EINVAL;
|
||||
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
|
||||
static int read_level(VCOS_LOG_LEVEL_T *level, const char **pstr, char sep)
|
||||
{
|
||||
char buf[16];
|
||||
int ret = 1;
|
||||
if (read_tok(buf,sizeof(buf),pstr,sep))
|
||||
{
|
||||
if (vcos_string_to_log_level(buf,level) != VCOS_SUCCESS)
|
||||
{
|
||||
vcos_log("Invalid trace level '%s'\n", buf);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void vcos_log_register(const char *name, VCOS_LOG_CAT_T *category)
|
||||
{
|
||||
const char *env;
|
||||
VCOS_LOG_CAT_T *i;
|
||||
|
||||
category->name = name;
|
||||
if ( category->level == VCOS_LOG_UNINITIALIZED )
|
||||
{
|
||||
category->level = VCOS_LOG_ERROR;
|
||||
}
|
||||
category->flags.want_prefix = (category != &dflt_log_category );
|
||||
|
||||
if (!REGISTER_CATEGORIES)
|
||||
return;
|
||||
|
||||
vcos_mutex_lock(&lock);
|
||||
|
||||
/* is it already registered? */
|
||||
for (i = vcos_logging_categories; i ; i = i->next )
|
||||
{
|
||||
if (i == category)
|
||||
{
|
||||
i->refcount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!i)
|
||||
{
|
||||
/* not yet registered */
|
||||
category->next = vcos_logging_categories;
|
||||
vcos_logging_categories = category;
|
||||
category->refcount++;
|
||||
|
||||
vcos_log_platform_register(category);
|
||||
}
|
||||
|
||||
vcos_mutex_unlock(&lock);
|
||||
|
||||
/* Check to see if this log level has been enabled. Look for
|
||||
* (<category:level>,)*
|
||||
*
|
||||
* VC_LOGLEVEL=ilcs:info,vchiq:warn
|
||||
*/
|
||||
|
||||
env = _VCOS_LOG_LEVEL();
|
||||
if (env)
|
||||
{
|
||||
do
|
||||
{
|
||||
char env_name[64];
|
||||
VCOS_LOG_LEVEL_T level;
|
||||
if (read_tok(env_name, sizeof(env_name), &env, ':') &&
|
||||
read_level(&level, &env, ','))
|
||||
{
|
||||
if (strcmp(env_name, name) == 0)
|
||||
{
|
||||
category->level = level;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!warned_loglevel)
|
||||
{
|
||||
vcos_log("VC_LOGLEVEL format invalid at %s\n", env);
|
||||
warned_loglevel = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
} while (env[0] != '\0');
|
||||
}
|
||||
|
||||
vcos_log_info( "Registered log category '%s' with level %s",
|
||||
category->name,
|
||||
vcos_log_level_to_string( category->level ));
|
||||
}
|
||||
|
||||
void vcos_log_unregister(VCOS_LOG_CAT_T *category)
|
||||
{
|
||||
VCOS_LOG_CAT_T **pcat;
|
||||
|
||||
if (!REGISTER_CATEGORIES)
|
||||
return;
|
||||
|
||||
vcos_mutex_lock(&lock);
|
||||
category->refcount--;
|
||||
if (category->refcount == 0)
|
||||
{
|
||||
pcat = &vcos_logging_categories;
|
||||
while (*pcat != category)
|
||||
{
|
||||
if (!*pcat)
|
||||
break; /* possibly deregistered twice? */
|
||||
if ((*pcat)->next == NULL)
|
||||
{
|
||||
vcos_assert(0); /* already removed! */
|
||||
vcos_mutex_unlock(&lock);
|
||||
return;
|
||||
}
|
||||
pcat = &(*pcat)->next;
|
||||
}
|
||||
if (*pcat)
|
||||
*pcat = category->next;
|
||||
|
||||
vcos_log_platform_unregister(category);
|
||||
}
|
||||
vcos_mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
VCOSPRE_ const VCOS_LOG_CAT_T * VCOSPOST_ vcos_log_get_default_category(void)
|
||||
{
|
||||
return &dflt_log_category;
|
||||
}
|
||||
|
||||
void vcos_set_log_options(const char *opt)
|
||||
{
|
||||
(void)opt;
|
||||
}
|
||||
|
||||
void vcos_log_dump_mem_impl( const VCOS_LOG_CAT_T *cat,
|
||||
const char *label,
|
||||
uint32_t addr,
|
||||
const void *voidMem,
|
||||
size_t numBytes )
|
||||
{
|
||||
const uint8_t *mem = (const uint8_t *)voidMem;
|
||||
size_t offset;
|
||||
char lineBuf[ 100 ];
|
||||
char *s;
|
||||
|
||||
while ( numBytes > 0 )
|
||||
{
|
||||
s = lineBuf;
|
||||
|
||||
for ( offset = 0; offset < 16; offset++ )
|
||||
{
|
||||
if ( offset < numBytes )
|
||||
{
|
||||
s += vcos_snprintf( s, 4, "%02x ", mem[ offset ]);
|
||||
}
|
||||
else
|
||||
{
|
||||
s += vcos_snprintf( s, 4, " " );
|
||||
}
|
||||
}
|
||||
|
||||
for ( offset = 0; offset < 16; offset++ )
|
||||
{
|
||||
if ( offset < numBytes )
|
||||
{
|
||||
uint8_t ch = mem[ offset ];
|
||||
|
||||
if (( ch < ' ' ) || ( ch > '~' ))
|
||||
{
|
||||
ch = '.';
|
||||
}
|
||||
*s++ = (char)ch;
|
||||
}
|
||||
}
|
||||
*s++ = '\0';
|
||||
|
||||
if (( label != NULL ) && ( *label != '\0' ))
|
||||
{
|
||||
vcos_log_impl( cat, VCOS_LOG_INFO, "%s: %08" PRIx32 ": %s", label, addr, lineBuf );
|
||||
}
|
||||
else
|
||||
{
|
||||
vcos_log_impl( cat, VCOS_LOG_INFO, "%08" PRIx32 ": %s", addr, lineBuf );
|
||||
}
|
||||
|
||||
addr += 16;
|
||||
mem += 16;
|
||||
if ( numBytes > 16 )
|
||||
{
|
||||
numBytes -= 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
numBytes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void vcos_log_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap,fmt);
|
||||
vcos_vlog_impl( cat, _level, fmt, ap );
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void vcos_vlog_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args)
|
||||
{
|
||||
vcos_vlog_impl_func( cat, _level, fmt, args );
|
||||
}
|
||||
|
||||
void vcos_set_vlog_impl( VCOS_VLOG_IMPL_FUNC_T vlog_impl_func )
|
||||
{
|
||||
if ( vlog_impl_func == NULL )
|
||||
{
|
||||
vcos_vlog_impl_func = vcos_vlog_default_impl;
|
||||
}
|
||||
else
|
||||
{
|
||||
vcos_vlog_impl_func = vlog_impl_func;
|
||||
}
|
||||
}
|
||||
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - memory alloc implementation
|
||||
=============================================================================*/
|
||||
|
||||
#include "interface/vcos/vcos.h"
|
||||
|
||||
#ifndef _vcos_platform_malloc
|
||||
#include <stdlib.h>
|
||||
#define _vcos_platform_malloc malloc
|
||||
#define _vcos_platform_free free
|
||||
#endif
|
||||
|
||||
typedef struct malloc_header_s {
|
||||
uint32_t guardword;
|
||||
uint32_t size;
|
||||
const char *description;
|
||||
void *ptr;
|
||||
} MALLOC_HEADER_T;
|
||||
|
||||
|
||||
#define MIN_ALIGN sizeof(MALLOC_HEADER_T)
|
||||
|
||||
#define GUARDWORDHEAP 0xa55a5aa5
|
||||
|
||||
void *vcos_generic_mem_alloc_aligned(VCOS_UNSIGNED size, VCOS_UNSIGNED align, const char *desc)
|
||||
{
|
||||
int local_align = align == 0 ? 1 : align;
|
||||
int required_size = size + local_align + sizeof(MALLOC_HEADER_T);
|
||||
void *ptr = _vcos_platform_malloc(required_size);
|
||||
void *ret = NULL;
|
||||
MALLOC_HEADER_T *h;
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
ret = (void *)VCOS_ALIGN_UP(((char *)ptr)+sizeof(MALLOC_HEADER_T), local_align);
|
||||
h = ((MALLOC_HEADER_T *)ret)-1;
|
||||
h->size = size;
|
||||
h->description = desc;
|
||||
h->guardword = GUARDWORDHEAP;
|
||||
h->ptr = ptr;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *vcos_generic_mem_alloc(VCOS_UNSIGNED size, const char *desc)
|
||||
{
|
||||
return vcos_generic_mem_alloc_aligned(size,MIN_ALIGN,desc);
|
||||
}
|
||||
|
||||
void *vcos_generic_mem_calloc(VCOS_UNSIGNED count, VCOS_UNSIGNED sz, const char *desc)
|
||||
{
|
||||
uint32_t size = count*sz;
|
||||
void *ptr = vcos_generic_mem_alloc_aligned(size,MIN_ALIGN,desc);
|
||||
if (ptr)
|
||||
{
|
||||
memset(ptr, 0, size);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void vcos_generic_mem_free(void *ptr)
|
||||
{
|
||||
MALLOC_HEADER_T *h;
|
||||
if (! ptr) return;
|
||||
|
||||
h = ((MALLOC_HEADER_T *)ptr)-1;
|
||||
vcos_assert(h->guardword == GUARDWORDHEAP);
|
||||
_vcos_platform_free(h->ptr);
|
||||
}
|
||||
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
Create the vcos_malloc API from the regular system malloc/free
|
||||
=============================================================================*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Create the vcos malloc API from a regular system malloc/free library.
|
||||
*
|
||||
* The API lets callers specify an alignment.
|
||||
*
|
||||
* Under VideoCore this is not needed, as we can simply use the rtos_malloc routines.
|
||||
* But on host platforms that won't be the case.
|
||||
*
|
||||
*/
|
||||
|
||||
VCOSPRE_ void * VCOSPOST_ vcos_generic_mem_alloc(VCOS_UNSIGNED sz, const char *desc);
|
||||
VCOSPRE_ void * VCOSPOST_ vcos_generic_mem_calloc(VCOS_UNSIGNED count, VCOS_UNSIGNED sz, const char *descr);
|
||||
VCOSPRE_ void VCOSPOST_ vcos_generic_mem_free(void *ptr);
|
||||
VCOSPRE_ void * VCOSPOST_ vcos_generic_mem_alloc_aligned(VCOS_UNSIGNED sz, VCOS_UNSIGNED align, const char *desc);
|
||||
|
||||
#ifdef VCOS_INLINE_BODIES
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void *vcos_malloc(VCOS_UNSIGNED size, const char *description) {
|
||||
return vcos_generic_mem_alloc(size, description);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void *vcos_calloc(VCOS_UNSIGNED num, VCOS_UNSIGNED size, const char *description) {
|
||||
return vcos_generic_mem_calloc(num, size, description);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_free(void *ptr) {
|
||||
vcos_generic_mem_free(ptr);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void * vcos_malloc_aligned(VCOS_UNSIGNED size, VCOS_UNSIGNED align, const char *description) {
|
||||
return vcos_generic_mem_alloc_aligned(size, align, description);
|
||||
}
|
||||
|
||||
|
||||
#endif /* VCOS_INLINE_BODIES */
|
||||
|
||||
|
||||
@@ -0,0 +1,389 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "vcos.h"
|
||||
#include "vcos_msgqueue.h"
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAGIC VCOS_MSGQ_MAGIC
|
||||
|
||||
/* Probably a good idea for MSG_T to be multiple of 8 so that doubles
|
||||
* are naturally aligned without problem.
|
||||
*/
|
||||
vcos_static_assert((sizeof(VCOS_MSG_T) & 7) == 0);
|
||||
|
||||
static void vcos_msgq_pool_on_reply(VCOS_MSG_WAITER_T *waiter,
|
||||
VCOS_MSG_T *msg);
|
||||
static void vcos_msgq_queue_waiter_on_reply(VCOS_MSG_WAITER_T *waiter,
|
||||
VCOS_MSG_T *msg);
|
||||
|
||||
/** Simple reply protocol. The client creates a semaphore and waits
|
||||
* for it. No queuing of multiple replies is possible but nothing needs
|
||||
* to be setup in advance. Because creating semaphores is very fast on
|
||||
* VideoCore there's no need to do anything elaborate to optimize create
|
||||
* time - this might need revisiting on other platforms.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
VCOS_MSG_WAITER_T waiter;
|
||||
VCOS_SEMAPHORE_T waitsem;
|
||||
} VCOS_MSG_SIMPLE_WAITER_T;
|
||||
|
||||
static void vcos_msgq_simple_waiter_on_reply(VCOS_MSG_WAITER_T *waiter,
|
||||
VCOS_MSG_T *msg)
|
||||
{
|
||||
VCOS_MSG_SIMPLE_WAITER_T *self;
|
||||
(void)msg;
|
||||
self = (VCOS_MSG_SIMPLE_WAITER_T*)waiter;
|
||||
vcos_semaphore_post(&self->waitsem);
|
||||
}
|
||||
|
||||
static VCOS_STATUS_T vcos_msgq_simple_waiter_init(VCOS_MSG_SIMPLE_WAITER_T *waiter)
|
||||
{
|
||||
VCOS_STATUS_T status;
|
||||
status = vcos_semaphore_create(&waiter->waitsem, "waiter", 0);
|
||||
waiter->waiter.on_reply = vcos_msgq_simple_waiter_on_reply;
|
||||
return status;
|
||||
}
|
||||
|
||||
static void vcos_msgq_simple_waiter_deinit(VCOS_MSG_SIMPLE_WAITER_T *waiter)
|
||||
{
|
||||
vcos_semaphore_delete(&waiter->waitsem);
|
||||
}
|
||||
|
||||
/*
|
||||
* Message queues
|
||||
*/
|
||||
|
||||
static VCOS_STATUS_T vcos_msgq_create_internal(VCOS_MSGQUEUE_T *q, const char *name)
|
||||
{
|
||||
VCOS_STATUS_T st;
|
||||
|
||||
memset(q, 0, sizeof(*q));
|
||||
|
||||
q->waiter.on_reply = vcos_msgq_queue_waiter_on_reply;
|
||||
st = vcos_semaphore_create(&q->sem, name, 0);
|
||||
if (st != VCOS_SUCCESS)
|
||||
goto fail_sem;
|
||||
|
||||
st = vcos_mutex_create(&q->lock, name);
|
||||
if (st != VCOS_SUCCESS)
|
||||
goto fail_mtx;
|
||||
|
||||
return st;
|
||||
|
||||
fail_mtx:
|
||||
vcos_semaphore_delete(&q->sem);
|
||||
fail_sem:
|
||||
return st;
|
||||
}
|
||||
|
||||
static void vcos_msgq_delete_internal(VCOS_MSGQUEUE_T *q)
|
||||
{
|
||||
vcos_semaphore_delete(&q->sem);
|
||||
vcos_mutex_delete(&q->lock);
|
||||
}
|
||||
|
||||
VCOS_STATUS_T vcos_msgq_create(VCOS_MSGQUEUE_T *q, const char *name)
|
||||
{
|
||||
VCOS_STATUS_T st;
|
||||
|
||||
st = vcos_msgq_create_internal(q, name);
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
void vcos_msgq_delete(VCOS_MSGQUEUE_T *q)
|
||||
{
|
||||
vcos_msgq_delete_internal(q);
|
||||
}
|
||||
|
||||
/* append a message to a message queue */
|
||||
static _VCOS_INLINE void msgq_append(VCOS_MSGQUEUE_T *q, VCOS_MSG_T *msg)
|
||||
{
|
||||
vcos_mutex_lock(&q->lock);
|
||||
if (q->head == NULL)
|
||||
{
|
||||
q->head = q->tail = msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
q->tail->next = msg;
|
||||
q->tail = msg;
|
||||
}
|
||||
vcos_mutex_unlock(&q->lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* A waiter for a message queue. Just appends the message to the
|
||||
* queue, waking up the waiting thread.
|
||||
*/
|
||||
static void vcos_msgq_queue_waiter_on_reply(VCOS_MSG_WAITER_T *waiter,
|
||||
VCOS_MSG_T *msg)
|
||||
{
|
||||
VCOS_MSGQUEUE_T *queue = (VCOS_MSGQUEUE_T*)waiter;
|
||||
msgq_append(queue, msg);
|
||||
vcos_semaphore_post(&queue->sem);
|
||||
}
|
||||
|
||||
/* initialise this library */
|
||||
|
||||
VCOS_STATUS_T vcos_msgq_init(void)
|
||||
{
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
|
||||
void vcos_msgq_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
static _VCOS_INLINE
|
||||
void vcos_msg_send_helper(VCOS_MSG_WAITER_T *waiter,
|
||||
VCOS_MSGQUEUE_T *dest,
|
||||
uint32_t code,
|
||||
VCOS_MSG_T *msg)
|
||||
{
|
||||
vcos_assert(msg);
|
||||
vcos_assert(dest);
|
||||
|
||||
msg->code = code;
|
||||
if (waiter)
|
||||
msg->waiter = waiter;
|
||||
msg->next = NULL;
|
||||
msg->src_thread = vcos_thread_current();
|
||||
|
||||
msgq_append(dest, msg);
|
||||
vcos_semaphore_post(&dest->sem);
|
||||
}
|
||||
|
||||
/* wait on a queue for a message */
|
||||
VCOS_MSG_T *vcos_msg_wait(VCOS_MSGQUEUE_T *queue)
|
||||
{
|
||||
VCOS_MSG_T *msg;
|
||||
vcos_semaphore_wait(&queue->sem);
|
||||
vcos_mutex_lock(&queue->lock);
|
||||
|
||||
msg = queue->head;
|
||||
vcos_assert(msg); /* should always be a message here! */
|
||||
|
||||
queue->head = msg->next;
|
||||
if (queue->head == NULL)
|
||||
queue->tail = NULL;
|
||||
|
||||
vcos_mutex_unlock(&queue->lock);
|
||||
return msg;
|
||||
}
|
||||
|
||||
/* peek on a queue for a message */
|
||||
VCOS_MSG_T *vcos_msg_peek(VCOS_MSGQUEUE_T *queue)
|
||||
{
|
||||
VCOS_MSG_T *msg;
|
||||
vcos_mutex_lock(&queue->lock);
|
||||
|
||||
msg = queue->head;
|
||||
|
||||
/* if there's a message, remove it from the queue */
|
||||
if (msg)
|
||||
{
|
||||
queue->head = msg->next;
|
||||
if (queue->head == NULL)
|
||||
queue->tail = NULL;
|
||||
|
||||
/* keep the semaphore count consistent */
|
||||
|
||||
/* coverity[lock_order]
|
||||
* the semaphore must have a non-zero count so cannot block here.
|
||||
*/
|
||||
vcos_semaphore_wait(&queue->sem);
|
||||
}
|
||||
|
||||
vcos_mutex_unlock(&queue->lock);
|
||||
return msg;
|
||||
}
|
||||
|
||||
void vcos_msg_send(VCOS_MSGQUEUE_T *dest, uint32_t code, VCOS_MSG_T *msg)
|
||||
{
|
||||
vcos_assert(msg->magic == MAGIC);
|
||||
vcos_msg_send_helper(NULL, dest, code, msg);
|
||||
}
|
||||
|
||||
/** Send on to the target queue, then wait on a simple waiter for the reply
|
||||
*/
|
||||
VCOS_STATUS_T vcos_msg_sendwait(VCOS_MSGQUEUE_T *dest, uint32_t code, VCOS_MSG_T *msg)
|
||||
{
|
||||
VCOS_STATUS_T st;
|
||||
VCOS_MSG_SIMPLE_WAITER_T waiter;
|
||||
|
||||
vcos_assert(msg->magic == MAGIC);
|
||||
|
||||
/* if this fires, you've set a waiter up but are now about to obliterate it
|
||||
* with the 'wait for a reply' waiter.
|
||||
*/
|
||||
vcos_assert(msg->waiter == NULL);
|
||||
|
||||
if ((st=vcos_msgq_simple_waiter_init(&waiter)) != VCOS_SUCCESS)
|
||||
return st;
|
||||
|
||||
vcos_msg_send_helper(&waiter.waiter, dest, code, msg);
|
||||
vcos_semaphore_wait(&waiter.waitsem);
|
||||
vcos_msgq_simple_waiter_deinit(&waiter);
|
||||
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
|
||||
/** Send a reply to a message
|
||||
*/
|
||||
void vcos_msg_reply(VCOS_MSG_T *msg)
|
||||
{
|
||||
vcos_assert(msg->magic == MAGIC);
|
||||
msg->code |= MSG_REPLY_BIT;
|
||||
if (msg->waiter)
|
||||
{
|
||||
msg->waiter->on_reply(msg->waiter, msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
VCOS_ALERT("%s: reply to non-reply message id %d",
|
||||
VCOS_FUNCTION,
|
||||
msg->code);
|
||||
vcos_assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void vcos_msg_set_source(VCOS_MSG_T *msg, VCOS_MSGQUEUE_T *queue)
|
||||
{
|
||||
vcos_assert(msg);
|
||||
vcos_assert(msg->magic == MAGIC);
|
||||
vcos_assert(queue);
|
||||
msg->waiter = &queue->waiter;
|
||||
}
|
||||
|
||||
/*
|
||||
* Message pools
|
||||
*/
|
||||
|
||||
VCOS_STATUS_T vcos_msgq_pool_create(VCOS_MSGQ_POOL_T *pool,
|
||||
size_t count,
|
||||
size_t payload_size,
|
||||
const char *name)
|
||||
{
|
||||
VCOS_STATUS_T status;
|
||||
int bp_size = payload_size + sizeof(VCOS_MSG_T);
|
||||
status = vcos_blockpool_create_on_heap(&pool->blockpool,
|
||||
count, bp_size,
|
||||
VCOS_BLOCKPOOL_ALIGN_DEFAULT,
|
||||
0,
|
||||
name);
|
||||
if (status != VCOS_SUCCESS)
|
||||
goto fail_pool;
|
||||
|
||||
status = vcos_semaphore_create(&pool->sem, name, count);
|
||||
if (status != VCOS_SUCCESS)
|
||||
goto fail_sem;
|
||||
|
||||
pool->waiter.on_reply = vcos_msgq_pool_on_reply;
|
||||
pool->magic = MAGIC;
|
||||
return status;
|
||||
|
||||
fail_sem:
|
||||
vcos_blockpool_delete(&pool->blockpool);
|
||||
fail_pool:
|
||||
return status;
|
||||
}
|
||||
|
||||
void vcos_msgq_pool_delete(VCOS_MSGQ_POOL_T *pool)
|
||||
{
|
||||
vcos_blockpool_delete(&pool->blockpool);
|
||||
vcos_semaphore_delete(&pool->sem);
|
||||
}
|
||||
|
||||
/** Called when a message from a pool is replied-to. Just returns
|
||||
* the message back to the blockpool.
|
||||
*/
|
||||
static void vcos_msgq_pool_on_reply(VCOS_MSG_WAITER_T *waiter,
|
||||
VCOS_MSG_T *msg)
|
||||
{
|
||||
vcos_unused(waiter);
|
||||
vcos_assert(msg->magic == MAGIC);
|
||||
vcos_msgq_pool_free(msg);
|
||||
}
|
||||
|
||||
VCOS_MSG_T *vcos_msgq_pool_alloc(VCOS_MSGQ_POOL_T *pool)
|
||||
{
|
||||
VCOS_MSG_T *msg;
|
||||
if (vcos_semaphore_trywait(&pool->sem) == VCOS_SUCCESS)
|
||||
{
|
||||
msg = vcos_blockpool_calloc(&pool->blockpool);
|
||||
vcos_assert(msg);
|
||||
msg->magic = MAGIC;
|
||||
msg->waiter = &pool->waiter;
|
||||
msg->pool = pool;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = NULL;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
void vcos_msgq_pool_free(VCOS_MSG_T *msg)
|
||||
{
|
||||
if (msg)
|
||||
{
|
||||
VCOS_MSGQ_POOL_T *pool;
|
||||
vcos_assert(msg->pool);
|
||||
|
||||
pool = msg->pool;
|
||||
vcos_assert(msg->pool->magic == MAGIC);
|
||||
|
||||
vcos_blockpool_free(msg);
|
||||
vcos_semaphore_post(&pool->sem);
|
||||
}
|
||||
}
|
||||
|
||||
VCOS_MSG_T *vcos_msgq_pool_wait(VCOS_MSGQ_POOL_T *pool)
|
||||
{
|
||||
VCOS_MSG_T *msg;
|
||||
vcos_semaphore_wait(&pool->sem);
|
||||
msg = vcos_blockpool_calloc(&pool->blockpool);
|
||||
vcos_assert(msg);
|
||||
msg->magic = MAGIC;
|
||||
msg->waiter = &pool->waiter;
|
||||
msg->pool = pool;
|
||||
return msg;
|
||||
}
|
||||
|
||||
void vcos_msg_init(VCOS_MSG_T *msg)
|
||||
{
|
||||
msg->magic = MAGIC;
|
||||
msg->next = NULL;
|
||||
msg->waiter = NULL;
|
||||
msg->pool = NULL;
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - reentrant mutexes mapped directly to regular ones
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_GENERIC_REENTRANT_MUTEX_H
|
||||
#define VCOS_GENERIC_REENTRANT_MUTEX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "interface/vcos/vcos_types.h"
|
||||
#include "interface/vcos/vcos_mutex.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Reentrant Mutexes directly using the native re-entrant mutex.
|
||||
*
|
||||
*/
|
||||
|
||||
typedef VCOS_MUTEX_T VCOS_REENTRANT_MUTEX_T;
|
||||
|
||||
/* Inline forwarding functions */
|
||||
|
||||
#if defined(VCOS_INLINE_BODIES)
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_reentrant_mutex_create(VCOS_REENTRANT_MUTEX_T *m, const char *name) {
|
||||
return vcos_mutex_create(m,name);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_reentrant_mutex_delete(VCOS_REENTRANT_MUTEX_T *m) {
|
||||
vcos_mutex_delete(m);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_reentrant_mutex_lock(VCOS_REENTRANT_MUTEX_T *m) {
|
||||
vcos_mutex_lock(m);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_reentrant_mutex_unlock(VCOS_REENTRANT_MUTEX_T *m) {
|
||||
vcos_mutex_unlock(m);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
int vcos_reentrant_mutex_is_locked(VCOS_REENTRANT_MUTEX_T *m) {
|
||||
return vcos_mutex_is_locked(m);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - thread reaping
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_THREAD_REAPER_H
|
||||
#define VCOS_THREAD_REAPER_H
|
||||
|
||||
#define VCOS_HAVE_THREAD_REAPER
|
||||
|
||||
/** Initialise the thread reaper.
|
||||
*/
|
||||
VCOS_STATUS_T vcos_thread_reaper_init(void);
|
||||
|
||||
/** Reap a thread. Arranges for the thread to be automatically
|
||||
* joined.
|
||||
*
|
||||
* @sa vcos_thread_join().
|
||||
*
|
||||
* @param thread the thread to terminate
|
||||
* @param on_terminated called after the thread has exited
|
||||
* @param cxt pass back to the callback
|
||||
*
|
||||
*/
|
||||
void vcos_thread_reap(VCOS_THREAD_T *thread, void (*on_terminated)(void*), void *cxt);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <interface/vcos/vcos.h>
|
||||
#ifdef HAVE_CMAKE_CONFIG
|
||||
#include "cmake_config.h"
|
||||
#endif
|
||||
#ifdef HAVE_EXECINFO_H
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
void vcos_backtrace_self(void)
|
||||
{
|
||||
#ifdef HAVE_EXECINFO_H
|
||||
void *stack[64];
|
||||
int depth = backtrace(stack, sizeof(stack)/sizeof(stack[0]));
|
||||
char **names = backtrace_symbols(stack, depth);
|
||||
int i;
|
||||
if (names)
|
||||
{
|
||||
for (i=0; i<depth; i++)
|
||||
{
|
||||
printf("%s\n", names[i]);
|
||||
}
|
||||
free(names);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# MSVC5 does not fully support C99, enabling declaration-after-statement
|
||||
# warnings allows a common MSVC5 build error to be detected in Linux builds.
|
||||
if (CMAKE_COMPILER_IS_GNUCC)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wdeclaration-after-statement")
|
||||
add_definitions (-D_GNU_SOURCE)
|
||||
endif ()
|
||||
|
||||
set (HEADERS
|
||||
vcos_platform.h
|
||||
vcos_platform_types.h
|
||||
)
|
||||
|
||||
foreach (header ${HEADERS})
|
||||
configure_file ("${header}" "${VCOS_HEADERS_BUILD_DIR}/${header}" COPYONLY)
|
||||
endforeach ()
|
||||
|
||||
add_subdirectory (../generic generic)
|
||||
|
||||
set (SOURCES
|
||||
vcos_pthreads.c
|
||||
vcos_dlfcn.c
|
||||
../glibc/vcos_backtrace.c
|
||||
../generic/vcos_generic_event_flags.c
|
||||
../generic/vcos_mem_from_malloc.c
|
||||
../generic/vcos_generic_named_sem.c
|
||||
../generic/vcos_generic_safe_string.c
|
||||
../generic/vcos_generic_reentrant_mtx.c
|
||||
../generic/vcos_abort.c
|
||||
../generic/vcos_cmd.c
|
||||
../generic/vcos_init.c
|
||||
../generic/vcos_msgqueue.c
|
||||
../generic/vcos_logcat.c
|
||||
../generic/vcos_generic_blockpool.c
|
||||
)
|
||||
|
||||
if (VCOS_PTHREADS_BUILD_SHARED)
|
||||
add_library (vcos SHARED ${SOURCES})
|
||||
target_link_libraries (vcos pthread dl rt)
|
||||
else ()
|
||||
add_library (vcos ${SOURCES})
|
||||
target_link_libraries (vcos pthread rt)
|
||||
endif ()
|
||||
|
||||
|
||||
#install(FILES ${HEADERS} DESTINATION include)
|
||||
install(TARGETS vcos DESTINATION lib)
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "interface/vcos/vcos.h"
|
||||
#include "interface/vcos/vcos_dlfcn.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
void *vcos_dlopen(const char *name, int mode)
|
||||
{
|
||||
return dlopen(name, mode);
|
||||
}
|
||||
|
||||
void (*vcos_dlsym(void *handle, const char *name))(void)
|
||||
{
|
||||
return dlsym(handle, name);
|
||||
}
|
||||
|
||||
int vcos_dlclose (void *handle)
|
||||
{
|
||||
return dlclose(handle);
|
||||
}
|
||||
|
||||
int vcos_dlerror(int *err, char *buf, size_t buflen)
|
||||
{
|
||||
/* not really threadsafe! */
|
||||
const char *errmsg = dlerror();
|
||||
|
||||
vcos_assert(buflen > 0);
|
||||
|
||||
if (errmsg)
|
||||
{
|
||||
*err = -1;
|
||||
strncpy(buf, errmsg, buflen);
|
||||
buf[buflen-1] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
*err = 0;
|
||||
buf[0] = '\0';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
FIXME: This code should be moved to 'linux', it is linux-specific and not generic
|
||||
on 'pthreads'.
|
||||
============================================================================*/
|
||||
|
||||
#ifndef VCOS_MUTEX_FROM_FUTEX_H
|
||||
#define VCOS_MUTEX_FROM_FUTEX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "interface/vcos/vcos_types.h"
|
||||
#include "vcos_platform.h"
|
||||
|
||||
typedef struct VCOS_FUTEX_T
|
||||
{
|
||||
volatile int value;
|
||||
} VCOS_FUTEX_T;
|
||||
|
||||
typedef VCOS_FUTEX_T VCOS_MUTEX_T;
|
||||
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_futex_init(VCOS_FUTEX_T *futex);
|
||||
VCOSPRE_ void VCOSPOST_ vcos_futex_delete(VCOS_FUTEX_T *futex);
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_futex_lock(VCOS_FUTEX_T *futex);
|
||||
VCOSPRE_ void VCOSPOST_ vcos_futex_unlock(VCOS_FUTEX_T *futex);
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_futex_trylock(VCOS_FUTEX_T *futex);
|
||||
|
||||
#if defined(VCOS_INLINE_BODIES)
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_mutex_create(VCOS_MUTEX_T *latch, const char *name) {
|
||||
vcos_unused(name);
|
||||
return vcos_futex_init(latch);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_mutex_delete(VCOS_MUTEX_T *latch) {
|
||||
vcos_futex_delete(latch);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_mutex_lock(VCOS_MUTEX_T *latch) {
|
||||
return vcos_futex_lock(latch);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_mutex_unlock(VCOS_MUTEX_T *latch) {
|
||||
vcos_futex_unlock(latch);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
int vcos_mutex_is_locked(VCOS_MUTEX_T *latch) {
|
||||
int rc = latch->value;
|
||||
if (!rc) {
|
||||
/* it wasn't locked */
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return 1; /* it was locked */
|
||||
}
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_mutex_trylock(VCOS_MUTEX_T *m) {
|
||||
return vcos_futex_trylock(m);
|
||||
}
|
||||
|
||||
#endif /* VCOS_INLINE_BODIES */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* VCOS_MUTEX_FROM_FUTEX_H */
|
||||
|
||||
@@ -0,0 +1,749 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - pthreads types
|
||||
=============================================================================*/
|
||||
|
||||
/* Do not include this file directly - instead include it via vcos.h */
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Pthreads implementation of VCOS.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef VCOS_PLATFORM_H
|
||||
#define VCOS_PLATFORM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
|
||||
#define VCOS_HAVE_RTOS 1
|
||||
#define VCOS_HAVE_SEMAPHORE 1
|
||||
#define VCOS_HAVE_EVENT 1
|
||||
#define VCOS_HAVE_QUEUE 0
|
||||
#define VCOS_HAVE_LEGACY_ISR 0
|
||||
#define VCOS_HAVE_TIMER 1
|
||||
#define VCOS_HAVE_CANCELLATION_SAFE_TIMER 1
|
||||
#define VCOS_HAVE_MEMPOOL 0
|
||||
#define VCOS_HAVE_ISR 0
|
||||
#define VCOS_HAVE_ATOMIC_FLAGS 1
|
||||
#define VCOS_HAVE_THREAD_AT_EXIT 1
|
||||
#define VCOS_HAVE_ONCE 1
|
||||
#define VCOS_HAVE_BLOCK_POOL 1
|
||||
#define VCOS_HAVE_FILE 0
|
||||
#define VCOS_HAVE_PROC 0
|
||||
#define VCOS_HAVE_CFG 0
|
||||
#define VCOS_HAVE_ALIEN_THREADS 1
|
||||
#define VCOS_HAVE_CMD 1
|
||||
#define VCOS_HAVE_EVENT_FLAGS 1
|
||||
#define VCOS_WANT_LOG_CMD 0 /* User apps should do their own thing */
|
||||
|
||||
#define VCOS_ALWAYS_WANT_LOGGING
|
||||
|
||||
#ifdef __linux__
|
||||
#define VCOS_HAVE_BACKTRACE 1
|
||||
#endif
|
||||
|
||||
#define VCOS_SO_EXT ".so"
|
||||
|
||||
/* Linux/pthreads seems to have different timer characteristics */
|
||||
#define VCOS_TIMER_MARGIN_EARLY 0
|
||||
#define VCOS_TIMER_MARGIN_LATE 15
|
||||
|
||||
typedef sem_t VCOS_SEMAPHORE_T;
|
||||
typedef uint32_t VCOS_UNSIGNED;
|
||||
typedef uint32_t VCOS_OPTION;
|
||||
typedef pthread_key_t VCOS_TLS_KEY_T;
|
||||
typedef pthread_once_t VCOS_ONCE_T;
|
||||
|
||||
typedef struct VCOS_LLTHREAD_T
|
||||
{
|
||||
pthread_t thread; // Must be first field.
|
||||
} VCOS_LLTHREAD_T;
|
||||
|
||||
/* VCOS_CASSERT(offsetof(VCOS_LLTHREAD_T, thread) == 0); */
|
||||
|
||||
#ifndef VCOS_USE_VCOS_FUTEX
|
||||
typedef pthread_mutex_t VCOS_MUTEX_T;
|
||||
#else
|
||||
#include "vcos_futex_mutex.h"
|
||||
#endif /* VCOS_USE_VCOS_FUTEX */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
VCOS_MUTEX_T mutex;
|
||||
sem_t sem;
|
||||
} VCOS_EVENT_T;
|
||||
|
||||
#define VCOS_ONCE_INIT PTHREAD_ONCE_INIT
|
||||
|
||||
typedef struct VCOS_TIMER_T
|
||||
{
|
||||
pthread_t thread; /**< id of the timer thread */
|
||||
|
||||
pthread_mutex_t lock; /**< lock protecting all other members of the struct */
|
||||
pthread_cond_t settings_changed; /**< cond. var. for informing the timer thread about changes*/
|
||||
int quit; /**< non-zero if the timer thread is requested to quit*/
|
||||
|
||||
struct timespec expires; /**< absolute time of next expiration, or 0 if disarmed*/
|
||||
|
||||
void (*orig_expiration_routine)(void*);/**< the expiration routine provided by the user of the timer*/
|
||||
void *orig_context; /**< the context for exp. routine provided by the user*/
|
||||
|
||||
} VCOS_TIMER_T;
|
||||
|
||||
/** Thread attribute structure. Don't use pthread_attr directly, as
|
||||
* the calls can fail, and inits must match deletes.
|
||||
*/
|
||||
typedef struct VCOS_THREAD_ATTR_T
|
||||
{
|
||||
void *ta_stackaddr;
|
||||
VCOS_UNSIGNED ta_stacksz;
|
||||
VCOS_UNSIGNED ta_priority;
|
||||
VCOS_UNSIGNED ta_affinity;
|
||||
VCOS_UNSIGNED ta_timeslice;
|
||||
VCOS_UNSIGNED legacy;
|
||||
} VCOS_THREAD_ATTR_T;
|
||||
|
||||
/** Called at thread exit.
|
||||
*/
|
||||
typedef struct VCOS_THREAD_EXIT_T
|
||||
{
|
||||
void (*pfn)(void *);
|
||||
void *cxt;
|
||||
} VCOS_THREAD_EXIT_T;
|
||||
#define VCOS_MAX_EXIT_HANDLERS 4
|
||||
|
||||
typedef struct VCOS_THREAD_T
|
||||
{
|
||||
pthread_t thread; /**< The thread itself */
|
||||
VCOS_THREAD_ENTRY_FN_T entry; /**< The thread entry point */
|
||||
void *arg; /**< The argument to be passed to entry */
|
||||
VCOS_SEMAPHORE_T suspend; /**< For support event groups and similar - a per thread semaphore */
|
||||
|
||||
VCOS_TIMER_T task_timer;
|
||||
int task_timer_created; /**< non-zero if the task timer has already been created*/
|
||||
void (*orig_task_timer_expiration_routine)(void*);
|
||||
void *orig_task_timer_context;
|
||||
|
||||
VCOS_UNSIGNED legacy;
|
||||
char name[16]; /**< Record the name of this thread, for diagnostics */
|
||||
VCOS_UNSIGNED dummy; /**< Dummy thread created for non-vcos created threads */
|
||||
|
||||
/** Callback invoked at thread exit time */
|
||||
VCOS_THREAD_EXIT_T at_exit[VCOS_MAX_EXIT_HANDLERS];
|
||||
} VCOS_THREAD_T;
|
||||
|
||||
#ifdef VCOS_PTHREADS_WANT_HISR_EMULATION
|
||||
|
||||
typedef struct
|
||||
{
|
||||
VCOS_THREAD_T thread;
|
||||
char stack[1024];
|
||||
VCOS_SEMAPHORE_T waitsem;
|
||||
} VCOS_HISR_T;
|
||||
|
||||
#endif
|
||||
|
||||
#define VCOS_SUSPEND -1
|
||||
#define VCOS_NO_SUSPEND 0
|
||||
|
||||
#define VCOS_START 1
|
||||
#define VCOS_NO_START 0
|
||||
|
||||
#define VCOS_THREAD_PRI_MIN (sched_get_priority_min(SCHED_OTHER))
|
||||
#define VCOS_THREAD_PRI_MAX (sched_get_priority_max(SCHED_OTHER))
|
||||
|
||||
#define VCOS_THREAD_PRI_INCREASE (1)
|
||||
#define VCOS_THREAD_PRI_HIGHEST VCOS_THREAD_PRI_MAX
|
||||
#define VCOS_THREAD_PRI_LOWEST VCOS_THREAD_PRI_MIN
|
||||
#define VCOS_THREAD_PRI_NORMAL ((VCOS_THREAD_PRI_MAX+VCOS_THREAD_PRI_MIN)/2)
|
||||
#define VCOS_THREAD_PRI_BELOW_NORMAL (VCOS_THREAD_PRI_NORMAL-VCOS_THREAD_PRI_INCREASE)
|
||||
#define VCOS_THREAD_PRI_ABOVE_NORMAL (VCOS_THREAD_PRI_NORMAL+VCOS_THREAD_PRI_INCREASE)
|
||||
#define VCOS_THREAD_PRI_REALTIME VCOS_THREAD_PRI_MAX
|
||||
|
||||
#define _VCOS_AFFINITY_DEFAULT 0
|
||||
#define _VCOS_AFFINITY_CPU0 0x100
|
||||
#define _VCOS_AFFINITY_CPU1 0x200
|
||||
#define _VCOS_AFFINITY_MASK 0x300
|
||||
#define VCOS_CAN_SET_STACK_ADDR 0
|
||||
|
||||
#define VCOS_TICKS_PER_SECOND _vcos_get_ticks_per_second()
|
||||
|
||||
#include "generic/vcos_generic_event_flags.h"
|
||||
#include "generic/vcos_generic_blockpool.h"
|
||||
#include "generic/vcos_mem_from_malloc.h"
|
||||
|
||||
/** Convert errno values into the values recognized by vcos */
|
||||
VCOSPRE_ VCOS_STATUS_T vcos_pthreads_map_error(int error);
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_pthreads_map_errno(void);
|
||||
|
||||
/** Register a function to be called when the current thread exits.
|
||||
*/
|
||||
extern VCOS_STATUS_T vcos_thread_at_exit(void (*pfn)(void*), void *cxt);
|
||||
|
||||
extern uint32_t _vcos_get_ticks_per_second(void);
|
||||
|
||||
/**
|
||||
* Set to 1 by default when ANDROID is defined. Allows runtime
|
||||
* switching for console apps.
|
||||
*/
|
||||
extern int vcos_use_android_log;
|
||||
|
||||
typedef struct {
|
||||
VCOS_MUTEX_T mutex;
|
||||
uint32_t flags;
|
||||
} VCOS_ATOMIC_FLAGS_T;
|
||||
|
||||
#if defined(VCOS_INLINE_BODIES)
|
||||
|
||||
#undef VCOS_ASSERT_LOGGING_DISABLE
|
||||
#define VCOS_ASSERT_LOGGING_DISABLE 1
|
||||
|
||||
|
||||
/*
|
||||
* Counted Semaphores
|
||||
*/
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_semaphore_wait(VCOS_SEMAPHORE_T *sem) {
|
||||
int ret;
|
||||
/* gdb causes sem_wait() to EINTR when a breakpoint is hit, retry here */
|
||||
while ((ret = sem_wait(sem)) == -1 && errno == EINTR)
|
||||
continue;
|
||||
vcos_assert(ret==0);
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_semaphore_trywait(VCOS_SEMAPHORE_T *sem) {
|
||||
int ret;
|
||||
while ((ret = sem_trywait(sem)) == -1 && errno == EINTR)
|
||||
continue;
|
||||
if (ret == 0)
|
||||
return VCOS_SUCCESS;
|
||||
else if (errno == EAGAIN)
|
||||
return VCOS_EAGAIN;
|
||||
else {
|
||||
vcos_assert(0);
|
||||
return VCOS_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Wait on a semaphore with a timeout.
|
||||
*
|
||||
* Note that this function may not be implemented on all
|
||||
* platforms, and may not be efficient on all platforms
|
||||
* (see comment in vcos_semaphore_wait)
|
||||
*
|
||||
* Try to obtain the semaphore. If it is already taken, return
|
||||
* VCOS_EAGAIN.
|
||||
* @param sem Semaphore to wait on
|
||||
* @param timeout Number of milliseconds to wait before
|
||||
* returning if the semaphore can't be acquired.
|
||||
* @return VCOS_SUCCESS - semaphore was taken.
|
||||
* VCOS_EAGAIN - could not take semaphore (i.e. timeout
|
||||
* expired)
|
||||
* VCOS_EINVAL - Some other error (most likely bad
|
||||
* parameters).
|
||||
*/
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_semaphore_wait_timeout(VCOS_SEMAPHORE_T *sem, VCOS_UNSIGNED timeout) {
|
||||
struct timespec ts;
|
||||
int ret;
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
|
||||
return VCOS_EINVAL;
|
||||
ts.tv_sec += timeout/1000;
|
||||
ts.tv_nsec += (timeout%1000)*1000*1000;
|
||||
if (ts.tv_nsec > 1000000000) {
|
||||
ts.tv_sec++;
|
||||
ts.tv_nsec -= 1000000000;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
ret = sem_timedwait( sem, &ts );
|
||||
if (ret == 0) {
|
||||
return VCOS_SUCCESS;
|
||||
} else {
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
} else if (errno == ETIMEDOUT) {
|
||||
return VCOS_EAGAIN;
|
||||
} else {
|
||||
vcos_assert(0);
|
||||
return VCOS_EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_semaphore_create(VCOS_SEMAPHORE_T *sem,
|
||||
const char *name,
|
||||
VCOS_UNSIGNED initial_count) {
|
||||
int rc = sem_init(sem, 0, initial_count);
|
||||
(void)name;
|
||||
if (rc != -1) return VCOS_SUCCESS;
|
||||
else return vcos_pthreads_map_errno();
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_semaphore_delete(VCOS_SEMAPHORE_T *sem) {
|
||||
int rc = sem_destroy(sem);
|
||||
vcos_assert(rc != -1);
|
||||
(void)rc;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_semaphore_post(VCOS_SEMAPHORE_T *sem) {
|
||||
int rc = sem_post(sem);
|
||||
vcos_assert(rc == 0);
|
||||
(void)rc;
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
*
|
||||
* Threads
|
||||
*
|
||||
***********************************************************/
|
||||
|
||||
|
||||
extern VCOS_THREAD_T *vcos_dummy_thread_create(void);
|
||||
extern pthread_key_t _vcos_thread_current_key;
|
||||
extern uint64_t vcos_getmicrosecs64_internal(void);
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
uint32_t vcos_getmicrosecs(void) { return (uint32_t)vcos_getmicrosecs64_internal(); }
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
uint64_t vcos_getmicrosecs64(void) { return vcos_getmicrosecs64_internal(); }
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_THREAD_T *vcos_thread_current(void) {
|
||||
void *ret = pthread_getspecific(_vcos_thread_current_key);
|
||||
if (ret == NULL)
|
||||
{
|
||||
ret = vcos_dummy_thread_create();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
return static_cast<VCOS_THREAD_T*>(ret);
|
||||
#else
|
||||
return (VCOS_THREAD_T *)ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_sleep(uint32_t ms) {
|
||||
struct timespec ts;
|
||||
ts.tv_sec = ms/1000;
|
||||
ts.tv_nsec = ms % 1000 * (1000000);
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_thread_attr_setstack(VCOS_THREAD_ATTR_T *attr, void *addr, VCOS_UNSIGNED sz) {
|
||||
attr->ta_stackaddr = addr;
|
||||
attr->ta_stacksz = sz;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_thread_attr_setstacksize(VCOS_THREAD_ATTR_T *attr, VCOS_UNSIGNED sz) {
|
||||
attr->ta_stacksz = sz;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_thread_attr_setpriority(VCOS_THREAD_ATTR_T *attr, VCOS_UNSIGNED pri) {
|
||||
(void)attr;
|
||||
(void)pri;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_thread_set_priority(VCOS_THREAD_T *thread, VCOS_UNSIGNED p) {
|
||||
/* not implemented */
|
||||
(void)thread;
|
||||
(void)p;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_UNSIGNED vcos_thread_get_priority(VCOS_THREAD_T *thread) {
|
||||
/* not implemented */
|
||||
(void)thread;
|
||||
return 0;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_thread_set_affinity(VCOS_THREAD_T *thread, VCOS_UNSIGNED affinity) {
|
||||
/* not implemented */
|
||||
vcos_unused(thread);
|
||||
vcos_unused(affinity);
|
||||
}
|
||||
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_thread_attr_setaffinity(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED affinity) {
|
||||
attrs->ta_affinity = affinity;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_thread_attr_settimeslice(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED ts) {
|
||||
attrs->ta_timeslice = ts;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void _vcos_thread_attr_setlegacyapi(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED legacy) {
|
||||
attrs->legacy = legacy;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_thread_attr_setautostart(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED autostart) {
|
||||
(void)attrs;
|
||||
(void)autostart;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_LLTHREAD_T *vcos_llthread_current(void) {
|
||||
return (VCOS_LLTHREAD_T *)pthread_self();
|
||||
}
|
||||
|
||||
/*
|
||||
* Mutexes
|
||||
*/
|
||||
|
||||
#ifndef VCOS_USE_VCOS_FUTEX
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_mutex_create(VCOS_MUTEX_T *latch, const char *name) {
|
||||
int rc = pthread_mutex_init(latch, NULL);
|
||||
(void)name;
|
||||
if (rc == 0) return VCOS_SUCCESS;
|
||||
else return vcos_pthreads_map_errno();
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_mutex_delete(VCOS_MUTEX_T *latch) {
|
||||
int rc = pthread_mutex_destroy(latch);
|
||||
(void)rc;
|
||||
vcos_assert(rc==0);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_mutex_lock(VCOS_MUTEX_T *latch) {
|
||||
int rc = pthread_mutex_lock(latch);
|
||||
vcos_assert(rc==0);
|
||||
(void)rc;
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_mutex_unlock(VCOS_MUTEX_T *latch) {
|
||||
int rc = pthread_mutex_unlock(latch);
|
||||
(void)rc;
|
||||
vcos_assert(rc==0);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
int vcos_mutex_is_locked(VCOS_MUTEX_T *m) {
|
||||
int rc = pthread_mutex_trylock(m);
|
||||
if (rc == 0) {
|
||||
pthread_mutex_unlock(m);
|
||||
/* it wasn't locked */
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return 1; /* it was locked */
|
||||
}
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_mutex_trylock(VCOS_MUTEX_T *m) {
|
||||
int rc = pthread_mutex_trylock(m);
|
||||
(void)rc;
|
||||
return (rc == 0) ? VCOS_SUCCESS : VCOS_EAGAIN;
|
||||
}
|
||||
|
||||
#endif /* VCOS_USE_VCOS_FUTEX */
|
||||
|
||||
/*
|
||||
* Events
|
||||
*/
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_event_create(VCOS_EVENT_T *event, const char *debug_name)
|
||||
{
|
||||
VCOS_STATUS_T status;
|
||||
|
||||
int rc = sem_init(&event->sem, 0, 0);
|
||||
if (rc != 0) return vcos_pthreads_map_errno();
|
||||
|
||||
status = vcos_mutex_create(&event->mutex, debug_name);
|
||||
if (status != VCOS_SUCCESS) {
|
||||
sem_destroy(&event->sem);
|
||||
return status;
|
||||
}
|
||||
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_event_signal(VCOS_EVENT_T *event)
|
||||
{
|
||||
#if VCOS_ASSERT_ENABLED
|
||||
int ok = 0;
|
||||
#endif
|
||||
int value;
|
||||
|
||||
if (vcos_mutex_lock(&event->mutex) != VCOS_SUCCESS)
|
||||
goto fail_mtx;
|
||||
|
||||
if (sem_getvalue(&event->sem, &value) != 0)
|
||||
goto fail_sem;
|
||||
|
||||
if (value == 0)
|
||||
if (sem_post(&event->sem) != 0)
|
||||
goto fail_sem;
|
||||
#if VCOS_ASSERT_ENABLED
|
||||
ok = 1;
|
||||
#endif
|
||||
fail_sem:
|
||||
vcos_mutex_unlock(&event->mutex);
|
||||
fail_mtx:
|
||||
vcos_assert(ok);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_event_wait(VCOS_EVENT_T *event)
|
||||
{
|
||||
int ret;
|
||||
/* gdb causes sem_wait() to EINTR when a breakpoint is hit, retry here */
|
||||
while ((ret = sem_wait(&event->sem)) == -1 && errno == EINTR)
|
||||
continue;
|
||||
vcos_assert(ret==0);
|
||||
return ret == 0 ? VCOS_SUCCESS : (VCOS_STATUS_T)errno;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_event_try(VCOS_EVENT_T *event)
|
||||
{
|
||||
int ret;
|
||||
while ((ret = sem_trywait(&event->sem)) == -1 && errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (ret == -1 && errno == EAGAIN)
|
||||
return VCOS_EAGAIN;
|
||||
else
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_event_delete(VCOS_EVENT_T *event)
|
||||
{
|
||||
int rc = sem_destroy(&event->sem);
|
||||
vcos_assert(rc != -1);
|
||||
(void)rc;
|
||||
|
||||
vcos_mutex_delete(&event->mutex);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_UNSIGNED vcos_process_id_current(void) {
|
||||
return (VCOS_UNSIGNED) getpid();
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
int vcos_strcasecmp(const char *s1, const char *s2) {
|
||||
return strcasecmp(s1,s2);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
int vcos_strncasecmp(const char *s1, const char *s2, size_t n) {
|
||||
return strncasecmp(s1,s2,n);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
int vcos_in_interrupt(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* For support event groups - per thread semaphore */
|
||||
VCOS_INLINE_IMPL
|
||||
void _vcos_thread_sem_wait(void) {
|
||||
VCOS_THREAD_T *t = vcos_thread_current();
|
||||
vcos_semaphore_wait(&t->suspend);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void _vcos_thread_sem_post(VCOS_THREAD_T *target) {
|
||||
vcos_semaphore_post(&target->suspend);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_tls_create(VCOS_TLS_KEY_T *key) {
|
||||
int st = pthread_key_create(key, NULL);
|
||||
return st == 0 ? VCOS_SUCCESS: VCOS_ENOMEM;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_tls_delete(VCOS_TLS_KEY_T tls) {
|
||||
pthread_key_delete(tls);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_tls_set(VCOS_TLS_KEY_T tls, void *v) {
|
||||
pthread_setspecific(tls, v);
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void *vcos_tls_get(VCOS_TLS_KEY_T tls) {
|
||||
return pthread_getspecific(tls);
|
||||
}
|
||||
|
||||
#if VCOS_HAVE_ATOMIC_FLAGS
|
||||
|
||||
/*
|
||||
* Atomic flags
|
||||
*/
|
||||
|
||||
/* TODO implement properly... */
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_STATUS_T vcos_atomic_flags_create(VCOS_ATOMIC_FLAGS_T *atomic_flags)
|
||||
{
|
||||
atomic_flags->flags = 0;
|
||||
return vcos_mutex_create(&atomic_flags->mutex, "VCOS_ATOMIC_FLAGS_T");
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_atomic_flags_or(VCOS_ATOMIC_FLAGS_T *atomic_flags, uint32_t flags)
|
||||
{
|
||||
vcos_mutex_lock(&atomic_flags->mutex);
|
||||
atomic_flags->flags |= flags;
|
||||
vcos_mutex_unlock(&atomic_flags->mutex);
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
uint32_t vcos_atomic_flags_get_and_clear(VCOS_ATOMIC_FLAGS_T *atomic_flags)
|
||||
{
|
||||
uint32_t flags;
|
||||
vcos_mutex_lock(&atomic_flags->mutex);
|
||||
flags = atomic_flags->flags;
|
||||
atomic_flags->flags = 0;
|
||||
vcos_mutex_unlock(&atomic_flags->mutex);
|
||||
return flags;
|
||||
}
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
void vcos_atomic_flags_delete(VCOS_ATOMIC_FLAGS_T *atomic_flags)
|
||||
{
|
||||
vcos_mutex_delete(&atomic_flags->mutex);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(linux) || defined(_HAVE_SBRK)
|
||||
|
||||
/* not exactly the free memory, but a measure of it */
|
||||
|
||||
VCOS_INLINE_IMPL
|
||||
unsigned long vcos_get_free_mem(void) {
|
||||
return (unsigned long)sbrk(0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef VCOS_PTHREADS_WANT_HISR_EMULATION
|
||||
VCOS_STATUS_T vcos_legacy_hisr_create(VCOS_HISR_T *hisr, const char *name,
|
||||
void (*entry)(void),
|
||||
VCOS_UNSIGNED pri,
|
||||
void *stack, VCOS_UNSIGNED stack_size);
|
||||
|
||||
void vcos_legacy_hisr_activate(VCOS_HISR_T *hisr);
|
||||
|
||||
void vcos_legacy_hisr_delete(VCOS_HISR_T *hisr);
|
||||
|
||||
#endif
|
||||
|
||||
#undef VCOS_ASSERT_LOGGING_DISABLE
|
||||
#define VCOS_ASSERT_LOGGING_DISABLE 0
|
||||
|
||||
#endif /* VCOS_INLINE_BODIES */
|
||||
|
||||
#define vcos_log_platform_init() _vcos_log_platform_init()
|
||||
VCOSPRE_ void VCOSPOST_ _vcos_log_platform_init(void);
|
||||
|
||||
VCOS_INLINE_DECL void _vcos_thread_sem_wait(void);
|
||||
VCOS_INLINE_DECL void _vcos_thread_sem_post(VCOS_THREAD_T *);
|
||||
|
||||
#define VCOS_APPLICATION_ARGC vcos_get_argc()
|
||||
#define VCOS_APPLICATION_ARGV vcos_get_argv()
|
||||
|
||||
#include "generic/vcos_generic_reentrant_mtx.h"
|
||||
#include "generic/vcos_generic_named_sem.h"
|
||||
#include "generic/vcos_generic_quickslow_mutex.h"
|
||||
#include "generic/vcos_common.h"
|
||||
|
||||
#define _VCOS_LOG_LEVEL() getenv("VC_LOGLEVEL")
|
||||
|
||||
VCOS_STATIC_INLINE
|
||||
char *vcos_strdup(const char *str)
|
||||
{
|
||||
return strdup(str);
|
||||
}
|
||||
|
||||
typedef void (*VCOS_ISR_HANDLER_T)(VCOS_UNSIGNED vecnum);
|
||||
|
||||
#define VCOS_DL_LAZY RTLD_LAZY
|
||||
#define VCOS_DL_NOW RTLD_NOW
|
||||
#define VCOS_DL_LOCAL RTLD_LOCAL
|
||||
#define VCOS_DL_GLOBAL RTLD_GLOBAL
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* VCOS_PLATFORM_H */
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - platform-specific types and defines
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_PLATFORM_TYPES_H
|
||||
#define VCOS_PLATFORM_TYPES_H
|
||||
|
||||
#include "vcos_inttypes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define VCOSPRE_ extern
|
||||
#define VCOSPOST_
|
||||
|
||||
#if defined(__GNUC__) && (( __GNUC__ > 2 ) || (( __GNUC__ == 2 ) && ( __GNUC_MINOR__ >= 3 )))
|
||||
#define VCOS_FORMAT_ATTR_(ARCHETYPE, STRING_INDEX, FIRST_TO_CHECK) __attribute__ ((format (ARCHETYPE, STRING_INDEX, FIRST_TO_CHECK)))
|
||||
#else
|
||||
#define VCOS_FORMAT_ATTR_(ARCHETYPE, STRING_INDEX, FIRST_TO_CHECK)
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && !defined(NDEBUG) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
#define VCOS_BKPT ({ __asm volatile ("int3":::"memory"); })
|
||||
#endif
|
||||
/*#define VCOS_BKPT vcos_abort() */
|
||||
|
||||
#define VCOS_ASSERT_LOGGING 1
|
||||
#define VCOS_ASSERT_LOGGING_DISABLE 0
|
||||
|
||||
extern void
|
||||
vcos_pthreads_logging_assert(const char *file, const char *func, unsigned int line, const char *fmt, ...);
|
||||
|
||||
#define VCOS_ASSERT_MSG(...) ((VCOS_ASSERT_LOGGING && !VCOS_ASSERT_LOGGING_DISABLE) ? vcos_pthreads_logging_assert(__FILE__, __func__, __LINE__, __VA_ARGS__) : (void)0)
|
||||
|
||||
#define VCOS_INLINE_BODIES
|
||||
#define VCOS_INLINE_DECL extern __inline__
|
||||
#define VCOS_INLINE_IMPL static __inline__
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,902 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*#define VCOS_INLINE_BODIES */
|
||||
#include "interface/vcos/vcos.h"
|
||||
#include "interface/vcos/vcos_msgqueue.h"
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <linux/param.h>
|
||||
|
||||
/* Cygwin doesn't always have prctl.h and it doesn't have PR_SET_NAME */
|
||||
#if defined( __linux__ )
|
||||
# if !defined(HAVE_PRCTL)
|
||||
# define HAVE_PRCTL
|
||||
# endif
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CMAKE_CONFIG
|
||||
#include "cmake_config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MTRACE
|
||||
#include <mcheck.h>
|
||||
#endif
|
||||
|
||||
#if defined(ANDROID)
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_DEFAULT_STACK_SIZE
|
||||
#define VCOS_DEFAULT_STACK_SIZE 4096
|
||||
#endif
|
||||
|
||||
static int vcos_argc;
|
||||
static const char **vcos_argv;
|
||||
|
||||
typedef void (*LEGACY_ENTRY_FN_T)(int, void *);
|
||||
|
||||
static VCOS_THREAD_ATTR_T default_attrs = {
|
||||
.ta_stacksz = VCOS_DEFAULT_STACK_SIZE,
|
||||
};
|
||||
|
||||
/** Singleton global lock used for vcos_global_lock/unlock(). */
|
||||
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
#ifdef ANDROID
|
||||
static VCOS_MUTEX_T printf_lock;
|
||||
#endif
|
||||
|
||||
/* Create a per-thread key for faking up vcos access
|
||||
* on non-vcos threads.
|
||||
*/
|
||||
pthread_key_t _vcos_thread_current_key;
|
||||
|
||||
static VCOS_UNSIGNED _vcos_thread_current_key_created = 0;
|
||||
static VCOS_ONCE_T current_thread_key_once; /* init just once */
|
||||
|
||||
static void vcos_thread_cleanup(VCOS_THREAD_T *thread)
|
||||
{
|
||||
vcos_semaphore_delete(&thread->suspend);
|
||||
if (thread->task_timer_created)
|
||||
{
|
||||
vcos_timer_delete(&thread->task_timer);
|
||||
}
|
||||
}
|
||||
|
||||
static void vcos_dummy_thread_cleanup(void *cxt)
|
||||
{
|
||||
VCOS_THREAD_T *thread = cxt;
|
||||
if (thread->dummy)
|
||||
{
|
||||
int i;
|
||||
/* call termination functions */
|
||||
for (i=0; thread->at_exit[i].pfn != NULL; i++)
|
||||
{
|
||||
thread->at_exit[i].pfn(thread->at_exit[i].cxt);
|
||||
}
|
||||
vcos_thread_cleanup(thread);
|
||||
vcos_free(thread);
|
||||
}
|
||||
}
|
||||
|
||||
static void current_thread_key_init(void)
|
||||
{
|
||||
vcos_assert(!_vcos_thread_current_key_created);
|
||||
pthread_key_create (&_vcos_thread_current_key, vcos_dummy_thread_cleanup);
|
||||
_vcos_thread_current_key_created = 1;
|
||||
}
|
||||
|
||||
|
||||
/* A VCOS wrapper for the thread which called vcos_init. */
|
||||
static VCOS_THREAD_T vcos_thread_main;
|
||||
|
||||
static void *vcos_thread_entry(void *arg)
|
||||
{
|
||||
int i;
|
||||
void *ret;
|
||||
VCOS_THREAD_T *thread = (VCOS_THREAD_T *)arg;
|
||||
|
||||
vcos_assert(thread != NULL);
|
||||
thread->dummy = 0;
|
||||
|
||||
pthread_setspecific(_vcos_thread_current_key, thread);
|
||||
#if defined( HAVE_PRCTL ) && defined( PR_SET_NAME )
|
||||
/* cygwin doesn't have PR_SET_NAME */
|
||||
prctl( PR_SET_NAME, (unsigned long)thread->name, 0, 0, 0 );
|
||||
#endif
|
||||
if (thread->legacy)
|
||||
{
|
||||
LEGACY_ENTRY_FN_T fn = (LEGACY_ENTRY_FN_T)thread->entry;
|
||||
(*fn)(0, thread->arg);
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = (*thread->entry)(thread->arg);
|
||||
}
|
||||
|
||||
/* call termination functions */
|
||||
for (i=0; thread->at_exit[i].pfn != NULL; i++)
|
||||
{
|
||||
thread->at_exit[i].pfn(thread->at_exit[i].cxt);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void _task_timer_expiration_routine(void *cxt)
|
||||
{
|
||||
VCOS_THREAD_T *thread = (VCOS_THREAD_T *)cxt;
|
||||
|
||||
vcos_assert(thread->orig_task_timer_expiration_routine);
|
||||
thread->orig_task_timer_expiration_routine(thread->orig_task_timer_context);
|
||||
thread->orig_task_timer_expiration_routine = NULL;
|
||||
}
|
||||
|
||||
VCOS_STATUS_T vcos_thread_create(VCOS_THREAD_T *thread,
|
||||
const char *name,
|
||||
VCOS_THREAD_ATTR_T *attrs,
|
||||
VCOS_THREAD_ENTRY_FN_T entry,
|
||||
void *arg)
|
||||
{
|
||||
VCOS_STATUS_T st;
|
||||
pthread_attr_t pt_attrs;
|
||||
VCOS_THREAD_ATTR_T *local_attrs = attrs ? attrs : &default_attrs;
|
||||
int rc;
|
||||
|
||||
vcos_assert(thread);
|
||||
memset(thread, 0, sizeof(VCOS_THREAD_T));
|
||||
|
||||
rc = pthread_attr_init(&pt_attrs);
|
||||
if (rc < 0)
|
||||
return VCOS_ENOMEM;
|
||||
|
||||
st = vcos_semaphore_create(&thread->suspend, NULL, 0);
|
||||
if (st != VCOS_SUCCESS)
|
||||
{
|
||||
pthread_attr_destroy(&pt_attrs);
|
||||
return st;
|
||||
}
|
||||
|
||||
pthread_attr_setstacksize(&pt_attrs, local_attrs->ta_stacksz);
|
||||
#if VCOS_CAN_SET_STACK_ADDR
|
||||
if (local_attrs->ta_stackaddr)
|
||||
{
|
||||
pthread_attr_setstackaddr(&pt_attrs, local_attrs->ta_stackaddr);
|
||||
}
|
||||
#else
|
||||
vcos_demand(local_attrs->ta_stackaddr == 0);
|
||||
#endif
|
||||
|
||||
/* pthread_attr_setpriority(&pt_attrs, local_attrs->ta_priority); */
|
||||
|
||||
vcos_assert(local_attrs->ta_stackaddr == 0); /* Not possible */
|
||||
|
||||
thread->entry = entry;
|
||||
thread->arg = arg;
|
||||
thread->legacy = local_attrs->legacy;
|
||||
|
||||
strncpy(thread->name, name, sizeof(thread->name));
|
||||
thread->name[sizeof(thread->name)-1] = '\0';
|
||||
memset(thread->at_exit, 0, sizeof(thread->at_exit));
|
||||
|
||||
rc = pthread_create(&thread->thread, &pt_attrs, vcos_thread_entry, thread);
|
||||
|
||||
pthread_attr_destroy(&pt_attrs);
|
||||
|
||||
if (rc < 0)
|
||||
{
|
||||
vcos_semaphore_delete(&thread->suspend);
|
||||
return VCOS_ENOMEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
void vcos_thread_join(VCOS_THREAD_T *thread,
|
||||
void **pData)
|
||||
{
|
||||
pthread_join(thread->thread, pData);
|
||||
vcos_thread_cleanup(thread);
|
||||
}
|
||||
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_thread_create_classic(VCOS_THREAD_T *thread,
|
||||
const char *name,
|
||||
void *(*entry)(void *arg),
|
||||
void *arg,
|
||||
void *stack,
|
||||
VCOS_UNSIGNED stacksz,
|
||||
VCOS_UNSIGNED priaff,
|
||||
VCOS_UNSIGNED timeslice,
|
||||
VCOS_UNSIGNED autostart)
|
||||
{
|
||||
VCOS_THREAD_ATTR_T attrs;
|
||||
vcos_thread_attr_init(&attrs);
|
||||
vcos_thread_attr_setstacksize(&attrs, stacksz);
|
||||
vcos_thread_attr_setpriority(&attrs, priaff & ~_VCOS_AFFINITY_MASK);
|
||||
vcos_thread_attr_setaffinity(&attrs, priaff & _VCOS_AFFINITY_MASK);
|
||||
(void)timeslice;
|
||||
(void)autostart;
|
||||
|
||||
if (VCOS_CAN_SET_STACK_ADDR)
|
||||
{
|
||||
vcos_thread_attr_setstack(&attrs, stack, stacksz);
|
||||
}
|
||||
|
||||
return vcos_thread_create(thread, name, &attrs, entry, arg);
|
||||
}
|
||||
|
||||
uint64_t vcos_getmicrosecs64_internal(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
uint64_t tm = 0;
|
||||
|
||||
if (!gettimeofday(&tv, NULL))
|
||||
{
|
||||
tm = (tv.tv_sec * 1000000LL) + tv.tv_usec;
|
||||
}
|
||||
|
||||
return tm;
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
|
||||
static int log_prio[] =
|
||||
{
|
||||
ANDROID_LOG_INFO, /* VCOS_LOG_UNINITIALIZED */
|
||||
ANDROID_LOG_INFO, /* VCOS_LOG_NEVER */
|
||||
ANDROID_LOG_ERROR, /* VCOS_LOG_ERROR */
|
||||
ANDROID_LOG_WARN, /* VCOS_LOG_WARN */
|
||||
ANDROID_LOG_INFO, /* VCOS_LOG_INFO */
|
||||
ANDROID_LOG_DEBUG /* VCOS_LOG_TRACE */
|
||||
};
|
||||
|
||||
int vcos_use_android_log = 1;
|
||||
int vcos_log_to_file = 0;
|
||||
#else
|
||||
int vcos_use_android_log = 0;
|
||||
int vcos_log_to_file = 0;
|
||||
#endif
|
||||
|
||||
static FILE * log_fhandle = NULL;
|
||||
|
||||
void vcos_vlog_default_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args)
|
||||
{
|
||||
(void)_level;
|
||||
|
||||
#ifdef ANDROID
|
||||
if ( vcos_use_android_log )
|
||||
{
|
||||
__android_log_vprint(log_prio[_level], cat->name, fmt, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
vcos_mutex_lock(&printf_lock);
|
||||
#endif
|
||||
if(NULL != log_fhandle)
|
||||
{
|
||||
if (cat->flags.want_prefix)
|
||||
fprintf( log_fhandle, "%s: ", cat->name );
|
||||
vfprintf(log_fhandle, fmt, args);
|
||||
fputs("\n", log_fhandle);
|
||||
fflush(log_fhandle);
|
||||
}
|
||||
#ifdef ANDROID
|
||||
vcos_mutex_unlock(&printf_lock);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void _vcos_log_platform_init(void)
|
||||
{
|
||||
if(vcos_log_to_file)
|
||||
{
|
||||
char log_fname[100];
|
||||
#ifdef ANDROID
|
||||
snprintf(log_fname, 100, "/data/log/vcos_log%u.txt", vcos_process_id_current());
|
||||
#else
|
||||
snprintf(log_fname, 100, "/var/log/vcos_log%u.txt", vcos_process_id_current());
|
||||
#endif
|
||||
log_fhandle = fopen(log_fname, "w");
|
||||
}
|
||||
else
|
||||
log_fhandle = stderr;
|
||||
}
|
||||
|
||||
/* Flags for init/deinit components */
|
||||
enum
|
||||
{
|
||||
VCOS_INIT_NAMED_SEM = (1 << 0),
|
||||
VCOS_INIT_PRINTF_LOCK = (1 << 1),
|
||||
VCOS_INIT_MAIN_SEM = (1 << 2),
|
||||
VCOS_INIT_MSGQ = (1 << 3),
|
||||
VCOS_INIT_ALL = 0xffffffff
|
||||
};
|
||||
|
||||
static void vcos_term(uint32_t flags)
|
||||
{
|
||||
if (flags & VCOS_INIT_MSGQ)
|
||||
vcos_msgq_deinit();
|
||||
|
||||
if (flags & VCOS_INIT_MAIN_SEM)
|
||||
vcos_semaphore_delete(&vcos_thread_main.suspend);
|
||||
|
||||
#ifdef ANDROID
|
||||
if (flags & VCOS_INIT_PRINTF_LOCK)
|
||||
vcos_mutex_delete(&printf_lock);
|
||||
#endif
|
||||
|
||||
if (flags & VCOS_INIT_NAMED_SEM)
|
||||
_vcos_named_semaphore_deinit();
|
||||
}
|
||||
|
||||
VCOS_STATUS_T vcos_platform_init(void)
|
||||
{
|
||||
VCOS_STATUS_T st;
|
||||
uint32_t flags = 0;
|
||||
int pst;
|
||||
|
||||
st = _vcos_named_semaphore_init();
|
||||
if (!vcos_verify(st == VCOS_SUCCESS))
|
||||
goto end;
|
||||
|
||||
flags |= VCOS_INIT_NAMED_SEM;
|
||||
|
||||
#ifdef HAVE_MTRACE
|
||||
/* enable glibc memory debugging, if the environment
|
||||
* variable MALLOC_TRACE names a valid file.
|
||||
*/
|
||||
mtrace();
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID
|
||||
st = vcos_mutex_create(&printf_lock, "printf");
|
||||
if (!vcos_verify(st == VCOS_SUCCESS))
|
||||
goto end;
|
||||
|
||||
flags |= VCOS_INIT_PRINTF_LOCK;
|
||||
#endif
|
||||
|
||||
st = vcos_once(¤t_thread_key_once, current_thread_key_init);
|
||||
if (!vcos_verify(st == VCOS_SUCCESS))
|
||||
goto end;
|
||||
|
||||
/* Initialise a VCOS wrapper for the thread which called vcos_init. */
|
||||
st = vcos_semaphore_create(&vcos_thread_main.suspend, NULL, 0);
|
||||
if (!vcos_verify(st == VCOS_SUCCESS))
|
||||
goto end;
|
||||
|
||||
flags |= VCOS_INIT_MAIN_SEM;
|
||||
|
||||
vcos_thread_main.thread = pthread_self();
|
||||
|
||||
pst = pthread_setspecific(_vcos_thread_current_key, &vcos_thread_main);
|
||||
if (!vcos_verify(pst == 0))
|
||||
{
|
||||
st = VCOS_EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
st = vcos_msgq_init();
|
||||
if (!vcos_verify(st == VCOS_SUCCESS))
|
||||
goto end;
|
||||
|
||||
flags |= VCOS_INIT_MSGQ;
|
||||
|
||||
vcos_logging_init();
|
||||
|
||||
end:
|
||||
if (st != VCOS_SUCCESS)
|
||||
vcos_term(flags);
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
void vcos_platform_deinit(void)
|
||||
{
|
||||
vcos_term(VCOS_INIT_ALL);
|
||||
}
|
||||
|
||||
void vcos_global_lock(void)
|
||||
{
|
||||
pthread_mutex_lock(&lock);
|
||||
}
|
||||
|
||||
void vcos_global_unlock(void)
|
||||
{
|
||||
pthread_mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
void vcos_thread_exit(void *arg)
|
||||
{
|
||||
VCOS_THREAD_T *thread = vcos_thread_current();
|
||||
|
||||
if ( thread && thread->dummy )
|
||||
{
|
||||
vcos_free ( (void*) thread );
|
||||
thread = NULL;
|
||||
}
|
||||
|
||||
pthread_exit(arg);
|
||||
}
|
||||
|
||||
|
||||
void vcos_thread_attr_init(VCOS_THREAD_ATTR_T *attrs)
|
||||
{
|
||||
*attrs = default_attrs;
|
||||
}
|
||||
|
||||
VCOS_STATUS_T vcos_pthreads_map_error(int error)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
case ENOMEM:
|
||||
return VCOS_ENOMEM;
|
||||
case ENXIO:
|
||||
return VCOS_ENXIO;
|
||||
case EAGAIN:
|
||||
return VCOS_EAGAIN;
|
||||
case ENOSPC:
|
||||
return VCOS_ENOSPC;
|
||||
default:
|
||||
return VCOS_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
VCOS_STATUS_T vcos_pthreads_map_errno(void)
|
||||
{
|
||||
return vcos_pthreads_map_error(errno);
|
||||
}
|
||||
|
||||
void _vcos_task_timer_set(void (*pfn)(void*), void *cxt, VCOS_UNSIGNED ms)
|
||||
{
|
||||
VCOS_THREAD_T *thread = vcos_thread_current();
|
||||
|
||||
if (thread == NULL)
|
||||
return;
|
||||
|
||||
vcos_assert(thread->orig_task_timer_expiration_routine == NULL);
|
||||
|
||||
if (!thread->task_timer_created)
|
||||
{
|
||||
VCOS_STATUS_T st = vcos_timer_create(&thread->task_timer, NULL,
|
||||
_task_timer_expiration_routine, thread);
|
||||
(void)st;
|
||||
vcos_assert(st == VCOS_SUCCESS);
|
||||
thread->task_timer_created = 1;
|
||||
}
|
||||
|
||||
thread->orig_task_timer_expiration_routine = pfn;
|
||||
thread->orig_task_timer_context = cxt;
|
||||
|
||||
vcos_timer_set(&thread->task_timer, ms);
|
||||
}
|
||||
|
||||
void _vcos_task_timer_cancel(void)
|
||||
{
|
||||
VCOS_THREAD_T *thread = vcos_thread_current();
|
||||
|
||||
if (thread == NULL || !thread->task_timer_created)
|
||||
return;
|
||||
|
||||
vcos_timer_cancel(&thread->task_timer);
|
||||
thread->orig_task_timer_expiration_routine = NULL;
|
||||
}
|
||||
|
||||
int vcos_vsnprintf( char *buf, size_t buflen, const char *fmt, va_list ap )
|
||||
{
|
||||
return vsnprintf( buf, buflen, fmt, ap );
|
||||
}
|
||||
|
||||
int vcos_snprintf(char *buf, size_t buflen, const char *fmt, ...)
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
va_start(ap,fmt);
|
||||
ret = vsnprintf(buf, buflen, fmt, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vcos_have_rtos(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char * vcos_thread_get_name(const VCOS_THREAD_T *thread)
|
||||
{
|
||||
return thread->name;
|
||||
}
|
||||
|
||||
#ifdef VCOS_HAVE_BACKTRACK
|
||||
void __attribute__((weak)) vcos_backtrace_self(void);
|
||||
#endif
|
||||
|
||||
void vcos_pthreads_logging_assert(const char *file, const char *func, unsigned int line, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
fprintf(stderr, "assertion failure:%s:%d:%s():",
|
||||
file, line, func);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
#ifdef VCOS_HAVE_BACKTRACK
|
||||
if (vcos_backtrace_self)
|
||||
vcos_backtrace_self();
|
||||
#endif
|
||||
abort();
|
||||
}
|
||||
|
||||
extern VCOS_STATUS_T vcos_thread_at_exit(void (*pfn)(void*), void *cxt)
|
||||
{
|
||||
int i;
|
||||
VCOS_THREAD_T *self = vcos_thread_current();
|
||||
if (!self)
|
||||
{
|
||||
vcos_assert(0);
|
||||
return VCOS_EINVAL;
|
||||
}
|
||||
for (i=0; i<VCOS_MAX_EXIT_HANDLERS; i++)
|
||||
{
|
||||
if (self->at_exit[i].pfn == NULL)
|
||||
{
|
||||
self->at_exit[i].pfn = pfn;
|
||||
self->at_exit[i].cxt = cxt;
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
}
|
||||
return VCOS_ENOSPC;
|
||||
}
|
||||
|
||||
void vcos_set_args(int argc, const char **argv)
|
||||
{
|
||||
vcos_argc = argc;
|
||||
vcos_argv = argv;
|
||||
}
|
||||
|
||||
int vcos_get_argc(void)
|
||||
{
|
||||
return vcos_argc;
|
||||
}
|
||||
|
||||
const char ** vcos_get_argv(void)
|
||||
{
|
||||
return vcos_argv;
|
||||
}
|
||||
|
||||
/* we can't inline this, because HZ comes from sys/param.h which
|
||||
* dumps all sorts of junk into the global namespace, notable MIN and
|
||||
* MAX.
|
||||
*/
|
||||
uint32_t _vcos_get_ticks_per_second(void)
|
||||
{
|
||||
return HZ;
|
||||
}
|
||||
|
||||
VCOS_STATUS_T vcos_once(VCOS_ONCE_T *once_control,
|
||||
void (*init_routine)(void))
|
||||
{
|
||||
int rc = pthread_once(once_control, init_routine);
|
||||
if (rc != 0)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
case EINVAL:
|
||||
return VCOS_EINVAL;
|
||||
default:
|
||||
vcos_assert(0);
|
||||
return VCOS_EACCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VCOS_THREAD_T *vcos_dummy_thread_create(void)
|
||||
{
|
||||
VCOS_STATUS_T st;
|
||||
VCOS_THREAD_T *thread_hndl = NULL;
|
||||
int rc;
|
||||
|
||||
thread_hndl = (VCOS_THREAD_T *)vcos_malloc(sizeof(VCOS_THREAD_T), NULL);
|
||||
vcos_assert(thread_hndl != NULL);
|
||||
|
||||
memset(thread_hndl, 0, sizeof(VCOS_THREAD_T));
|
||||
|
||||
thread_hndl->dummy = 1;
|
||||
thread_hndl->thread = pthread_self();
|
||||
|
||||
st = vcos_semaphore_create(&thread_hndl->suspend, NULL, 0);
|
||||
if (st != VCOS_SUCCESS)
|
||||
{
|
||||
vcos_free(thread_hndl);
|
||||
return( thread_hndl );
|
||||
}
|
||||
|
||||
vcos_once(¤t_thread_key_once, current_thread_key_init);
|
||||
|
||||
rc = pthread_setspecific(_vcos_thread_current_key,
|
||||
thread_hndl);
|
||||
(void)rc;
|
||||
|
||||
return( thread_hndl );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************
|
||||
*
|
||||
* Timers
|
||||
*
|
||||
***********************************************************/
|
||||
|
||||
/* On Linux we could use POSIX timers with a bit of synchronization.
|
||||
* Unfortunately POSIX timers on Bionic are NOT POSIX compliant
|
||||
* what makes that option not viable.
|
||||
* That's why we ended up with our own implementation of timers.
|
||||
* NOTE: That condition variables on Bionic are also buggy and
|
||||
* they work incorrectly with CLOCK_MONOTONIC, so we have to
|
||||
* use CLOCK_REALTIME (and hope that no one will change the time
|
||||
* significantly after the timer has been set up
|
||||
*/
|
||||
#define NSEC_IN_SEC (1000*1000*1000)
|
||||
#define MSEC_IN_SEC (1000)
|
||||
#define NSEC_IN_MSEC (1000*1000)
|
||||
|
||||
static int _timespec_is_zero(struct timespec *ts)
|
||||
{
|
||||
return ((ts->tv_sec == 0) && (ts->tv_nsec == 0));
|
||||
}
|
||||
|
||||
static void _timespec_set_zero(struct timespec *ts)
|
||||
{
|
||||
ts->tv_sec = ts->tv_nsec = 0;
|
||||
}
|
||||
|
||||
/* Adds left to right and stores the result in left */
|
||||
static void _timespec_add(struct timespec *left, struct timespec *right)
|
||||
{
|
||||
left->tv_sec += right->tv_sec;
|
||||
left->tv_nsec += right->tv_nsec;
|
||||
if (left->tv_nsec >= (NSEC_IN_SEC))
|
||||
{
|
||||
left->tv_nsec -= NSEC_IN_SEC;
|
||||
left->tv_sec++;
|
||||
}
|
||||
}
|
||||
|
||||
static int _timespec_is_larger(struct timespec *left, struct timespec *right)
|
||||
{
|
||||
if (left->tv_sec != right->tv_sec)
|
||||
return left->tv_sec > right->tv_sec;
|
||||
else
|
||||
return left->tv_nsec > right->tv_nsec;
|
||||
}
|
||||
|
||||
static void* _timer_thread(void *arg)
|
||||
{
|
||||
VCOS_TIMER_T *timer = (VCOS_TIMER_T*)arg;
|
||||
|
||||
pthread_mutex_lock(&timer->lock);
|
||||
while (!timer->quit)
|
||||
{
|
||||
struct timespec now;
|
||||
|
||||
/* Wait until next expiry time, or until timer's settings are changed */
|
||||
if (_timespec_is_zero(&timer->expires))
|
||||
pthread_cond_wait(&timer->settings_changed, &timer->lock);
|
||||
else
|
||||
pthread_cond_timedwait(&timer->settings_changed, &timer->lock, &timer->expires);
|
||||
|
||||
/* See if the timer has expired - reloop if it didn't */
|
||||
clock_gettime(CLOCK_REALTIME, &now);
|
||||
if (_timespec_is_zero(&timer->expires) || _timespec_is_larger(&timer->expires, &now))
|
||||
continue;
|
||||
|
||||
/* The timer has expired. Clear the expiry time and call the
|
||||
* expiration routine
|
||||
*/
|
||||
_timespec_set_zero(&timer->expires);
|
||||
timer->orig_expiration_routine(timer->orig_context);
|
||||
}
|
||||
pthread_mutex_unlock(&timer->lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VCOS_STATUS_T vcos_timer_init(void)
|
||||
{
|
||||
return VCOS_SUCCESS;
|
||||
}
|
||||
|
||||
VCOS_STATUS_T vcos_timer_create(VCOS_TIMER_T *timer,
|
||||
const char *name,
|
||||
void (*expiration_routine)(void *context),
|
||||
void *context)
|
||||
{
|
||||
pthread_mutexattr_t lock_attr;
|
||||
VCOS_STATUS_T result = VCOS_SUCCESS;
|
||||
int settings_changed_initialized = 0;
|
||||
int lock_attr_initialized = 0;
|
||||
int lock_initialized = 0;
|
||||
|
||||
(void)name;
|
||||
|
||||
vcos_assert(timer);
|
||||
vcos_assert(expiration_routine);
|
||||
|
||||
memset(timer, 0, sizeof(VCOS_TIMER_T));
|
||||
|
||||
timer->orig_expiration_routine = expiration_routine;
|
||||
timer->orig_context = context;
|
||||
|
||||
/* Create conditional variable for notifying the timer's thread
|
||||
* when settings change.
|
||||
*/
|
||||
if (result == VCOS_SUCCESS)
|
||||
{
|
||||
int rc = pthread_cond_init(&timer->settings_changed, NULL);
|
||||
if (rc == 0)
|
||||
settings_changed_initialized = 1;
|
||||
else
|
||||
result = vcos_pthreads_map_error(rc);
|
||||
}
|
||||
|
||||
/* Create attributes for the lock (we want it to be recursive) */
|
||||
if (result == VCOS_SUCCESS)
|
||||
{
|
||||
int rc = pthread_mutexattr_init(&lock_attr);
|
||||
if (rc == 0)
|
||||
{
|
||||
pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
lock_attr_initialized = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = vcos_pthreads_map_error(rc);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create lock for the timer structure */
|
||||
if (result == VCOS_SUCCESS)
|
||||
{
|
||||
int rc = pthread_mutex_init(&timer->lock, &lock_attr);
|
||||
if (rc == 0)
|
||||
lock_initialized = 1;
|
||||
else
|
||||
result = vcos_pthreads_map_error(rc);
|
||||
}
|
||||
|
||||
/* Lock attributes are no longer needed */
|
||||
if (lock_attr_initialized)
|
||||
pthread_mutexattr_destroy(&lock_attr);
|
||||
|
||||
/* Create the underlying thread */
|
||||
if (result == VCOS_SUCCESS)
|
||||
{
|
||||
int rc = pthread_create(&timer->thread, NULL, _timer_thread, timer);
|
||||
if (rc != 0)
|
||||
result = vcos_pthreads_map_error(rc);
|
||||
}
|
||||
|
||||
/* Clean up if anything went wrong */
|
||||
if (result != VCOS_SUCCESS)
|
||||
{
|
||||
if (lock_initialized)
|
||||
pthread_mutex_destroy(&timer->lock);
|
||||
|
||||
if (settings_changed_initialized)
|
||||
pthread_cond_destroy(&timer->settings_changed);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void vcos_timer_set(VCOS_TIMER_T *timer, VCOS_UNSIGNED delay_ms)
|
||||
{
|
||||
struct timespec now;
|
||||
|
||||
vcos_assert(timer);
|
||||
|
||||
/* Other implementations of this function do undefined things
|
||||
* when delay_ms is 0. This implementation will simply assert and return
|
||||
*/
|
||||
vcos_assert(delay_ms != 0);
|
||||
if (delay_ms == 0)
|
||||
return;
|
||||
|
||||
pthread_mutex_lock(&timer->lock);
|
||||
|
||||
/* Calculate the new absolute expiry time */
|
||||
clock_gettime(CLOCK_REALTIME, &now);
|
||||
timer->expires.tv_sec = delay_ms / MSEC_IN_SEC;
|
||||
timer->expires.tv_nsec = (delay_ms % MSEC_IN_SEC) * NSEC_IN_MSEC;
|
||||
_timespec_add(&timer->expires, &now);
|
||||
|
||||
/* Notify the timer's thread about the change */
|
||||
pthread_cond_signal(&timer->settings_changed);
|
||||
|
||||
pthread_mutex_unlock(&timer->lock);
|
||||
}
|
||||
|
||||
void vcos_timer_cancel(VCOS_TIMER_T *timer)
|
||||
{
|
||||
vcos_assert(timer);
|
||||
|
||||
pthread_mutex_lock(&timer->lock);
|
||||
|
||||
_timespec_set_zero(&timer->expires);
|
||||
pthread_cond_signal(&timer->settings_changed);
|
||||
|
||||
pthread_mutex_unlock(&timer->lock);
|
||||
}
|
||||
|
||||
void vcos_timer_reset(VCOS_TIMER_T *timer, VCOS_UNSIGNED delay_ms)
|
||||
{
|
||||
vcos_timer_set(timer, delay_ms);
|
||||
}
|
||||
|
||||
void vcos_timer_delete(VCOS_TIMER_T *timer)
|
||||
{
|
||||
vcos_assert(timer);
|
||||
|
||||
pthread_mutex_lock(&timer->lock);
|
||||
|
||||
/* Other implementation of this function (e.g. ThreadX)
|
||||
* disallow it being called from the expiration routine
|
||||
*/
|
||||
vcos_assert(pthread_self() != timer->thread);
|
||||
|
||||
/* Stop the timer and set flag telling the timer thread to quit */
|
||||
_timespec_set_zero(&timer->expires);
|
||||
timer->quit = 1;
|
||||
|
||||
/* Notify the timer's thread about the change */
|
||||
pthread_cond_signal(&timer->settings_changed);
|
||||
|
||||
/* Release the lock, so that the timer's thread can quit */
|
||||
pthread_mutex_unlock(&timer->lock);
|
||||
|
||||
/* Wait for the timer thread to finish */
|
||||
pthread_join(timer->thread, NULL);
|
||||
|
||||
/* Free resources used by the timer */
|
||||
pthread_mutex_destroy(&timer->lock);
|
||||
pthread_cond_destroy(&timer->settings_changed);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef USER_NODEFS_H
|
||||
#define USER_NODEFS_H
|
||||
|
||||
/*
|
||||
* This tells coverity not to expand the assert macro, so it still sees the
|
||||
* asserts in the code, even in release builds (we currently run coverity on
|
||||
* our release builds). Unfortunately MetaWare won't compile it, even though
|
||||
* __COVERITY__ isn't defined, so we put this in its own header.
|
||||
*
|
||||
* FIXME: This belongs in the Coverity config (in a file called
|
||||
* config/user_nodefs.h)
|
||||
*/
|
||||
#nodef assert
|
||||
|
||||
/*
|
||||
* So we need to declare the function now that it isn't a macro any more. It's
|
||||
* already built into coverity that assert is a "killpath".
|
||||
*/
|
||||
extern void assert(int cond);
|
||||
|
||||
#endif /* USER_NODEFS_H */
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - public header file
|
||||
=============================================================================*/
|
||||
|
||||
/**
|
||||
* \mainpage OS Abstraction Layer
|
||||
*
|
||||
* \section intro Introduction
|
||||
*
|
||||
* This abstraction layer is here to allow the underlying OS to be easily changed (e.g. from
|
||||
* Nucleus to ThreadX) and to aid in porting host applications to new targets.
|
||||
*
|
||||
* \subsection error Error handling
|
||||
*
|
||||
* Wherever possible, VCOS functions assert internally and return void. The only exceptions
|
||||
* are creation functions (which might fail due to lack of resources) and functions that
|
||||
* might timeout or fail due to lack of space. Errors that might be reported by the underlying
|
||||
* OS API (e.g. invalid mutex) are treated as a programming error, and are merely asserted on.
|
||||
*
|
||||
* \section thread_synch Threads and synchronisation
|
||||
*
|
||||
* \subsection thread Threads
|
||||
*
|
||||
* The thread API is somewhat different to that found in Nucleus. In particular, threads
|
||||
* cannot just be destroyed at arbitrary times and nor can they merely exit. This is so
|
||||
* that the same API can be implemented across all interesting platforms without too much
|
||||
* difficulty. See vcos_thread.h for details. Thread attributes are configured via
|
||||
* the VCOS_THREAD_ATTR_T structure, found in vcos_thread_attr.h.
|
||||
*
|
||||
* \subsection sema Semaphores
|
||||
*
|
||||
* Counted semaphores (c.f. Nucleus NU_SEMAPHORE) are created with VCOS_SEMAPHORE_T.
|
||||
* Under ThreadX on VideoCore, semaphores are implemented using VideoCore spinlocks, and
|
||||
* so are quite a lot faster than ordinary ThreadX semaphores. See vcos_semaphore.h.
|
||||
*
|
||||
* \subsection mtx Mutexes
|
||||
*
|
||||
* Mutexes are used for locking. Attempts to take a mutex twice, or to unlock it
|
||||
* in a different thread to the one in which it was locked should be expected to fail.
|
||||
* Mutexes are not re-entrant (see vcos_reentrant_mutex.h for a slightly slower
|
||||
* re-entrant mutex).
|
||||
*
|
||||
* \subsection evflags Event flags
|
||||
*
|
||||
* Event flags (the ThreadX name - also known as event groups under Nucleus) provide
|
||||
* 32 flags which can be waited on by multiple clients, and signalled by multiple clients.
|
||||
* A timeout can be specified. See vcos_event_flags.h. An alternative to this is the
|
||||
* VCOS_EVENT_T (see vcos_event.h) which is akin to the Win32 auto-reset event, or a
|
||||
* saturating counted semaphore.
|
||||
*
|
||||
* \subsection event Events
|
||||
*
|
||||
* A VCOS_EVENT_T is a bit like a saturating semaphore. No matter how many times it
|
||||
* is signalled, the waiter will only wake up once. See vcos_event.h. You might think this
|
||||
* is useful if you suspect that the cost of reading the semaphore count (perhaps via a
|
||||
* system call) is expensive on your platform.
|
||||
*
|
||||
* \subsection tls Thread local storage
|
||||
*
|
||||
* Thread local storage is supported using vcos_tls.h. This is emulated on Nucleus
|
||||
* and ThreadX.
|
||||
*
|
||||
* \section int Interrupts
|
||||
*
|
||||
* The legacy LISR/HISR scheme found in Nucleus is supported via the legacy ISR API,
|
||||
* which is also supported on ThreadX. New code should avoid this, and old code should
|
||||
* be migrated away from it, since it is slow. See vcos_legacy_isr.h.
|
||||
*
|
||||
* Registering an interrupt handler, and disabling/restoring interrupts, is handled
|
||||
* using the functions in vcos_isr.h.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file vcos.h
|
||||
*
|
||||
* This is the top level header file. Clients include this. It pulls in the platform-specific
|
||||
* header file (vcos_platform.h) together with header files defining the expected APIs, such
|
||||
* as vcos_mutex.h, vcos_semaphore.h, etc. It is also possible to include these header files
|
||||
* directly.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef VCOS_H
|
||||
#define VCOS_H
|
||||
|
||||
#include "vcos_assert.h"
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
#ifndef VCOS_INIT_H
|
||||
#include "vcos_init.h"
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_SEMAPHORE_H
|
||||
#include "vcos_semaphore.h"
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_THREAD_H
|
||||
#include "vcos_thread.h"
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_MUTEX_H
|
||||
#include "vcos_mutex.h"
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_MEM_H
|
||||
#include "vcos_mem.h"
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_LOGGING_H
|
||||
#include "vcos_logging.h"
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_STRING_H
|
||||
#include "vcos_string.h"
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_EVENT_H
|
||||
#include "vcos_event.h"
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_THREAD_ATTR_H
|
||||
#include "vcos_thread_attr.h"
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_TLS_H
|
||||
#include "vcos_tls.h"
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_REENTRANT_MUTEX_H
|
||||
#include "vcos_reentrant_mutex.h"
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_NAMED_SEMAPHORE_H
|
||||
#include "vcos_named_semaphore.h"
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_QUICKSLOW_MUTEX_H
|
||||
#include "vcos_quickslow_mutex.h"
|
||||
#endif
|
||||
|
||||
/* Headers with predicates */
|
||||
|
||||
#if VCOS_HAVE_EVENT_FLAGS
|
||||
#include "vcos_event_flags.h"
|
||||
#endif
|
||||
|
||||
#if VCOS_HAVE_QUEUE
|
||||
#include "vcos_queue.h"
|
||||
#endif
|
||||
|
||||
#if VCOS_HAVE_LEGACY_ISR
|
||||
#include "vcos_legacy_isr.h"
|
||||
#endif
|
||||
|
||||
#if VCOS_HAVE_TIMER
|
||||
#include "vcos_timer.h"
|
||||
#endif
|
||||
|
||||
#if VCOS_HAVE_MEMPOOL
|
||||
#include "vcos_mempool.h"
|
||||
#endif
|
||||
|
||||
#if VCOS_HAVE_ISR
|
||||
#include "vcos_isr.h"
|
||||
#endif
|
||||
|
||||
#if VCOS_HAVE_ATOMIC_FLAGS
|
||||
#include "vcos_atomic_flags.h"
|
||||
#endif
|
||||
|
||||
#if VCOS_HAVE_ONCE
|
||||
#include "vcos_once.h"
|
||||
#endif
|
||||
|
||||
#if VCOS_HAVE_BLOCK_POOL
|
||||
#include "vcos_blockpool.h"
|
||||
#endif
|
||||
|
||||
#if VCOS_HAVE_FILE
|
||||
#include "vcos_file.h"
|
||||
#endif
|
||||
|
||||
#if VCOS_HAVE_CFG
|
||||
#include "vcos_cfg.h"
|
||||
#endif
|
||||
|
||||
#if VCOS_HAVE_CMD
|
||||
#include "vcos_cmd.h"
|
||||
#endif
|
||||
|
||||
#endif /* VCOS_H */
|
||||
|
||||
@@ -0,0 +1,324 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - Assertion and error-handling macros.
|
||||
=============================================================================*/
|
||||
|
||||
|
||||
#ifndef VCOS_ASSERT_H
|
||||
#define VCOS_ASSERT_H
|
||||
|
||||
/*
|
||||
* Macro:
|
||||
* vcos_assert(cond)
|
||||
* vcos_assert_msg(cond, fmt, ...)
|
||||
* Use:
|
||||
* Detecting programming errors by ensuring that assumptions are correct.
|
||||
* On failure:
|
||||
* Performs a platform-dependent "breakpoint", usually with an assert-style
|
||||
* message. The '_msg' variant expects a printf-style format string and
|
||||
* parameters.
|
||||
* If a failure is detected, the code should be fixed and rebuilt.
|
||||
* In release builds:
|
||||
* Generates no code, i.e. does not evaluate 'cond'.
|
||||
* Returns:
|
||||
* Nothing.
|
||||
*
|
||||
* Macro:
|
||||
* vcos_demand(cond)
|
||||
* vcos_demand_msg(cond, fmt, ...)
|
||||
* Use:
|
||||
* Detecting fatal system errors that require a reboot.
|
||||
* On failure:
|
||||
* Performs a platform-dependent "breakpoint", usually with an assert-style
|
||||
* message, then calls vcos_abort (see below).
|
||||
* In release builds:
|
||||
* Calls vcos_abort() if 'cond' is false.
|
||||
* Returns:
|
||||
* Nothing (never, on failure).
|
||||
*
|
||||
* Macro:
|
||||
* vcos_verify(cond)
|
||||
* vcos_verify_msg(cond, fmt, ...)
|
||||
* Use:
|
||||
* Detecting run-time errors and interesting conditions, normally within an
|
||||
* 'if' statement to catch the failures, i.e.
|
||||
* if (!vcos_verify(cond)) handle_error();
|
||||
* On failure:
|
||||
* Generates a message and optionally stops at a platform-dependent
|
||||
* "breakpoint" (usually disabled). See vcos_verify_bkpts_enable below.
|
||||
* In release builds:
|
||||
* Just evaluates and returns 'cond'.
|
||||
* Returns:
|
||||
* Non-zero if 'cond' is true, otherwise zero.
|
||||
*
|
||||
* Macro:
|
||||
* vcos_static_assert(cond)
|
||||
* Use:
|
||||
* Detecting compile-time errors.
|
||||
* On failure:
|
||||
* Generates a compiler error.
|
||||
* In release builds:
|
||||
* Generates a compiler error.
|
||||
*
|
||||
* Function:
|
||||
* void vcos_abort(void)
|
||||
* Use:
|
||||
* Invokes the fatal error handling mechanism, alerting the host where
|
||||
* applicable.
|
||||
* Returns:
|
||||
* Never.
|
||||
*
|
||||
* Macro:
|
||||
* VCOS_VERIFY_BKPTS
|
||||
* Use:
|
||||
* Define in a module (before including vcos.h) to specify an alternative
|
||||
* flag to control breakpoints on vcos_verify() failures.
|
||||
* Returns:
|
||||
* Non-zero values enable breakpoints.
|
||||
*
|
||||
* Function:
|
||||
* int vcos_verify_bkpts_enable(int enable);
|
||||
* Use:
|
||||
* Sets the global flag controlling breakpoints on vcos_verify failures,
|
||||
* enabling the breakpoints iff 'enable' is non-zero.
|
||||
* Returns:
|
||||
* The previous state of the flag.
|
||||
*
|
||||
* Function:
|
||||
* int vcos_verify_bkpts_enabled(void);
|
||||
* Use:
|
||||
* Queries the state of the global flag enabling breakpoints on vcos_verify
|
||||
* failures.
|
||||
* Returns:
|
||||
* The current state of the flag.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* int my_breakpoint_enable_flag = 1;
|
||||
*
|
||||
* #define VCOS_VERIFY_BKPTS my_breakpoint_enable_flag
|
||||
*
|
||||
* #include "vcos.h"
|
||||
*
|
||||
* vcos_static_assert((sizeof(object) % 32) == 0);
|
||||
*
|
||||
* // ...
|
||||
*
|
||||
* vcos_assert_msg(postcondition_is_true, "Coding error");
|
||||
*
|
||||
* if (!vcos_verify_msg(buf, "Buffer allocation failed (%d bytes)", size))
|
||||
* {
|
||||
* // Tidy up
|
||||
* // ...
|
||||
* return OUT_OF_MEMORY;
|
||||
* }
|
||||
*
|
||||
* vcos_demand(*p++==GUARDWORDHEAP);
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
|
||||
#ifdef __COVERITY__
|
||||
#include "user_nodefs.h"
|
||||
|
||||
extern void __coverity_panic__(void);
|
||||
#undef VCOS_ASSERT_BKPT
|
||||
#define VCOS_ASSERT_BKPT __coverity_panic__()
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ANDROID should NOT be defined for files built for Videocore, but currently it
|
||||
* is. FIXME When that's fixed, remove the __VIDEOCORE__ band-aid.
|
||||
*/
|
||||
#if (defined(ANDROID) && !defined(__VIDEOCORE__))
|
||||
# include "assert.h"
|
||||
# define vcos_assert assert
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_VERIFY_BKPTS
|
||||
#define VCOS_VERIFY_BKPTS vcos_verify_bkpts_enabled()
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_BKPT
|
||||
#if defined(__VIDEOCORE__) && !defined(VCOS_ASSERT_NO_BKPTS)
|
||||
#define VCOS_BKPT _bkpt()
|
||||
#else
|
||||
#define VCOS_BKPT (void )0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_ASSERT_BKPT
|
||||
#define VCOS_ASSERT_BKPT VCOS_BKPT
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_VERIFY_BKPT
|
||||
#define VCOS_VERIFY_BKPT (VCOS_VERIFY_BKPTS ? VCOS_BKPT : (void)0)
|
||||
#endif
|
||||
|
||||
VCOSPRE_ int VCOSPOST_ vcos_verify_bkpts_enabled(void);
|
||||
VCOSPRE_ int VCOSPOST_ vcos_verify_bkpts_enable(int enable);
|
||||
VCOSPRE_ void VCOSPOST_ vcos_abort(void);
|
||||
|
||||
#ifndef VCOS_ASSERT_MSG
|
||||
#ifdef LOGGING
|
||||
extern void logging_assert(const char *file, const char *func, int line, const char *format, ...);
|
||||
extern void logging_assert_dump(void);
|
||||
#define VCOS_ASSERT_MSG(...) ((VCOS_ASSERT_LOGGING && !VCOS_ASSERT_LOGGING_DISABLE) ? logging_assert_dump(), logging_assert(__FILE__, __func__, __LINE__, __VA_ARGS__) : (void)0)
|
||||
#else
|
||||
#define VCOS_ASSERT_MSG(...) ((void)0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_VERIFY_MSG
|
||||
#define VCOS_VERIFY_MSG(...) VCOS_ASSERT_MSG(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_ASSERT_LOGGING
|
||||
#define VCOS_ASSERT_LOGGING 0
|
||||
#endif
|
||||
|
||||
#ifndef VCOS_ASSERT_LOGGING_DISABLE
|
||||
#define VCOS_ASSERT_LOGGING_DISABLE 0
|
||||
#endif
|
||||
|
||||
#if !defined(NDEBUG) || defined(VCOS_RELEASE_ASSERTS)
|
||||
#define VCOS_ASSERT_ENABLED 1
|
||||
#define VCOS_VERIFY_ENABLED 1
|
||||
#else
|
||||
#define VCOS_ASSERT_ENABLED 0
|
||||
#define VCOS_VERIFY_ENABLED 0
|
||||
#endif
|
||||
|
||||
#define VCOS_DEMAND_ENABLED 1
|
||||
|
||||
#if VCOS_ASSERT_ENABLED
|
||||
|
||||
#ifndef vcos_assert
|
||||
#define vcos_assert(cond) \
|
||||
( (cond) ? (void)0 : (VCOS_ASSERT_MSG("%s", #cond), VCOS_ASSERT_BKPT) )
|
||||
#endif
|
||||
|
||||
#ifndef vcos_assert_msg
|
||||
#define vcos_assert_msg(cond, ...) \
|
||||
( (cond) ? (void)0 : (VCOS_ASSERT_MSG(__VA_ARGS__), VCOS_ASSERT_BKPT) )
|
||||
#endif
|
||||
|
||||
#else /* VCOS_ASSERT_ENABLED */
|
||||
|
||||
#ifndef vcos_assert
|
||||
#define vcos_assert(cond) (void)0
|
||||
#endif
|
||||
|
||||
#ifndef vcos_assert_msg
|
||||
#define vcos_assert_msg(cond, ...) (void)0
|
||||
#endif
|
||||
|
||||
#endif /* VCOS_ASSERT_ENABLED */
|
||||
|
||||
|
||||
#if VCOS_DEMAND_ENABLED
|
||||
|
||||
#ifndef vcos_demand
|
||||
#define vcos_demand(cond) \
|
||||
( (cond) ? (void)0 : (VCOS_ASSERT_MSG("%s", #cond), VCOS_ASSERT_BKPT, vcos_abort()) )
|
||||
#endif
|
||||
|
||||
#ifndef vcos_demand_msg
|
||||
#define vcos_demand_msg(cond, ...) \
|
||||
( (cond) ? (void)0 : (VCOS_ASSERT_MSG(__VA_ARGS__), VCOS_ASSERT_BKPT, vcos_abort()) )
|
||||
#endif
|
||||
|
||||
#else /* VCOS_DEMAND_ENABLED */
|
||||
|
||||
#ifndef vcos_demand
|
||||
#define vcos_demand(cond) \
|
||||
( (cond) ? (void)0 : vcos_abort() )
|
||||
#endif
|
||||
|
||||
#ifndef vcos_demand_msg
|
||||
#define vcos_demand_msg(cond, ...) \
|
||||
( (cond) ? (void)0 : vcos_abort() )
|
||||
#endif
|
||||
|
||||
#endif /* VCOS_DEMAND_ENABLED */
|
||||
|
||||
|
||||
#if VCOS_VERIFY_ENABLED
|
||||
|
||||
#ifndef vcos_verify
|
||||
#define vcos_verify(cond) \
|
||||
( (cond) ? 1 : (VCOS_VERIFY_MSG("%s", #cond), VCOS_VERIFY_BKPT, 0) )
|
||||
#endif
|
||||
|
||||
#ifndef vcos_verify_msg
|
||||
#define vcos_verify_msg(cond, ...) \
|
||||
( (cond) ? 1 : (VCOS_VERIFY_MSG(__VA_ARGS__), VCOS_VERIFY_BKPT, 0) )
|
||||
#endif
|
||||
|
||||
#else /* VCOS_VERIFY_ENABLED */
|
||||
|
||||
#ifndef vcos_verify
|
||||
#define vcos_verify(cond) (cond)
|
||||
#endif
|
||||
|
||||
#ifndef vcos_verify_msg
|
||||
#define vcos_verify_msg(cond, ...) (cond)
|
||||
#endif
|
||||
|
||||
#endif /* VCOS_VERIFY_ENABLED */
|
||||
|
||||
|
||||
#ifndef vcos_static_assert
|
||||
#if defined(__GNUC__)
|
||||
#define vcos_static_assert(cond) __attribute__((unused)) extern int vcos_static_assert[(cond)?1:-1]
|
||||
#else
|
||||
#define vcos_static_assert(cond) extern int vcos_static_assert[(cond)?1:-1]
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef vc_assert
|
||||
#define vc_assert(cond) vcos_assert(cond)
|
||||
#endif
|
||||
|
||||
#define vcos_unreachable() vcos_assert(0)
|
||||
#define vcos_not_impl() vcos_assert(0)
|
||||
|
||||
/** Print out a backtrace, on supported platforms.
|
||||
*/
|
||||
extern void vcos_backtrace_self(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* VCOS_ASSERT_H */
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - public header file
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_ATOMIC_FLAGS_H
|
||||
#define VCOS_ATOMIC_FLAGS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
/**
|
||||
* \file vcos_atomic_flags.h
|
||||
*
|
||||
* Defines atomic flags API.
|
||||
*
|
||||
* 32 flags. Atomic "or" and "get and clear" operations
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create an atomic flags instance.
|
||||
*
|
||||
* @param atomic_flags Pointer to atomic flags instance, filled in on return
|
||||
*
|
||||
* @return VCOS_SUCCESS if succeeded.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_atomic_flags_create(VCOS_ATOMIC_FLAGS_T *atomic_flags);
|
||||
|
||||
/**
|
||||
* Atomically set the specified flags.
|
||||
*
|
||||
* @param atomic_flags Instance to set flags on
|
||||
* @param flags Mask of flags to set
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_atomic_flags_or(VCOS_ATOMIC_FLAGS_T *atomic_flags, uint32_t flags);
|
||||
|
||||
/**
|
||||
* Retrieve the current flags and then clear them. The entire operation is
|
||||
* atomic.
|
||||
*
|
||||
* @param atomic_flags Instance to get/clear flags from/on
|
||||
*
|
||||
* @return Mask of flags which were set (and we cleared)
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
uint32_t vcos_atomic_flags_get_and_clear(VCOS_ATOMIC_FLAGS_T *atomic_flags);
|
||||
|
||||
/**
|
||||
* Delete an atomic flags instance.
|
||||
*
|
||||
* @param atomic_flags Instance to delete
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_atomic_flags_delete(VCOS_ATOMIC_FLAGS_T *atomic_flags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - compiler-specific attributes
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_ATTR_H
|
||||
#define VCOS_ATTR_H
|
||||
|
||||
/**
|
||||
* Type attribute indicating the enum should be stored in as few bytes as
|
||||
* possible. MetaWare does this by default, so the attribute is useful when
|
||||
* structs need to be portable to GCC too.
|
||||
*
|
||||
* MSVC doesn't support VCOS_ENUM_PACKED, so code that needs to be portable
|
||||
* across all platforms but wants the type-safety and debug-info benefits
|
||||
* of enum types when possible, should do:
|
||||
*
|
||||
* typedef enum VCOS_ENUM_PACKED { a = 0, b = 0xffff } EXAMPLE_T;
|
||||
* struct foo {
|
||||
* int bar;
|
||||
* #if VCOS_HAS_ENUM_PACKED
|
||||
* EXAMPLE_T baz;
|
||||
* #else
|
||||
* uint16_t baz;
|
||||
* #endif
|
||||
* };
|
||||
*/
|
||||
|
||||
#if defined(__VECTORC__)
|
||||
# define VCOS_ENUM_PACKED
|
||||
# define VCOS_HAS_ENUM_PACKED 0
|
||||
#elif defined(__GNUC__)
|
||||
# define VCOS_ENUM_PACKED __attribute__ ((packed))
|
||||
# define VCOS_HAS_ENUM_PACKED 1
|
||||
#elif defined(__HIGHC__)
|
||||
# define VCOS_ENUM_PACKED /* packed enums are default on Metaware */
|
||||
# define VCOS_HAS_ENUM_PACKED 1
|
||||
#else
|
||||
# define VCOS_ENUM_PACKED
|
||||
# define VCOS_HAS_ENUM_PACKED 0
|
||||
#endif
|
||||
|
||||
/** Variable attribute indicating the variable must be emitted even if it appears unused. */
|
||||
#if defined(__GNUC__) || defined(__HIGHC__)
|
||||
# define VCOS_ATTR_USED __attribute__ ((used))
|
||||
#else
|
||||
# define VCOS_ATTR_USED
|
||||
#endif
|
||||
|
||||
/** Variable attribute indicating the compiler should not warn if the variable is unused. */
|
||||
#if defined(__GNUC__) || defined(__HIGHC__)
|
||||
# define VCOS_ATTR_POSSIBLY_UNUSED __attribute__ ((unused))
|
||||
#else
|
||||
# define VCOS_ATTR_POSSIBLY_UNUSED
|
||||
#endif
|
||||
|
||||
/** Variable attribute requiring specific alignment.
|
||||
*
|
||||
* Use as:
|
||||
* int VCOS_ATTR_ALIGNED(256) n;
|
||||
* or:
|
||||
* VCOS_ATTR_ALIGNED(256) int n;
|
||||
* or if you don't want to support MSVC:
|
||||
* int n VCOS_ATTR_ALIGNED(256);
|
||||
*/
|
||||
#if defined(__GNUC__) || defined(__HIGHC__)
|
||||
# define VCOS_ATTR_ALIGNED(n) __attribute__ ((aligned(n)))
|
||||
#elif defined(_MSC_VER)
|
||||
# define VCOS_ATTR_ALIGNED(n) __declspec(align(n))
|
||||
#else
|
||||
/* Force a syntax error if this is used when the compiler doesn't support it,
|
||||
* instead of silently misaligning */
|
||||
# define VCOS_ATTR_ALIGNED(n) VCOS_ATTR_ALIGNED_NOT_SUPPORTED_ON_THIS_COMPILER
|
||||
#endif
|
||||
|
||||
/** Variable attribute requiring specific ELF section.
|
||||
*
|
||||
* Use as:
|
||||
* int n VCOS_ATTR_SECTION(".foo") = 1;
|
||||
*
|
||||
* A pointer like &n will have type "VCOS_ATTR_SECTION_QUALIFIER int *".
|
||||
*/
|
||||
#if defined(__HIGHC__) || defined(__VECTORC__)
|
||||
/* hcvc requires 'far' else it'll put small objects in .sdata/.rsdata/.sbss */
|
||||
# define VCOS_ATTR_SECTION(s) __attribute__ ((far, section(s)))
|
||||
# define VCOS_ATTR_SECTION_QUALIFIER _Far
|
||||
#elif defined(__GNUC__)
|
||||
# define VCOS_ATTR_SECTION(s) __attribute__ ((section(s)))
|
||||
# define VCOS_ATTR_SECTION_QUALIFIER
|
||||
#else
|
||||
/* Force a syntax error if this is used when the compiler doesn't support it */
|
||||
# define VCOS_ATTR_SECTION(s) VCOS_ATTR_SECTION_NOT_SUPPORTED_ON_THIS_COMPILER
|
||||
# define VCOS_ATTR_SECTION_QUALIFIER
|
||||
#endif
|
||||
|
||||
/** Define a function as a weak alias to another function.
|
||||
* @param ret_type Function return type.
|
||||
* @param alias_name Name of the alias.
|
||||
* @param param_list Function parameter list, including the parentheses.
|
||||
* @param target_name Target function (bare function name, not a string).
|
||||
*/
|
||||
#if defined(__GNUC__) || defined(__HIGHC__)
|
||||
/* N.B. gcc allows __attribute__ after parameter list, but hcvc seems to silently ignore it. */
|
||||
# define VCOS_WEAK_ALIAS(ret_type, alias_name, param_list, target_name) \
|
||||
__attribute__ ((weak, alias(#target_name))) ret_type alias_name param_list
|
||||
#else
|
||||
# define VCOS_WEAK_ALIAS(ret_type, alias, params, target) VCOS_CASSERT(0)
|
||||
#endif
|
||||
|
||||
/** Define a function as a weak alias to another function, specified as a string.
|
||||
* @param ret_type Function return type.
|
||||
* @param alias_name Name of the alias.
|
||||
* @param param_list Function parameter list, including the parentheses.
|
||||
* @param target_name Target function name as a string.
|
||||
* @note Prefer the use of VCOS_WEAK_ALIAS - it is likely to be more portable.
|
||||
* Only use VCOS_WEAK_ALIAS_STR if you need to do pre-processor mangling of the target
|
||||
* symbol.
|
||||
*/
|
||||
#if defined(__GNUC__) || defined(__HIGHC__)
|
||||
/* N.B. gcc allows __attribute__ after parameter list, but hcvc seems to silently ignore it. */
|
||||
# define VCOS_WEAK_ALIAS_STR(ret_type, alias_name, param_list, target_name) \
|
||||
__attribute__ ((weak, alias(target_name))) ret_type alias_name param_list
|
||||
#else
|
||||
# define VCOS_WEAK_ALIAS_STR(ret_type, alias, params, target) VCOS_CASSERT(0)
|
||||
#endif
|
||||
|
||||
#endif /* VCOS_ATTR_H */
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - fixed size allocator support
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_BLOCKPOOL_H
|
||||
#define VCOS_BLOCKPOOL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Thread safe, fixed size allocator API.
|
||||
*
|
||||
*/
|
||||
|
||||
/** Initialises a block pool to use already allocated (e.g. statically)
|
||||
* allocated memory.
|
||||
*
|
||||
* Different implementations will incur different overheads. Use
|
||||
* VCOS_BLOCKPOOL_SIZE(num_blocks, block_size) to calculate the number
|
||||
* of bytes required including overheads for the desired pools.
|
||||
*
|
||||
* @param pool Pointer to pool object
|
||||
* @param num_blocks The number of blocks required.
|
||||
* @param block_size The size of an individual block.
|
||||
* @param start The address of the start of the pool.
|
||||
* @param pool_size The size of the pool in bytes.
|
||||
* @param align Alignment for block data. Use VCOS_BLOCKPOOL_ALIGN_DEFAULT
|
||||
* for default word alignment.
|
||||
* @param flags Reserved for future use.
|
||||
* @param name Name of the pool. Used for diagnostics.
|
||||
*
|
||||
* @return VCOS_SUCCESS if the pool was created.
|
||||
*/
|
||||
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_blockpool_init(VCOS_BLOCKPOOL_T *pool,
|
||||
VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size,
|
||||
void *start, VCOS_UNSIGNED pool_size, VCOS_UNSIGNED align,
|
||||
VCOS_UNSIGNED flags, const char *name);
|
||||
|
||||
/** Creates a pool of blocks of a given size within a buffer allocated on
|
||||
* the heap.
|
||||
*
|
||||
* The heap memory is freed when the block pool is destroyed by
|
||||
* calling vcos_blockpool_delete.
|
||||
*
|
||||
* @param pool Pointer to pool object
|
||||
* @param num_blocks The number of blocks required.
|
||||
* @param block_size The size of an individual block.
|
||||
* @param align Alignment for block data. Use VCOS_BLOCKPOOL_ALIGN_DEFAULT
|
||||
* for default word alignment.
|
||||
* @param flags Reserved for future use.
|
||||
* @param name Name of the pool. Used for diagnostics.
|
||||
*
|
||||
* @return VCOS_SUCCESS if the pool was created.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_blockpool_create_on_heap(VCOS_BLOCKPOOL_T *pool,
|
||||
VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size,
|
||||
VCOS_UNSIGNED align, VCOS_UNSIGNED flags,
|
||||
const char *name);
|
||||
|
||||
/** Allocate a block from the pool
|
||||
*
|
||||
* @param pool Pointer to the pool to allocate from.
|
||||
* @return a pointer to the newly allocated block or NULL if no blocks were
|
||||
* available.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void *vcos_blockpool_alloc(VCOS_BLOCKPOOL_T *pool);
|
||||
|
||||
/** Allocate a block from the pool and zero it.
|
||||
*
|
||||
* @param pool Pointer to the pool to allocate from.
|
||||
* @return a pointer to the newly allocated block or NULL if no blocks were
|
||||
* available.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void *vcos_blockpool_calloc(VCOS_BLOCKPOOL_T *pool);
|
||||
|
||||
/** Returns a block to the pool.
|
||||
*
|
||||
* @param block The block to free.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_blockpool_free(void *block);
|
||||
|
||||
/** Queries the number of available blocks in the pool.
|
||||
* @param pool The pool to query.
|
||||
*/
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_UNSIGNED vcos_blockpool_available_count(VCOS_BLOCKPOOL_T *pool);
|
||||
|
||||
/** Queries the number of used blocks in the pool.
|
||||
* @param pool The pool to query.
|
||||
*/
|
||||
VCOS_INLINE_IMPL
|
||||
VCOS_UNSIGNED vcos_blockpool_used_count(VCOS_BLOCKPOOL_T *pool);
|
||||
|
||||
/** Deinitialize a memory pool.
|
||||
*
|
||||
* @param pool The pool to de-initialize.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_blockpool_delete(VCOS_BLOCKPOOL_T *pool);
|
||||
|
||||
/** Return an integer handle for a given allocated block. */
|
||||
VCOS_INLINE_DECL
|
||||
uint32_t vcos_blockpool_elem_to_handle(void *block);
|
||||
|
||||
/** Convert an integer handle back into a pointer.
|
||||
* Returns NULL if invalid. */
|
||||
VCOS_INLINE_DECL
|
||||
void *vcos_blockpool_elem_from_handle(VCOS_BLOCKPOOL_T *pool, uint32_t handle);
|
||||
|
||||
/** Checks whether a pointer is an allocated block within the specified pool.
|
||||
* Returns true if the block is valid, otherwise, false is returned. */
|
||||
VCOS_INLINE_DECL
|
||||
uint32_t vcos_blockpool_is_valid_elem(
|
||||
VCOS_BLOCKPOOL_T *pool, const void *block);
|
||||
|
||||
/** May be called once to allow the block pool to be extended by dynamically
|
||||
* adding subpools. The block size cannot be altered.
|
||||
*
|
||||
* @param num_extensions The number of extensions that may be created.
|
||||
* The maximum is (VCOS_BLOCKPOOL_MAX_SUBPOOLS - 1)
|
||||
* @param num_blocks The number of blocks to allocate in each in each
|
||||
* dynamically allocated subpool.
|
||||
* @return VCOS_SUCCESS if successful.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_blockpool_extend(VCOS_BLOCKPOOL_T *pool,
|
||||
VCOS_UNSIGNED num_extensions, VCOS_UNSIGNED num_blocks);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
const char *vcos_get_build_hostname( void );
|
||||
const char *vcos_get_build_version( void );
|
||||
const char *vcos_get_build_time( void );
|
||||
const char *vcos_get_build_date( void );
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined( VCOS_CFG_H )
|
||||
#define VCOS_CFG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
typedef struct opaque_vcos_cfg_buf_t *VCOS_CFG_BUF_T;
|
||||
typedef struct opaque_vcos_cfg_entry_t *VCOS_CFG_ENTRY_T;
|
||||
|
||||
/** \file vcos_file.h
|
||||
*
|
||||
* API for accessing configuration/statistics information. This
|
||||
* is loosely modelled on the linux proc entries.
|
||||
*/
|
||||
|
||||
typedef void (*VCOS_CFG_SHOW_FPTR)( VCOS_CFG_BUF_T buf, void *data );
|
||||
typedef void (*VCOS_CFG_PARSE_FPTR)( VCOS_CFG_BUF_T buf, void *data );
|
||||
|
||||
/** Create a configuration directory.
|
||||
*
|
||||
* @param entry Place to store the created config entry.
|
||||
* @param parent Parent entry (for directory like config
|
||||
* options).
|
||||
* @param entryName Name of the directory.
|
||||
*/
|
||||
|
||||
VCOS_STATUS_T vcos_cfg_mkdir( VCOS_CFG_ENTRY_T *entry,
|
||||
VCOS_CFG_ENTRY_T *parent,
|
||||
const char *dirName );
|
||||
|
||||
/** Create a configuration entry.
|
||||
*
|
||||
* @param entry Place to store the created config entry.
|
||||
* @param parent Parent entry (for directory like config
|
||||
* options).
|
||||
* @param entryName Name of the configuration entry.
|
||||
* @param showFunc Function pointer to show configuration
|
||||
* data.
|
||||
* @param parseFunc Function pointer to parse new data.
|
||||
*/
|
||||
|
||||
VCOS_STATUS_T vcos_cfg_create_entry( VCOS_CFG_ENTRY_T *entry,
|
||||
VCOS_CFG_ENTRY_T *parent,
|
||||
const char *entryName,
|
||||
VCOS_CFG_SHOW_FPTR showFunc,
|
||||
VCOS_CFG_PARSE_FPTR parseFunc,
|
||||
void *data );
|
||||
|
||||
/** Determines if a configuration entry has been created or not.
|
||||
*
|
||||
* @param entry Configuration entry to query.
|
||||
*/
|
||||
|
||||
int vcos_cfg_is_entry_created( VCOS_CFG_ENTRY_T entry );
|
||||
|
||||
/** Returns the name of a configuration entry.
|
||||
*
|
||||
* @param entry Configuration entry to query.
|
||||
*/
|
||||
|
||||
const char *vcos_cfg_get_entry_name( VCOS_CFG_ENTRY_T entry );
|
||||
|
||||
/** Removes a configuration entry.
|
||||
*
|
||||
* @param entry Configuration entry to remove.
|
||||
*/
|
||||
|
||||
VCOS_STATUS_T vcos_cfg_remove_entry( VCOS_CFG_ENTRY_T *entry );
|
||||
|
||||
|
||||
/** Writes data into a configuration buffer. Only valid inside
|
||||
* the show function.
|
||||
*
|
||||
* @param buf Buffer to write data into.
|
||||
* @param fmt printf style format string.
|
||||
*/
|
||||
|
||||
void vcos_cfg_buf_printf( VCOS_CFG_BUF_T buf, const char *fmt, ... );
|
||||
|
||||
/** Retrieves a null terminated string of the data associated
|
||||
* with the buffer. Only valid inside the parse function.
|
||||
*
|
||||
* @param buf Buffer to get data from.
|
||||
* @param fmt printf style format string.
|
||||
*/
|
||||
|
||||
char *vcos_cfg_buf_get_str( VCOS_CFG_BUF_T buf );
|
||||
|
||||
void *vcos_cfg_get_proc_entry( VCOS_CFG_ENTRY_T entry );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined( VCOS_CMD_H )
|
||||
#define VCOS_CMD_H
|
||||
|
||||
/* ---- Include Files ----------------------------------------------------- */
|
||||
|
||||
#ifndef VCOS_H
|
||||
#include "vcos.h"
|
||||
#endif
|
||||
#include "vcos_stdint.h"
|
||||
|
||||
|
||||
/* ---- Constants and Types ---------------------------------------------- */
|
||||
|
||||
struct VCOS_CMD_S;
|
||||
typedef struct VCOS_CMD_S VCOS_CMD_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int argc; /* Number of arguments (includes the command/sub-command) */
|
||||
char **argv; /* Array of arguments */
|
||||
char **argv_orig; /* Original array of arguments */
|
||||
|
||||
VCOS_CMD_T *cmd_entry;
|
||||
VCOS_CMD_T *cmd_parent_entry;
|
||||
|
||||
int use_log; /* Output being logged? */
|
||||
size_t result_size; /* Size of result buffer. */
|
||||
char *result_ptr; /* Next place to put output. */
|
||||
char *result_buf; /* Start of the buffer. */
|
||||
|
||||
} VCOS_CMD_PARAM_T;
|
||||
|
||||
typedef VCOS_STATUS_T (*VCOS_CMD_FUNC_T)( VCOS_CMD_PARAM_T *param );
|
||||
|
||||
struct VCOS_CMD_S
|
||||
{
|
||||
const char *name;
|
||||
const char *args;
|
||||
VCOS_CMD_FUNC_T cmd_fn;
|
||||
VCOS_CMD_T *sub_cmd_entry;
|
||||
const char *descr;
|
||||
|
||||
};
|
||||
|
||||
/* ---- Variable Externs ------------------------------------------------- */
|
||||
|
||||
/* ---- Function Prototypes ---------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Common printing routine for generating command output.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_cmd_error( VCOS_CMD_PARAM_T *param, const char *fmt, ... ) VCOS_FORMAT_ATTR_(printf, 2, 3);
|
||||
VCOSPRE_ void VCOSPOST_ vcos_cmd_printf( VCOS_CMD_PARAM_T *param, const char *fmt, ... ) VCOS_FORMAT_ATTR_(printf, 2, 3);
|
||||
VCOSPRE_ void VCOSPOST_ vcos_cmd_vprintf( VCOS_CMD_PARAM_T *param, const char *fmt, va_list args ) VCOS_FORMAT_ATTR_(printf, 2, 0);
|
||||
|
||||
/*
|
||||
* Cause vcos_cmd_error, printf and vprintf to always log to the provided
|
||||
* category. When this call is made, the results buffer passed into
|
||||
* vcos_cmd_execute is used as a line buffer and does not need to be
|
||||
* output by the caller.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_cmd_always_log_output( VCOS_LOG_CAT_T *log_category );
|
||||
|
||||
/*
|
||||
* Prints command usage for the current command.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_cmd_usage( VCOS_CMD_PARAM_T *param );
|
||||
|
||||
/*
|
||||
* Register commands to be processed
|
||||
*/
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_cmd_register( VCOS_CMD_T *cmd_entry );
|
||||
|
||||
/*
|
||||
* Registers multiple commands to be processed. The array should
|
||||
* be terminated by an entry with all zeros.
|
||||
*/
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_cmd_register_multiple( VCOS_CMD_T *cmd_entry );
|
||||
|
||||
/*
|
||||
* Executes a command based on a command line.
|
||||
*/
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_cmd_execute( int argc, char **argv, size_t result_size, char *result_buf );
|
||||
|
||||
/*
|
||||
* Shut down the command system and free all allocated data.
|
||||
* Do not call any other command functions after this.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_cmd_shutdown( void );
|
||||
|
||||
#endif /* VCOS_CMD_H */
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - public header file
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_CTYPE_H
|
||||
#define VCOS_CTYPE_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* ctype functions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/ctype.h>
|
||||
#else
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VCOS - abstraction over dynamic library opening
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_DLFCN_H
|
||||
#define VCOS_DLFCN_H
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Loading dynamic libraries. See also dlfcn.h.
|
||||
*/
|
||||
|
||||
/** Open a dynamic library.
|
||||
*
|
||||
* @param name name of the library
|
||||
* @param mode Load lazily or immediately (VCOS_DL_LAZY, VCOS_DL_NOW, VCOS_DL_LOCAL, VCOS_DL_GLOBAL).
|
||||
*
|
||||
* @return A handle for use in subsequent calls.
|
||||
*/
|
||||
VCOSPRE_ void * VCOSPOST_ vcos_dlopen(const char *name, int mode);
|
||||
|
||||
/** Look up a symbol.
|
||||
*
|
||||
* @param handle Handle to open
|
||||
* @param name Name of function
|
||||
*
|
||||
* @return Function pointer, or NULL.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ (*vcos_dlsym(void *handle, const char *name))(void);
|
||||
|
||||
/** Close a library
|
||||
*
|
||||
* @param handle Handle to close
|
||||
*/
|
||||
VCOSPRE_ int VCOSPOST_ vcos_dlclose (void *handle);
|
||||
|
||||
/** Return error message from library.
|
||||
*
|
||||
* @param err On return, set to non-zero if an error has occurred
|
||||
* @param buf Buffer to write error to
|
||||
* @param len Size of buffer (including terminating NUL).
|
||||
*/
|
||||
VCOSPRE_ int VCOSPOST_ vcos_dlerror(int *err, char *buf, size_t buflen);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - public header file for events
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_EVENT_H
|
||||
#define VCOS_EVENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* An event is akin to the Win32 auto-reset event.
|
||||
*
|
||||
*
|
||||
* Signalling an event will wake up one waiting thread only. Once one
|
||||
* thread has been woken the event atomically returns to the unsignalled
|
||||
* state.
|
||||
*
|
||||
* If no threads are waiting on the event when it is signalled it remains
|
||||
* signalled.
|
||||
*
|
||||
* This is almost, but not quite, completely unlike the "event flags"
|
||||
* object based on Nucleus event groups and ThreadX event flags.
|
||||
*
|
||||
* In particular, it should be similar in speed to a semaphore, unlike
|
||||
* the event flags.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create an event instance.
|
||||
*
|
||||
* @param event Filled in with constructed event.
|
||||
* @param name Name of the event (for debugging)
|
||||
*
|
||||
* @return VCOS_SUCCESS on success, or error code.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_event_create(VCOS_EVENT_T *event, const char *name);
|
||||
|
||||
#ifndef vcos_event_signal
|
||||
|
||||
/**
|
||||
* Signal the event. The event will return to being unsignalled
|
||||
* after exactly one waiting thread has been woken up. If no
|
||||
* threads are waiting it remains signalled.
|
||||
*
|
||||
* @param event The event to signal
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_event_signal(VCOS_EVENT_T *event);
|
||||
|
||||
/**
|
||||
* Wait for the event.
|
||||
*
|
||||
* @param event The event to wait for
|
||||
* @return VCOS_SUCCESS on success, VCOS_EAGAIN if the wait was interrupted.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_event_wait(VCOS_EVENT_T *event);
|
||||
|
||||
/**
|
||||
* Try event, but don't block.
|
||||
*
|
||||
* @param event The event to try
|
||||
* @return VCOS_SUCCESS on success, VCOS_EAGAIN if the event is not currently signalled
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_event_try(VCOS_EVENT_T *event);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Destroy an event.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_event_delete(VCOS_EVENT_T *event);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - public header file
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_EVENT_FLAGS_H
|
||||
#define VCOS_EVENT_FLAGS_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
#define VCOS_EVENT_FLAGS_SUSPEND VCOS_SUSPEND
|
||||
#define VCOS_EVENT_FLAGS_NO_SUSPEND VCOS_NO_SUSPEND
|
||||
typedef VCOS_OPTION VCOS_EVENTGROUP_OPERATION_T;
|
||||
|
||||
/**
|
||||
* \file vcos_event_flags.h
|
||||
*
|
||||
* Defines event flags API.
|
||||
*
|
||||
* Similar to Nucleus event groups.
|
||||
*
|
||||
* These have the same semantics as Nucleus event groups and ThreadX event
|
||||
* flags. As such, they are quite complex internally; if speed is important
|
||||
* they might not be your best choice.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create an event flags instance.
|
||||
*
|
||||
* @param flags Pointer to event flags instance, filled in on return.
|
||||
* @param name Name for the event flags, used for debug.
|
||||
*
|
||||
* @return VCOS_SUCCESS if succeeded.
|
||||
*/
|
||||
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_event_flags_create(VCOS_EVENT_FLAGS_T *flags, const char *name);
|
||||
|
||||
/**
|
||||
* Set some events.
|
||||
*
|
||||
* @param flags Instance to set flags on
|
||||
* @param events Bitmask of the flags to actually set
|
||||
* @param op How the flags should be set. VCOS_OR will OR in the flags; VCOS_AND
|
||||
* will AND them in, possibly clearing existing flags.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_event_flags_set(VCOS_EVENT_FLAGS_T *flags,
|
||||
VCOS_UNSIGNED events,
|
||||
VCOS_OPTION op);
|
||||
|
||||
/**
|
||||
* Retrieve some events.
|
||||
*
|
||||
* Waits until the specified events have been set.
|
||||
*
|
||||
* @param flags Instance to wait on
|
||||
* @param requested_events The bitmask to wait for
|
||||
* @param op VCOS_OR - get any; VCOS_AND - get all.
|
||||
* @param ms_suspend How long to wait, in milliseconds
|
||||
* @param retrieved_events the events actually retrieved.
|
||||
*
|
||||
* @return VCOS_SUCCESS if events were retrieved. VCOS_EAGAIN if the
|
||||
* timeout expired.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_event_flags_get(VCOS_EVENT_FLAGS_T *flags,
|
||||
VCOS_UNSIGNED requested_events,
|
||||
VCOS_OPTION op,
|
||||
VCOS_UNSIGNED ms_suspend,
|
||||
VCOS_UNSIGNED *retrieved_events);
|
||||
|
||||
|
||||
/**
|
||||
* Delete an event flags instance.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_event_flags_delete(VCOS_EVENT_FLAGS_T *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - initialization routines
|
||||
=============================================================================*/
|
||||
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Some OS support libraries need some initialization. To support this, call
|
||||
* vcos_init() function at the start of day; vcos_deinit() at the end.
|
||||
*/
|
||||
|
||||
/**
|
||||
* vcos initialization. Call this function before using other vcos functions.
|
||||
* Calls can be nested within the same process; they are reference counted so
|
||||
* that only a call from uninitialized state has any effect.
|
||||
* @note On platforms/toolchains that support it, gcc's constructor attribute or
|
||||
* similar is used to invoke this function before main() or equivalent.
|
||||
* @return Status of initialisation.
|
||||
*/
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_init(void);
|
||||
|
||||
/**
|
||||
* vcos deinitialization. Call this function when vcos is no longer required,
|
||||
* in order to free resources.
|
||||
* Calls can be nested within the same process; they are reference counted so
|
||||
* that only a call that decrements the reference count to 0 has any effect.
|
||||
* @note On platforms/toolchains that support it, gcc's destructor attribute or
|
||||
* similar is used to invoke this function after exit() or equivalent.
|
||||
* @return Status of initialisation.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_deinit(void);
|
||||
|
||||
/**
|
||||
* Acquire global lock. This must be available independent of vcos_init()/vcos_deinit().
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_global_lock(void);
|
||||
|
||||
/**
|
||||
* Release global lock. This must be available independent of vcos_init()/vcos_deinit().
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_global_unlock(void);
|
||||
|
||||
/** Pass in the argv/argc arguments passed to main() */
|
||||
VCOSPRE_ void VCOSPOST_ vcos_set_args(int argc, const char **argv);
|
||||
|
||||
/** Return argc. */
|
||||
VCOSPRE_ int VCOSPOST_ vcos_get_argc(void);
|
||||
|
||||
/** Return argv. */
|
||||
VCOSPRE_ const char ** VCOSPOST_ vcos_get_argv(void);
|
||||
|
||||
/**
|
||||
* Platform-specific initialisation.
|
||||
* VCOS internal function, not part of public API, do not call from outside
|
||||
* vcos. vcos_init()/vcos_deinit() reference count calls, so this function is
|
||||
* only called from an uninitialized state, i.e. there will not be two
|
||||
* consecutive calls to vcos_platform_init() without an intervening call to
|
||||
* vcos_platform_deinit().
|
||||
* This function is called with vcos_global_lock held.
|
||||
* @return Status of initialisation.
|
||||
*/
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_platform_init(void);
|
||||
|
||||
/**
|
||||
* Platform-specific de-initialisation.
|
||||
* VCOS internal function, not part of public API, do not call from outside
|
||||
* vcos.
|
||||
* See vcos_platform_init() re reference counting.
|
||||
* This function is called with vcos_global_lock held.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_platform_deinit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef VCOS_INTTYPES_H
|
||||
#define VCOS_INTTYPES_H
|
||||
|
||||
/** \file
|
||||
* Attempt to provide the support for fixed width integer types as per
|
||||
* inttypes.h. This simply includes inttypes.h, which should find the
|
||||
* system/toolchain version if present, otherwise falling back to the version
|
||||
* in <platform>. The vcos versions initially only provide the
|
||||
* most common printf() macros.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* VCOS_INTTYPES_H */
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - IRQ support
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_ISR_H
|
||||
#define VCOS_ISR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
/**
|
||||
* \file vcos_isr.h
|
||||
*
|
||||
* \section isr ISR support
|
||||
*
|
||||
* API for dispatching interrupts.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* Register an interrupt handler. The old handler (if any) is returned in
|
||||
* old_handler. The old handler should be called if the interrupt was not
|
||||
* for you.
|
||||
*
|
||||
* The handler function will be called in a context with interrupts disabled,
|
||||
* so should be written to be as short as possible. If significant processing
|
||||
* is needed, the handler should delegate to a thread.
|
||||
*
|
||||
* The handler function can call any OS primitive that does not block (e.g.
|
||||
* post a semaphore or set an event flag). Blocking operations (including memory
|
||||
* allocation from the system heap) are not permitted.
|
||||
*
|
||||
* To deregister an ISR, pass in NULL.
|
||||
*
|
||||
* @param vec Vector to register for
|
||||
* @param handler Handler to be called
|
||||
* @param old_handler Updated with the old handler, or NULL.
|
||||
*/
|
||||
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_register_isr(VCOS_UNSIGNED vec,
|
||||
VCOS_ISR_HANDLER_T handler,
|
||||
VCOS_ISR_HANDLER_T *old_handler);
|
||||
|
||||
/** Disable interrupts, returning the old value (enabled/disabled) to the caller.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_UNSIGNED vcos_int_disable(void);
|
||||
|
||||
/** Restore the previous interrupt enable/disable state.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_int_restore(VCOS_UNSIGNED previous);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - legacy (Nucleus) IRQ support
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_LEGACY_ISR_H
|
||||
#define VCOS_LEGACY_ISR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
/** \file vcos_legacy_isr.h
|
||||
*
|
||||
* API for dispatching interrupts the Nucleus way, via a LISR and HISR.
|
||||
* New code should use the single-dispatch scheme - the LISR/HISR
|
||||
* distinction is not necessary.
|
||||
*
|
||||
* Under ThreadX, a HISR is implemented as a high-priority thread which
|
||||
* waits on a counting semaphore to call the HISR function. Although this
|
||||
* provides a good approximation to the Nucleus semantics, it is potentially
|
||||
* slow if all you are trying to do is to wake a thread from LISR context.
|
||||
*/
|
||||
|
||||
/** Register a LISR. This is identical to the NU_Register_LISR API.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_register_legacy_lisr(VCOS_UNSIGNED vecnum,
|
||||
void (*lisr)(VCOS_INT),
|
||||
void (**old_lisr)(VCOS_INT));
|
||||
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_legacy_hisr_create(VCOS_HISR_T *hisr, const char *name,
|
||||
void (*entry)(void),
|
||||
VCOS_UNSIGNED pri,
|
||||
void *stack, VCOS_UNSIGNED stack_size);
|
||||
|
||||
/** Activate a HISR. On an OS which has no distinction between a HISR and LISR,
|
||||
* this may use some kind of emulation, which could well be less efficient than
|
||||
* a normal ISR.`
|
||||
*
|
||||
* @param hisr HISR to activate.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_legacy_hisr_activate(VCOS_HISR_T *hisr);
|
||||
|
||||
/** Delete a HISR.
|
||||
*
|
||||
* @param hisr HISR to delete.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_legacy_hisr_delete(VCOS_HISR_T *hisr);
|
||||
|
||||
/** Are we in a legacy LISR?
|
||||
*
|
||||
* @return On Nucleus, non-zero if in a LISR. On other platforms, non-zero if
|
||||
* in an interrupt.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
int vcos_in_legacy_lisr(void);
|
||||
|
||||
/** Is the current thread actually a fake HISR thread? Only implemented
|
||||
* on platforms that fake up HISRs.
|
||||
*/
|
||||
|
||||
#ifndef VCOS_LISRS_NEED_HISRS
|
||||
VCOSPRE_ int VCOSPOST_ vcos_current_thread_is_fake_hisr_thread(VCOS_HISR_T *);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - logging support
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_LOGGING_H
|
||||
#define VCOS_LOGGING_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
#include "vcos_logging_control.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Logging support
|
||||
*
|
||||
* This provides categorised logging. Clients register
|
||||
* a category, and then get a number of logging levels for
|
||||
* that category.
|
||||
*
|
||||
* The logging level flag is tested using a flag *before* the
|
||||
* function call, which makes logging very fast when disabled - there
|
||||
* is no function call overhead just to find out that this log
|
||||
* message is disabled.
|
||||
*
|
||||
* \section VCOS_LOG_CATEGORY
|
||||
*
|
||||
* As a convenience, clients define VCOS_LOG_CATEGORY to point to
|
||||
* their category; the various vcos_log_xxx() macros then expand to
|
||||
* use this.
|
||||
*
|
||||
* e.g.
|
||||
*
|
||||
* #define VCOS_LOG_CATEGORY (&my_category)
|
||||
*
|
||||
* #include <vcos.h>
|
||||
*
|
||||
* VCOS_LOG_CAT_T my_category;
|
||||
*
|
||||
* ....
|
||||
*
|
||||
* vcos_log_trace("Stuff happened: %d", n_stuff);
|
||||
*
|
||||
*/
|
||||
|
||||
/** Logging levels */
|
||||
typedef enum VCOS_LOG_LEVEL_T
|
||||
{
|
||||
VCOS_LOG_UNINITIALIZED = 0,
|
||||
VCOS_LOG_NEVER,
|
||||
VCOS_LOG_ERROR,
|
||||
VCOS_LOG_WARN,
|
||||
VCOS_LOG_INFO,
|
||||
VCOS_LOG_TRACE,
|
||||
} VCOS_LOG_LEVEL_T;
|
||||
|
||||
|
||||
/** Initialize a logging category without going through vcos_log_register().
|
||||
*
|
||||
* This is useful for the case where there is no obvious point to do the
|
||||
* registration (no initialization function for the module). However, it
|
||||
* means that your logging category is not registered, so cannot be easily
|
||||
* changed at run-time.
|
||||
*/
|
||||
#define VCOS_LOG_INIT(n,l) { l, n, 0, {0}, 0, 0 }
|
||||
|
||||
/** A registered logging category.
|
||||
*/
|
||||
typedef struct VCOS_LOG_CAT_T
|
||||
{
|
||||
VCOS_LOG_LEVEL_T level; /**< Which levels are enabled for this category */
|
||||
const char *name; /**< Name for this category. */
|
||||
struct VCOS_LOG_CAT_T *next;
|
||||
struct {
|
||||
unsigned int want_prefix:1;
|
||||
} flags;
|
||||
unsigned int refcount;
|
||||
void *platform_data; /**< platform specific data */
|
||||
} VCOS_LOG_CAT_T;
|
||||
|
||||
typedef void (*VCOS_VLOG_IMPL_FUNC_T)(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args);
|
||||
|
||||
/** Convert a VCOS_LOG_LEVEL_T into a printable string.
|
||||
* The platform needs to implement this function.
|
||||
*/
|
||||
VCOSPRE_ const char * VCOSPOST_ vcos_log_level_to_string( VCOS_LOG_LEVEL_T level );
|
||||
|
||||
/** Convert a string into a VCOS_LOG_LEVEL_T
|
||||
* The platform needs to implement this function.
|
||||
*/
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_string_to_log_level( const char *str, VCOS_LOG_LEVEL_T *level );
|
||||
|
||||
/** Log a message. Basic API. Normal code should not use this.
|
||||
* The platform needs to implement this function.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_log_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, ...) VCOS_FORMAT_ATTR_(printf, 3, 4);
|
||||
|
||||
/** Log a message using a varargs parameter list. Normal code should
|
||||
* not use this.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_vlog_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args) VCOS_FORMAT_ATTR_(printf, 3, 0);
|
||||
|
||||
/** Set the function which does the actual logging output.
|
||||
* Passing in NULL causes the default logging function to be
|
||||
* used.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_set_vlog_impl( VCOS_VLOG_IMPL_FUNC_T vlog_impl_func );
|
||||
|
||||
/** The default logging function, which is provided by each
|
||||
* platform.
|
||||
*/
|
||||
|
||||
VCOSPRE_ void VCOSPOST_ vcos_vlog_default_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args) VCOS_FORMAT_ATTR_(printf, 3, 0);
|
||||
|
||||
/*
|
||||
* Initialise the logging subsystem. This is called from
|
||||
* vcos_init() so you don't normally need to call it.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_logging_init(void);
|
||||
|
||||
/** Register a logging category.
|
||||
*
|
||||
* @param name the name of this category.
|
||||
* @param category the category to register.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_log_register(const char *name, VCOS_LOG_CAT_T *category);
|
||||
|
||||
/** Unregister a logging category.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_log_unregister(VCOS_LOG_CAT_T *category);
|
||||
|
||||
/** Return a default logging category, for people too lazy to create their own.
|
||||
*
|
||||
* Using the default category will be slow (there's an extra function
|
||||
* call overhead). Don't do this in normal code.
|
||||
*/
|
||||
VCOSPRE_ const VCOS_LOG_CAT_T * VCOSPOST_ vcos_log_get_default_category(void);
|
||||
|
||||
VCOSPRE_ void VCOSPOST_ vcos_set_log_options(const char *opt);
|
||||
|
||||
/** Set the logging level for a category at run time. Without this, the level
|
||||
* will be that set by vcos_log_register from a platform-specific source.
|
||||
*
|
||||
* @param category the category to modify.
|
||||
* @param level the new logging level for this category.
|
||||
*/
|
||||
VCOS_STATIC_INLINE void vcos_log_set_level(VCOS_LOG_CAT_T *category, VCOS_LOG_LEVEL_T level)
|
||||
{
|
||||
category->level = level;
|
||||
}
|
||||
|
||||
#define vcos_log_dump_mem(cat,label,addr,voidMem,numBytes) do { if (vcos_is_log_enabled(cat,VCOS_LOG_TRACE)) vcos_log_dump_mem_impl(cat,label,addr,voidMem,numBytes); } while (0)
|
||||
|
||||
void vcos_log_dump_mem_impl( const VCOS_LOG_CAT_T *cat,
|
||||
const char *label,
|
||||
uint32_t addr,
|
||||
const void *voidMem,
|
||||
size_t numBytes );
|
||||
|
||||
/*
|
||||
* Platform specific hooks (optional).
|
||||
*/
|
||||
#ifndef vcos_log_platform_init
|
||||
#define vcos_log_platform_init() (void)0
|
||||
#endif
|
||||
|
||||
#ifndef vcos_log_platform_register
|
||||
#define vcos_log_platform_register(category) (void)0
|
||||
#endif
|
||||
|
||||
#ifndef vcos_log_platform_unregister
|
||||
#define vcos_log_platform_unregister(category) (void)0
|
||||
#endif
|
||||
|
||||
/* VCOS_TRACE() - deprecated macro which just outputs in a debug build and
|
||||
* is a no-op in a release build.
|
||||
*
|
||||
* _VCOS_LOG_X() - internal macro which outputs if the current level for the
|
||||
* particular category is higher than the supplied message level.
|
||||
*/
|
||||
|
||||
#define VCOS_LOG_DFLT_CATEGORY vcos_log_get_default_category()
|
||||
|
||||
#define _VCOS_LEVEL(x) (x)
|
||||
|
||||
#define vcos_is_log_enabled(cat,_level) (_VCOS_LEVEL((cat)->level) >= _VCOS_LEVEL(_level))
|
||||
|
||||
#if defined(_VCOS_METAWARE) || defined(__GNUC__)
|
||||
|
||||
# if !defined(AMPUTATE_ALL_VCOS_LOGGING) && (!defined(NDEBUG) || defined(VCOS_ALWAYS_WANT_LOGGING))
|
||||
# define VCOS_LOGGING_ENABLED
|
||||
# define _VCOS_LOG_X(cat, _level, fmt...) do { if (vcos_is_log_enabled(cat,_level)) vcos_log_impl(cat,_level,fmt); } while (0)
|
||||
# define _VCOS_VLOG_X(cat, _level, fmt, ap) do { if (vcos_is_log_enabled(cat,_level)) vcos_vlog_impl(cat,_level,fmt,ap); } while (0)
|
||||
# else
|
||||
# define _VCOS_LOG_X(cat, _level, fmt...) (void)0
|
||||
# define _VCOS_VLOG_X(cat, _level, fmt, ap) (void)0
|
||||
# endif
|
||||
|
||||
|
||||
|
||||
# define vcos_log_error(...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_ERROR, __VA_ARGS__)
|
||||
# define vcos_log_warn(...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_WARN, __VA_ARGS__)
|
||||
# define vcos_log_info(...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_INFO, __VA_ARGS__)
|
||||
# define vcos_log_trace(...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_TRACE, __VA_ARGS__)
|
||||
|
||||
# define vcos_vlog_error(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_ERROR, fmt, ap)
|
||||
# define vcos_vlog_warn(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_WARN, fmt, ap)
|
||||
# define vcos_vlog_info(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_INFO, fmt, ap)
|
||||
# define vcos_vlog_trace(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_TRACE, fmt, ap)
|
||||
|
||||
# define vcos_logc_error(cat,...) _VCOS_LOG_X(cat, VCOS_LOG_ERROR, __VA_ARGS__)
|
||||
# define vcos_logc_warn(cat,...) _VCOS_LOG_X(cat, VCOS_LOG_WARN, __VA_ARGS__)
|
||||
# define vcos_logc_info(cat,...) _VCOS_LOG_X(cat, VCOS_LOG_INFO, __VA_ARGS__)
|
||||
# define vcos_logc_trace(cat,...) _VCOS_LOG_X(cat, VCOS_LOG_TRACE, __VA_ARGS__)
|
||||
|
||||
# define vcos_vlogc_error(cat,fmt,ap) _VCOS_VLOG_X(cat, VCOS_LOG_ERROR, fmt, ap)
|
||||
# define vcos_vlogc_warn(cat,fmt,ap) _VCOS_VLOG_X(cat, VCOS_LOG_WARN, fmt, ap)
|
||||
# define vcos_vlogc_info(cat,fmt,ap) _VCOS_VLOG_X(cat, VCOS_LOG_INFO, fmt, ap)
|
||||
# define vcos_vlogc_trace(cat,fmt,ap) _VCOS_VLOG_X(cat, VCOS_LOG_TRACE, fmt, ap)
|
||||
|
||||
# define vcos_log(...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, __VA_ARGS__)
|
||||
# define vcos_vlog(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, fmt, ap)
|
||||
# define VCOS_ALERT(...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_ERROR, __VA_ARGS__)
|
||||
# define VCOS_TRACE(...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, __VA_ARGS__)
|
||||
|
||||
/*
|
||||
* MS Visual Studio - pre 2005 does not grok variadic macros
|
||||
*/
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
# if _MSC_VER >= 1400
|
||||
|
||||
# if !defined(AMPUTATE_ALL_VCOS_LOGGING) && (!defined(NDEBUG) || defined(VCOS_ALWAYS_WANT_LOGGING))
|
||||
# define VCOS_LOGGING_ENABLED
|
||||
# define _VCOS_LOG_X(cat, _level, fmt,...) do { if (vcos_is_log_enabled(cat,_level)) vcos_log_impl(cat, _level, fmt, __VA_ARGS__); } while (0)
|
||||
# else
|
||||
# define _VCOS_LOG_X(cat, _level, fmt,...) (void)0
|
||||
# endif
|
||||
|
||||
# define vcos_log_error(fmt,...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_ERROR, fmt, __VA_ARGS__)
|
||||
# define vcos_log_warn(fmt,...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_WARN, fmt, __VA_ARGS__)
|
||||
# define vcos_log_info(fmt,...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_INFO, fmt, __VA_ARGS__)
|
||||
# define vcos_log_trace(fmt,...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_TRACE, fmt, __VA_ARGS__)
|
||||
|
||||
# define vcos_logc_error(cat,fmt,...) _VCOS_LOG_X(cat, VCOS_LOG_ERROR, fmt, __VA_ARGS__)
|
||||
# define vcos_logc_warn(cat,fmt,...) _VCOS_LOG_X(cat, VCOS_LOG_WARN, fmt, __VA_ARGS__)
|
||||
# define vcos_logc_info(cat,fmt,...) _VCOS_LOG_X(cat, VCOS_LOG_INFO, fmt, __VA_ARGS__)
|
||||
# define vcos_logc_trace(cat,fmt,...) _VCOS_LOG_X(cat, VCOS_LOG_TRACE, fmt, __VA_ARGS__)
|
||||
|
||||
# define vcos_log(fmt,...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, fmt, __VA_ARGS__)
|
||||
# define VCOS_ALERT(fmt,...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_ERROR, fmt, __VA_ARGS__)
|
||||
# define VCOS_TRACE(fmt,...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, fmt, __VA_ARGS__)
|
||||
|
||||
# else /* _MSC_VER >= 1400 */
|
||||
|
||||
/* do not define these */
|
||||
|
||||
# endif /* _MSC_VER >= 1400 */
|
||||
|
||||
#endif
|
||||
|
||||
#if VCOS_HAVE_CMD
|
||||
|
||||
#include "vcos_cmd.h"
|
||||
|
||||
/*
|
||||
* These are the log sub-commands. They're exported here for user-mode apps which
|
||||
* may want to call these, since the "log" command isn't registered for user-mode
|
||||
* apps (vcdbg for example, has its own log command).
|
||||
*/
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_log_assert_cmd( VCOS_CMD_PARAM_T *param );
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_log_set_cmd( VCOS_CMD_PARAM_T *param );
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_log_status_cmd( VCOS_CMD_PARAM_T *param );
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_log_test_cmd( VCOS_CMD_PARAM_T *param );
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* VCOS_LOGGING_H */
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - low level thread support
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_LOWLEVEL_THREAD_H
|
||||
#define VCOS_LOWLEVEL_THREAD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#ifndef VCOS_PLATFORM_H
|
||||
#include "pthreads/vcos_platform.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This defines a low level thread API that is supported by *some* operating systems
|
||||
* and can be used to construct the regular "joinable thread" API on those operating
|
||||
* systems.
|
||||
*
|
||||
* Most clients will not need to use this code.
|
||||
*
|
||||
* \sa vcos_joinable_thread.h
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Create a thread.
|
||||
*
|
||||
* This creates a thread which can be stopped either by returning from the
|
||||
* entry point function or by calling vcos_llthread_exit from within the entry
|
||||
* point function. The thread must be cleaned up by calling
|
||||
* vcos_llthread_delete. vcos_llthread_delete may or may not terminate the
|
||||
* thread.
|
||||
*
|
||||
* The preemptible parameter familiar from Nucleus is removed, as it is unused in
|
||||
* VideoCore code. Affinity is added, since we do use this.
|
||||
*
|
||||
* @param thread Filled in with thread instance
|
||||
* @param name An optional name for the thread. "" may be used (but
|
||||
* a name will aid in debugging).
|
||||
* @param entry Entry point
|
||||
* @param arg A single argument passed to the entry point function
|
||||
* @param stack Pointer to stack address
|
||||
* @param stacksz Size of stack in bytes
|
||||
* @param priority Priority of task, between VCOS_PRI_LOW and VCOS_PRI_HIGH
|
||||
* @param affinity CPU affinity
|
||||
*
|
||||
* @sa vcos_llthread_terminate vcos_llthread_delete
|
||||
*/
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_llthread_create(VCOS_LLTHREAD_T *thread,
|
||||
const char *name,
|
||||
VCOS_LLTHREAD_ENTRY_FN_T entry,
|
||||
void *arg,
|
||||
void *stack,
|
||||
VCOS_UNSIGNED stacksz,
|
||||
VCOS_UNSIGNED priority,
|
||||
VCOS_UNSIGNED affinity,
|
||||
VCOS_UNSIGNED timeslice,
|
||||
VCOS_UNSIGNED autostart);
|
||||
|
||||
/**
|
||||
* \brief Exits the current thread.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_llthread_exit(void);
|
||||
|
||||
/**
|
||||
* \brief Delete a thread. This must be called to cleanup after
|
||||
* vcos_llthread_create. This may or may not terminate the thread.
|
||||
* It does not clean up any resources that may have been
|
||||
* allocated by the thread.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_llthread_delete(VCOS_LLTHREAD_T *thread);
|
||||
|
||||
/**
|
||||
* \brief Return current lowlevel thread pointer.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_LLTHREAD_T *vcos_llthread_current(void);
|
||||
|
||||
/**
|
||||
* Resume a thread.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_llthread_resume(VCOS_LLTHREAD_T *thread);
|
||||
|
||||
VCOSPRE_ int VCOSPOST_ vcos_llthread_running(VCOS_LLTHREAD_T *thread);
|
||||
|
||||
/**
|
||||
* \brief Create a VCOS_LLTHREAD_T for the current thread. This is so we can
|
||||
* have VCOS_LLTHREAD_Ts even for threads not originally created by VCOS (eg
|
||||
* the thread that calls vcos_init).
|
||||
*/
|
||||
extern VCOS_STATUS_T _vcos_llthread_create_attach(VCOS_LLTHREAD_T *thread);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - memory support
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_MEM_H
|
||||
#define VCOS_MEM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Memory allocation api (malloc/free equivalents) is for benefit of host
|
||||
* applications. VideoCore code should use rtos_XXX functions.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/** Allocate memory
|
||||
*
|
||||
* @param size Size of memory to allocate
|
||||
* @param description Description, to aid in debugging. May be ignored internally on some platforms.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void *vcos_malloc(VCOS_UNSIGNED size, const char *description);
|
||||
|
||||
void *vcos_kmalloc(VCOS_UNSIGNED size, const char *description);
|
||||
void *vcos_kcalloc(VCOS_UNSIGNED num, VCOS_UNSIGNED size, const char *description);
|
||||
|
||||
/** Allocate cleared memory
|
||||
*
|
||||
* @param num Number of items to allocate.
|
||||
* @param size Size of each item in bytes.
|
||||
* @param description Description, to aid in debugging. May be ignored internally on some platforms.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void *vcos_calloc(VCOS_UNSIGNED num, VCOS_UNSIGNED size, const char *description);
|
||||
|
||||
/** Free memory
|
||||
*
|
||||
* Free memory that has been allocated.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_free(void *ptr);
|
||||
|
||||
void vcos_kfree(void *ptr);
|
||||
|
||||
/** Allocate aligned memory
|
||||
*
|
||||
* Allocate memory aligned on the specified boundary.
|
||||
*
|
||||
* @param size Size of memory to allocate
|
||||
* @param description Description, to aid in debugging. May be ignored internally on some platforms.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void *vcos_malloc_aligned(VCOS_UNSIGNED size, VCOS_UNSIGNED align, const char *description);
|
||||
|
||||
/** Return the amount of free heap memory
|
||||
*
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
unsigned long vcos_get_free_mem(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - memory pool support
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_MEMPOOL_H
|
||||
#define VCOS_MEMPOOL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Memory pools - variable sized allocator.
|
||||
*
|
||||
* A very basic memory pool API.
|
||||
*
|
||||
* This interface is deliberately not thread safe - clients should add
|
||||
* their own locking, if required.
|
||||
*
|
||||
*
|
||||
* \fixme: Add fixed-size allocator.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/** Initialize a memory pool. The control data is taken from the memory
|
||||
* supplied itself.
|
||||
*
|
||||
* Note: the dmalloc pool uses the memory supplied for its control
|
||||
* area. This is probably a bit broken, as it stops you creating
|
||||
* a pool in some "special" area of memory, while leaving the control
|
||||
* information in normal memory.
|
||||
*
|
||||
* @param pool Pointer to pool object.
|
||||
*
|
||||
* @param name Name for the pool. Used for diagnostics.
|
||||
*
|
||||
* @param start Starting address. Must be at least 8byte aligned.
|
||||
*
|
||||
* @param size Size of pool in bytes.
|
||||
*
|
||||
* @return VCOS_SUCCESS if pool was created.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_mempool_create(VCOS_MEMPOOL_T *pool, const char *name, void *start, VCOS_UNSIGNED size);
|
||||
|
||||
/** Allocate some memory from a pool. If no memory is available, it
|
||||
* returns NULL.
|
||||
*
|
||||
* @param pool Pool to allocate from
|
||||
* @param len Length of memory to allocate
|
||||
*
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void *vcos_mempool_alloc(VCOS_MEMPOOL_T *pool, VCOS_UNSIGNED len);
|
||||
|
||||
/** Free some memory back to a pool.
|
||||
*
|
||||
* @param pool Pool to return to
|
||||
* @param mem Memory to return
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_mempool_free(VCOS_MEMPOOL_T *pool, void *mem);
|
||||
|
||||
/** Deinitialize a memory pool.
|
||||
*
|
||||
* @param pool Pool to return to
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_mempool_delete(VCOS_MEMPOOL_T *pool);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VCOS - packet-like messages, based loosely on those found in TRIPOS.
|
||||
|
||||
In the simple case, only the server thread creates a message queue, and
|
||||
clients wait for replies on a semaphore. In more complex cases, clients can
|
||||
also create message queues (not yet implemented).
|
||||
|
||||
Although it's possible for a thread to create multiple queues and listen
|
||||
on them in turn, if you find yourself doing this it's probably a bug.
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_MSGQUEUE_H
|
||||
#define VCOS_MSGQUEUE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
#include "vcos_blockpool.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Packet-like messages, based loosely on those found in TRIPOS and
|
||||
* derivatives thereof.
|
||||
*
|
||||
* A task can send a message *pointer* to another task, where it is
|
||||
* queued on a linked list and the task woken up. The receiving task
|
||||
* consumes all of the messages on its input queue, and optionally
|
||||
* sends back replies using the original message memory.
|
||||
*
|
||||
* A caller can wait for the reply to a specific message - any other
|
||||
* messages that arrive in the meantime are queued separately.
|
||||
*
|
||||
*
|
||||
* All messages have a standard common layout, but the payload area can
|
||||
* be used freely to extend this.
|
||||
*/
|
||||
|
||||
#define VCOS_MSGQ_MAGIC 0x5147534d
|
||||
|
||||
/** Map the payload portion of a message to a structure pointer.
|
||||
*/
|
||||
#define VCOS_MSG_DATA(_msg) (void*)((_msg)->data)
|
||||
|
||||
/** Standard message ids - FIXME - these need to be done properly! */
|
||||
#define VCOS_MSG_N_QUIT 1
|
||||
#define VCOS_MSG_N_OPEN 2
|
||||
#define VCOS_MSG_N_CLOSE 3
|
||||
#define VCOS_MSG_N_PRIVATE (1<<20)
|
||||
|
||||
#define VCOS_MSG_REPLY_BIT (1<<31)
|
||||
|
||||
/** Make gnuc compiler be happy about pointer punning */
|
||||
#ifdef __GNUC__
|
||||
#define __VCOS_MAY_ALIAS __attribute__((__may_alias__))
|
||||
#else
|
||||
#define __VCOS_MAY_ALIAS
|
||||
#endif
|
||||
|
||||
struct VCOS_MSG_T;
|
||||
|
||||
/* Replies go to one of these objects.
|
||||
*/
|
||||
typedef struct VCOS_MSG_WAITER_T
|
||||
{
|
||||
/* When the reply is sent, this function gets called with the
|
||||
* address of the waiter.
|
||||
*/
|
||||
void (*on_reply)(struct VCOS_MSG_WAITER_T *waiter,
|
||||
struct VCOS_MSG_T *msg);
|
||||
} VCOS_MSG_WAITER_T;
|
||||
|
||||
/** A single message queue.
|
||||
*/
|
||||
typedef struct VCOS_MSGQUEUE_T
|
||||
{
|
||||
VCOS_MSG_WAITER_T waiter; /**< So we can wait on a queue */
|
||||
struct VCOS_MSG_T *head; /**< head of linked list of messages waiting on this queue */
|
||||
struct VCOS_MSG_T *tail; /**< tail of message queue */
|
||||
VCOS_SEMAPHORE_T sem; /**< thread waits on this for new messages */
|
||||
VCOS_MUTEX_T lock; /**< locks the messages list */
|
||||
int attached; /**< Is this attached to a thread? */
|
||||
} VCOS_MSGQUEUE_T;
|
||||
|
||||
/** A single message
|
||||
*/
|
||||
typedef struct VCOS_MSG_T
|
||||
{
|
||||
uint32_t magic; /**< Sanity checking */
|
||||
uint32_t code; /**< message code */
|
||||
struct VCOS_MSG_T *next; /**< next in queue */
|
||||
VCOS_THREAD_T *src_thread; /**< for debug */
|
||||
struct VCOS_MSG_WAITER_T *waiter; /**< client waiter structure */
|
||||
struct VCOS_MSGQ_POOL_T *pool; /**< Pool allocated from, or NULL */
|
||||
} VCOS_MSG_T;
|
||||
|
||||
#define MSG_REPLY_BIT (1<<31)
|
||||
|
||||
/** Initialize a VCOS_MSG_T. Can also use vcos_msg_init().
|
||||
*/
|
||||
#define VCOS_MSG_INITIALIZER {VCOS_MSGQ_MAGIC, 0, NULL, NULL, NULL, 0}
|
||||
|
||||
/** A pool of messages. This contains its own waiter and
|
||||
* semaphore, as well as a blockpool for the actual memory
|
||||
* management.
|
||||
*
|
||||
* When messages are returned to the waiter, it posts the
|
||||
* semaphore.
|
||||
*
|
||||
* When waiting for a message, we just wait on the semaphore.
|
||||
* When allocating without waiting, we just try-wait on the
|
||||
* semaphore.
|
||||
*
|
||||
* If we managed to claim the semaphore, then by definition
|
||||
* there must be at least that many free messages in the
|
||||
* blockpool.
|
||||
*/
|
||||
typedef struct VCOS_MSGQ_POOL_T
|
||||
{
|
||||
VCOS_MSG_WAITER_T waiter;
|
||||
VCOS_BLOCKPOOL_T blockpool;
|
||||
VCOS_SEMAPHORE_T sem;
|
||||
uint32_t magic;
|
||||
} VCOS_MSGQ_POOL_T;
|
||||
|
||||
/** Initalise the library. Normally called from vcos_init().
|
||||
*/
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_msgq_init(void);
|
||||
|
||||
/** De-initialise the library. Normally called from vcos_deinit().
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_msgq_deinit(void);
|
||||
|
||||
/** Send a message.
|
||||
*
|
||||
* @param dest Destination message queue
|
||||
* @param code Message code.
|
||||
* @param msg Pointer to message to send. Must not go out of scope before
|
||||
* message is received (do not declare on the stack).
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_msg_send(VCOS_MSGQUEUE_T *dest, uint32_t code, VCOS_MSG_T *msg);
|
||||
|
||||
/** Send a message and wait for a reply.
|
||||
*
|
||||
* @param dest Destination message queue
|
||||
* @param code Message code.
|
||||
* @param msg Pointer to message to send. May be declared on the stack.
|
||||
*/
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_msg_sendwait(VCOS_MSGQUEUE_T *queue, uint32_t code, VCOS_MSG_T *msg);
|
||||
|
||||
/** Wait for a message on a queue.
|
||||
*/
|
||||
VCOSPRE_ VCOS_MSG_T * VCOSPOST_ vcos_msg_wait(VCOS_MSGQUEUE_T *queue);
|
||||
|
||||
/** Peek for a message on this thread's endpoint. If a message is not
|
||||
* available, NULL is returned. If a message is available it will be
|
||||
* removed from the endpoint and returned.
|
||||
*/
|
||||
VCOSPRE_ VCOS_MSG_T * VCOSPOST_ vcos_msg_peek(VCOS_MSGQUEUE_T *queue);
|
||||
|
||||
/** Send a reply to a message
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_msg_reply(VCOS_MSG_T *msg);
|
||||
|
||||
/** Set the reply queue for a message. When the message is replied-to, it
|
||||
* will return to the given queue.
|
||||
*
|
||||
* @param msg Message
|
||||
* @param queue Message queue the message should return to
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_msg_set_source(VCOS_MSG_T *msg, VCOS_MSGQUEUE_T *queue);
|
||||
|
||||
/** Initialise a newly allocated message. This only needs to be called
|
||||
* for messages allocated on the stack, heap or statically. It is not
|
||||
* needed for messages allocated from a pool.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_msg_init(VCOS_MSG_T *msg);
|
||||
|
||||
/** Create a message queue to wait on.
|
||||
*/
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_msgq_create(VCOS_MSGQUEUE_T *queue, const char *name);
|
||||
|
||||
/** Destroy a queue
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_msgq_delete(VCOS_MSGQUEUE_T *queue);
|
||||
|
||||
/*
|
||||
* Message pools
|
||||
*/
|
||||
|
||||
/** Create a pool of messages. Messages can be allocated from the pool and
|
||||
* sent to a message queue. Replying to the message will automatically
|
||||
* free it back to the pool.
|
||||
*
|
||||
* The pool is threadsafe.
|
||||
*
|
||||
* @param count number of messages in the pool
|
||||
* @param payload_size maximum message payload size, not including MSG_T.
|
||||
*/
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_msgq_pool_create(
|
||||
VCOS_MSGQ_POOL_T *pool,
|
||||
size_t count,
|
||||
size_t payload_size,
|
||||
const char *name);
|
||||
|
||||
/** Destroy a message pool.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_msgq_pool_delete(VCOS_MSGQ_POOL_T *pool);
|
||||
|
||||
/** Allocate a message from a message pool.
|
||||
*
|
||||
* Note:
|
||||
*
|
||||
* If the alloc fails (returns NULL) then your worker thread has stopped
|
||||
* servicing requests or your pool is too small for the latency in
|
||||
* the system. Your best bet to handle this is to fail the call that
|
||||
* needs to send the message.
|
||||
*
|
||||
* The returned message payload area is initialised to zero.
|
||||
*
|
||||
* @param pool Pool to allocate from.
|
||||
* @return Message or NULL if pool exhausted.
|
||||
*/
|
||||
VCOSPRE_ VCOS_MSG_T *VCOSPOST_ vcos_msgq_pool_alloc(VCOS_MSGQ_POOL_T *pool);
|
||||
|
||||
/** Wait for a message from a message pool. Waits until a
|
||||
* message is available in the pool and then allocates it. If
|
||||
* one is already available, returns immediately.
|
||||
*
|
||||
* This call can never fail.
|
||||
*
|
||||
* The returned message payload area is initialised to zero.
|
||||
*
|
||||
* @param pool Pool to allocate from.
|
||||
* @return Message
|
||||
*/
|
||||
VCOSPRE_ VCOS_MSG_T *VCOSPOST_ vcos_msgq_pool_wait(VCOS_MSGQ_POOL_T *pool);
|
||||
|
||||
/** Explicitly free a message and return it to its pool.
|
||||
*
|
||||
* @param msg Message to free. No-op if NULL.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_msgq_pool_free(VCOS_MSG_T *msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - mutex public header file
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_MUTEX_H
|
||||
#define VCOS_MUTEX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
/**
|
||||
* \file vcos_mutex.h
|
||||
*
|
||||
* Mutex API. Mutexes are not re-entrant, as supporting this adds extra code
|
||||
* that slows down clients which have been written sensibly.
|
||||
*
|
||||
* \sa vcos_reentrant_mutex.h
|
||||
*
|
||||
*/
|
||||
|
||||
/** Create a mutex.
|
||||
*
|
||||
* @param m Filled in with mutex on return
|
||||
* @param name A non-null name for the mutex, used for diagnostics.
|
||||
*
|
||||
* @return VCOS_SUCCESS if mutex was created, or error code.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_mutex_create(VCOS_MUTEX_T *m, const char *name);
|
||||
|
||||
/** Delete the mutex.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_mutex_delete(VCOS_MUTEX_T *m);
|
||||
|
||||
/**
|
||||
* \brief Wait to claim the mutex.
|
||||
*
|
||||
* On most platforms this always returns VCOS_SUCCESS, and so would ideally be
|
||||
* a void function, however some platforms allow a wait to be interrupted so
|
||||
* it remains non-void.
|
||||
*
|
||||
* Try to obtain the mutex.
|
||||
* @param m Mutex to wait on
|
||||
* @return VCOS_SUCCESS - mutex was taken.
|
||||
* VCOS_EAGAIN - could not take mutex.
|
||||
*/
|
||||
#ifndef vcos_mutex_lock
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_mutex_lock(VCOS_MUTEX_T *m);
|
||||
|
||||
/** Release the mutex.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_mutex_unlock(VCOS_MUTEX_T *m);
|
||||
#endif
|
||||
|
||||
/** Test if the mutex is already locked.
|
||||
*
|
||||
* @return 1 if mutex is locked, 0 if it is unlocked.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
int vcos_mutex_is_locked(VCOS_MUTEX_T *m);
|
||||
|
||||
/** Obtain the mutex if possible.
|
||||
*
|
||||
* @param m the mutex to try to obtain
|
||||
*
|
||||
* @return VCOS_SUCCESS if mutex is succesfully obtained, or VCOS_EAGAIN
|
||||
* if it is already in use by another thread.
|
||||
*/
|
||||
#ifndef vcos_mutex_trylock
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_mutex_trylock(VCOS_MUTEX_T *m);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - named semaphores
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_NAMED_SEMAPHORE_H
|
||||
#define VCOS_NAMED_SEMAPHORE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Create a named semaphore, or open an existing one by name.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Create a named semaphore.
|
||||
*
|
||||
* Semaphores are not re-entrant.
|
||||
*
|
||||
* @param sem Pointer to memory to be initialized
|
||||
* @param name A name for this semaphore.
|
||||
* @param count The initial count for the semaphore.
|
||||
*
|
||||
* @return VCOS_SUCCESS if the semaphore was created.
|
||||
*
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_named_semaphore_create(VCOS_NAMED_SEMAPHORE_T *sem, const char *name, VCOS_UNSIGNED count);
|
||||
|
||||
/**
|
||||
* \brief Wait on a named semaphore.
|
||||
*
|
||||
* There is no timeout option on a semaphore, as adding this will slow down
|
||||
* implementations on some platforms. If you need that kind of behaviour, use
|
||||
* an event group.
|
||||
*
|
||||
* This always returns VCOS_SUCCESS and so should really be a void function. However
|
||||
* too many lines of code would need to be changed in non-trivial ways, so for now
|
||||
* it is non-void.
|
||||
*
|
||||
* @param sem Semaphore to wait on
|
||||
* @return VCOS_SUCCESS - semaphore was taken.
|
||||
*
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_named_semaphore_wait(VCOS_NAMED_SEMAPHORE_T *sem);
|
||||
|
||||
/**
|
||||
* \brief Try to wait for a semaphore.
|
||||
*
|
||||
* Try to obtain the semaphore. If it is already taken, return VCOS_TIMEOUT.
|
||||
* @param sem Semaphore to wait on
|
||||
* @return VCOS_SUCCESS - semaphore was taken.
|
||||
* VCOS_EAGAIN - could not take semaphore
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_named_semaphore_trywait(VCOS_NAMED_SEMAPHORE_T *sem);
|
||||
|
||||
/**
|
||||
* \brief Post a semaphore.
|
||||
*
|
||||
* @param sem Semaphore to wait on
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_named_semaphore_post(VCOS_NAMED_SEMAPHORE_T *sem);
|
||||
|
||||
/**
|
||||
* \brief Delete a semaphore, releasing any resources consumed by it.
|
||||
*
|
||||
* @param sem Semaphore to wait on
|
||||
*/
|
||||
void vcos_named_semaphore_delete(VCOS_NAMED_SEMAPHORE_T *sem);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - 'once'
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_ONCE_H
|
||||
#define VCOS_ONCE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
/**
|
||||
* \file vcos_once.h
|
||||
*
|
||||
* Ensure something is called only once.
|
||||
*
|
||||
* Initialize once_control to VCOS_ONCE_INIT. The first
|
||||
* time this is called, the init_routine will be called. Thereafter
|
||||
* it won't.
|
||||
*
|
||||
* \sa pthread_once()
|
||||
*
|
||||
*/
|
||||
|
||||
VCOS_STATUS_T vcos_once(VCOS_ONCE_T *once_control,
|
||||
void (*init_routine)(void));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - Queue public header file
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_QUEUE_H
|
||||
#define VCOS_QUEUE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
/** \file vcos_queue.h
|
||||
*
|
||||
* API for accessing a fixed length queue.
|
||||
*
|
||||
* Nucleus offers variable length items, but this feature is not used
|
||||
* in the current code base, so is withdrawn to simplify the API.
|
||||
*/
|
||||
|
||||
/** Create a fixed length queue.
|
||||
*
|
||||
* @param queue Pointer to queue control block
|
||||
* @param name Name of queue
|
||||
* @param message_size Size of each queue message item in words (words are sizeof VCOS_UNSIGNED).
|
||||
* @param queue_start Start address of queue area
|
||||
* @param queue_size Size in words (words are sizeof VCOS_UNSIGNED) of queue
|
||||
*
|
||||
*/
|
||||
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_queue_create(VCOS_QUEUE_T *queue,
|
||||
const char *name,
|
||||
VCOS_UNSIGNED message_size,
|
||||
void *queue_start,
|
||||
VCOS_UNSIGNED queue_size);
|
||||
|
||||
/** Delete a queue.
|
||||
* @param queue The queue to delete
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_queue_delete(VCOS_QUEUE_T *queue);
|
||||
|
||||
/** Send an item to a queue. If there is no space, the call with
|
||||
* either block waiting for space, or return an error, depending
|
||||
* on the value of the wait parameter.
|
||||
*
|
||||
* @param queue The queue to send to
|
||||
* @param src The data to send (length set when queue was created)
|
||||
* @param wait Whether to wait for space (VCOS_SUSPEND) or fail if
|
||||
* no space (VCOS_NO_SUSPEND).
|
||||
*
|
||||
* @return If space available, returns VCOS_SUCCESS. Otherwise returns
|
||||
* VCOS_EAGAIN if no space available before timeout expires.
|
||||
*
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_queue_send(VCOS_QUEUE_T *queue, const void *src, VCOS_UNSIGNED wait);
|
||||
|
||||
/** Receive an item from a queue.
|
||||
* @param queue The queue to receive from
|
||||
* @param dst Where to write the data to
|
||||
* @param wait Whether to wait (VCOS_SUSPEND) or fail if
|
||||
* empty (VCOS_NO_SUSPEND).
|
||||
*
|
||||
* @return If an item is available, returns VCOS_SUCCESS. Otherwise returns
|
||||
* VCOS_EAGAIN if no item available before timeout expires.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_queue_receive(VCOS_QUEUE_T *queue, void *dst, VCOS_UNSIGNED wait);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - mutex public header file
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_QUICKSLOW_MUTEX_H
|
||||
#define VCOS_QUICKSLOW_MUTEX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
/**
|
||||
* \file vcos_quickslow_mutex.h
|
||||
*
|
||||
* "Quick/Slow" Mutex API. This is a mutex which supports an additional "quick"
|
||||
* (spinlock-based) locking mechanism. While in this quick locked state, other
|
||||
* operating system commands will be unavailable and the caller should complete
|
||||
* whatever it has to do in a short, bounded length of time (as the spinlock
|
||||
* completely locks out other system activity).
|
||||
*
|
||||
* \sa vcos_mutex.h
|
||||
*
|
||||
*/
|
||||
|
||||
/** Create a mutex.
|
||||
*
|
||||
* @param m Filled in with mutex on return
|
||||
* @param name A non-null name for the mutex, used for diagnostics.
|
||||
*
|
||||
* @return VCOS_SUCCESS if mutex was created, or error code.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_quickslow_mutex_create(VCOS_QUICKSLOW_MUTEX_T *m, const char *name);
|
||||
|
||||
/** Delete the mutex.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_quickslow_mutex_delete(VCOS_QUICKSLOW_MUTEX_T *m);
|
||||
|
||||
/**
|
||||
* \brief Wait to claim the mutex ("slow" mode).
|
||||
*
|
||||
* Obtain the mutex.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_quickslow_mutex_lock(VCOS_QUICKSLOW_MUTEX_T *m);
|
||||
|
||||
/** Release the mutex ("slow" mode).
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_quickslow_mutex_unlock(VCOS_QUICKSLOW_MUTEX_T *m);
|
||||
|
||||
/**
|
||||
* \brief Wait to claim the mutex ("quick" mode).
|
||||
*
|
||||
* Obtain the mutex. The caller must not call any OS functions or do anything
|
||||
* "slow" before the corresponding call to vcos_mutex_quickslow_unlock_quick.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_quickslow_mutex_lock_quick(VCOS_QUICKSLOW_MUTEX_T *m);
|
||||
|
||||
/** Release the mutex ("quick" mode).
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_quickslow_mutex_unlock_quick(VCOS_QUICKSLOW_MUTEX_T *m);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - reentrant mutex public header file
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_REENTRANT_MUTEX_H
|
||||
#define VCOS_REENTRANT_MUTEX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Reentrant Mutex API. You can take one of these mutexes even if you've already
|
||||
* taken it. Just to make sure.
|
||||
*
|
||||
* A re-entrant mutex may be slower on some platforms than a regular one.
|
||||
*
|
||||
* \sa vcos_mutex.h
|
||||
*
|
||||
*/
|
||||
|
||||
/** Create a mutex.
|
||||
*
|
||||
* @param m Filled in with mutex on return
|
||||
* @param name A non-null name for the mutex, used for diagnostics.
|
||||
*
|
||||
* @return VCOS_SUCCESS if mutex was created, or error code.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_reentrant_mutex_create(VCOS_REENTRANT_MUTEX_T *m, const char *name);
|
||||
|
||||
/** Delete the mutex.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_reentrant_mutex_delete(VCOS_REENTRANT_MUTEX_T *m);
|
||||
|
||||
/** Wait to claim the mutex. Must not have already been claimed by the current thread.
|
||||
*/
|
||||
#ifndef vcos_reentrant_mutexlock
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_reentrant_mutex_lock(VCOS_REENTRANT_MUTEX_T *m);
|
||||
|
||||
/** Release the mutex.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_reentrant_mutex_unlock(VCOS_REENTRANT_MUTEX_T *m);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - public header file
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_SEMAPHORE_H
|
||||
#define VCOS_SEMAPHORE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#ifndef VCOS_PLATFORM_H
|
||||
#include "pthreads/vcos_platform.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \file vcos_semaphore.h
|
||||
*
|
||||
* \section sem Semaphores
|
||||
*
|
||||
* This provides counting semaphores. Semaphores are not re-entrant. On sensible
|
||||
* operating systems a semaphore can always be posted but can only be taken in
|
||||
* thread (not interrupt) context. Under Nucleus, a LISR cannot post a semaphore,
|
||||
* although it would not be hard to lift this restriction.
|
||||
*
|
||||
* \subsection timeout Timeout
|
||||
*
|
||||
* On both Nucleus and ThreadX a semaphore can be taken with a timeout. This is
|
||||
* not supported by VCOS because it makes the non-timeout code considerably more
|
||||
* complicated (and hence slower). In the unlikely event that you need a timeout
|
||||
* with a semaphore, and you cannot simply redesign your code to avoid it, use
|
||||
* an event flag (vcos_event_flags.h).
|
||||
*
|
||||
* \subsection sem_nucleus Changes from Nucleus:
|
||||
*
|
||||
* Semaphores are always "FIFO" - i.e. sleeping threads are woken in FIFO order. That's
|
||||
* because:
|
||||
* \arg there's no support for NU_PRIORITY in threadx (though it can be emulated, slowly)
|
||||
* \arg we don't appear to actually consciously use it - for example, Dispmanx uses
|
||||
* it, but all threads waiting are the same priority.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Create a semaphore.
|
||||
*
|
||||
* Create a semaphore.
|
||||
*
|
||||
* @param sem Pointer to memory to be initialized
|
||||
* @param name A name for this semaphore. The name may be truncated internally.
|
||||
* @param count The initial count for the semaphore.
|
||||
*
|
||||
* @return VCOS_SUCCESS if the semaphore was created.
|
||||
*
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_semaphore_create(VCOS_SEMAPHORE_T *sem, const char *name, VCOS_UNSIGNED count);
|
||||
|
||||
/**
|
||||
* \brief Wait on a semaphore.
|
||||
*
|
||||
* There is no timeout option on a semaphore, as adding this will slow down
|
||||
* implementations on some platforms. If you need that kind of behaviour, use
|
||||
* an event group.
|
||||
*
|
||||
* On most platforms this always returns VCOS_SUCCESS, and so would ideally be
|
||||
* a void function, however some platforms allow a wait to be interrupted so
|
||||
* it remains non-void.
|
||||
*
|
||||
* @param sem Semaphore to wait on
|
||||
* @return VCOS_SUCCESS - semaphore was taken.
|
||||
* VCOS_EAGAIN - could not take semaphore
|
||||
*
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_semaphore_wait(VCOS_SEMAPHORE_T *sem);
|
||||
|
||||
/**
|
||||
* \brief Wait on a semaphore with a timeout.
|
||||
*
|
||||
* Note that this function may not be implemented on all
|
||||
* platforms, and may not be efficient on all platforms
|
||||
* (see comment in vcos_semaphore_wait)
|
||||
*
|
||||
* Try to obtain the semaphore. If it is already taken, return
|
||||
* VCOS_EAGAIN.
|
||||
* @param sem Semaphore to wait on
|
||||
* @param timeout Number of milliseconds to wait before
|
||||
* returning if the semaphore can't be acquired.
|
||||
* @return VCOS_SUCCESS - semaphore was taken.
|
||||
* VCOS_EAGAIN - could not take semaphore (i.e. timeout
|
||||
* expired)
|
||||
* VCOS_EINVAL - Some other error (most likely bad
|
||||
* parameters).
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_semaphore_wait_timeout(VCOS_SEMAPHORE_T *sem, VCOS_UNSIGNED timeout);
|
||||
|
||||
/**
|
||||
* \brief Try to wait for a semaphore.
|
||||
*
|
||||
* Try to obtain the semaphore. If it is already taken, return VCOS_TIMEOUT.
|
||||
* @param sem Semaphore to wait on
|
||||
* @return VCOS_SUCCESS - semaphore was taken.
|
||||
* VCOS_EAGAIN - could not take semaphore
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_semaphore_trywait(VCOS_SEMAPHORE_T *sem);
|
||||
|
||||
/**
|
||||
* \brief Post a semaphore.
|
||||
*
|
||||
* @param sem Semaphore to wait on
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_semaphore_post(VCOS_SEMAPHORE_T *sem);
|
||||
|
||||
/**
|
||||
* \brief Delete a semaphore, releasing any resources consumed by it.
|
||||
*
|
||||
* @param sem Semaphore to wait on
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_semaphore_delete(VCOS_SEMAPHORE_T *sem);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef VCOS_STDBOOL_H
|
||||
#define VCOS_STDBOOL_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
#if defined(__STDC__) && (__STDC_VERSION__ >= 199901L)
|
||||
#include <stdbool.h>
|
||||
#else
|
||||
/* sizeof(bool) == 1. hopefully this matches up with c++ (so structures and
|
||||
* such containing bool are binary compatible), but the c++ standard doesn't
|
||||
* require sizeof(bool) == 1, so there's no guarantee */
|
||||
typedef unsigned char bool;
|
||||
enum {
|
||||
false,
|
||||
true
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef VCOS_STDINT_H
|
||||
#define VCOS_STDINT_H
|
||||
|
||||
/** \file
|
||||
* Attempt to provide the types defined in stdint.h.
|
||||
*
|
||||
* Except for use with lcc, this simply includes stdint.h, which should find
|
||||
* the system/toolchain version if present, otherwise falling back to the
|
||||
* version in <platform>.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined (VCMODS_LCC)
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
typedef signed short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
|
||||
typedef signed long int32_t;
|
||||
typedef unsigned long uint32_t;
|
||||
|
||||
typedef int32_t intptr_t;
|
||||
typedef uint32_t uintptr_t;
|
||||
|
||||
typedef int32_t intmax_t;
|
||||
typedef uint32_t uintmax_t;
|
||||
|
||||
typedef int8_t int_least8_t;
|
||||
typedef int16_t int_least16_t;
|
||||
typedef int32_t int_least32_t;
|
||||
typedef uint8_t uint_least8_t;
|
||||
typedef uint16_t uint_least16_t;
|
||||
typedef uint32_t uint_least32_t;
|
||||
|
||||
#define INT8_MIN SCHAR_MIN
|
||||
#define INT8_MAX SCHAR_MAX
|
||||
#define UINT8_MAX UCHAR_MAX
|
||||
|
||||
#define INT16_MIN SHRT_MIN
|
||||
#define INT16_MAX SHRT_MAX
|
||||
#define UINT16_MAX USHRT_MAX
|
||||
|
||||
#define INT32_MIN LONG_MIN
|
||||
#define INT32_MAX LONG_MAX
|
||||
#define UINT32_MAX ULONG_MAX
|
||||
|
||||
#define INTPTR_MIN INT32_MIN
|
||||
#define INTPTR_MAX INT32_MAX
|
||||
#define UINTPTR_MAX UINT32_MAX
|
||||
|
||||
#define INTMAX_MIN INT32_MIN
|
||||
#define INTMAX_MAX INT32_MAX
|
||||
#define UINTMAX_MAX UINT32_MAX
|
||||
|
||||
/* N.B. 64-bit integer types are not currently supported by lcc.
|
||||
* However, these symbols are referenced in header files included by files
|
||||
* compiled by lcc for VCE, so removing them would break the build.
|
||||
* The solution here then is to define them, as the correct size, but in a
|
||||
* way that should make them unusable in normal arithmetic operations.
|
||||
*/
|
||||
typedef struct { uint32_t a; uint32_t b; } int64_t;
|
||||
typedef struct { uint32_t a; uint32_t b; } uint64_t;
|
||||
|
||||
#else
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* VCOS_STDINT_H */
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - public header file
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_STRING_H
|
||||
#define VCOS_STRING_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* String functions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/string.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
/** Case insensitive string comparison.
|
||||
*
|
||||
*/
|
||||
|
||||
VCOS_INLINE_DECL
|
||||
int vcos_strcasecmp(const char *s1, const char *s2);
|
||||
|
||||
VCOS_INLINE_DECL
|
||||
int vcos_strncasecmp(const char *s1, const char *s2, size_t n);
|
||||
|
||||
VCOSPRE_ int VCOSPOST_ vcos_vsnprintf(char *buf, size_t buflen, const char *fmt, va_list ap);
|
||||
|
||||
VCOSPRE_ int VCOSPOST_ vcos_snprintf(char *buf, size_t buflen, const char *fmt, ...);
|
||||
|
||||
/** Like vsnprintf, except it places the output at the specified offset.
|
||||
* Output is truncated to fit in buflen bytes, and is guaranteed to be NUL-terminated.
|
||||
* Returns the string length before/without truncation.
|
||||
*/
|
||||
VCOSPRE_ size_t VCOSPOST_ vcos_safe_vsprintf(char *buf, size_t buflen, size_t offset, const char *fmt, va_list ap);
|
||||
|
||||
#define VCOS_SAFE_VSPRINTF(buf, offset, fmt, ap) \
|
||||
vcos_safe_vsprintf(buf, sizeof(buf) + ((char (*)[sizeof(buf)])buf - &(buf)), offset, fmt, ap)
|
||||
|
||||
/** Like snprintf, except it places the output at the specified offset.
|
||||
* Output is truncated to fit in buflen bytes, and is guaranteed to be NUL-terminated.
|
||||
* Returns the string length before/without truncation.
|
||||
*/
|
||||
VCOSPRE_ size_t VCOSPOST_ vcos_safe_sprintf(char *buf, size_t buflen, size_t offset, const char *fmt, ...);
|
||||
|
||||
/* The Metaware compiler currently has a bug in its variadic macro handling which
|
||||
causes it to append a spurious command to the end of its __VA_ARGS__ data.
|
||||
Do not use until this has been fixed (and this comment has been deleted). */
|
||||
|
||||
#define VCOS_SAFE_SPRINTF(buf, offset, ...) \
|
||||
vcos_safe_sprintf(buf, sizeof(buf) + ((char (*)[sizeof(buf)])buf - &(buf)), offset, __VA_ARGS__)
|
||||
|
||||
/** Copies string src to dst at the specified offset.
|
||||
* Output is truncated to fit in dstlen bytes, i.e. the string is at most
|
||||
* (buflen - 1) characters long. Unlike strncpy, exactly one NUL is written
|
||||
* to dst, which is always NUL-terminated.
|
||||
* Returns the string length before/without truncation.
|
||||
*/
|
||||
VCOSPRE_ size_t VCOSPOST_ vcos_safe_strcpy(char *dst, const char *src, size_t dstlen, size_t offset);
|
||||
|
||||
#define VCOS_SAFE_STRCPY(dst, src, offset) \
|
||||
vcos_safe_strcpy(dst, src, sizeof(dst) + ((char (*)[sizeof(dst)])dst - &(dst)), offset)
|
||||
|
||||
VCOS_STATIC_INLINE
|
||||
int vcos_strlen(const char *s) { return (int)strlen(s); }
|
||||
|
||||
VCOS_STATIC_INLINE
|
||||
int vcos_strcmp(const char *s1, const char *s2) { return strcmp(s1,s2); }
|
||||
|
||||
VCOS_STATIC_INLINE
|
||||
int vcos_strncmp(const char *cs, const char *ct, size_t count) { return strncmp(cs, ct, count); }
|
||||
|
||||
VCOS_STATIC_INLINE
|
||||
char *vcos_strcpy(char *dst, const char *src) { return strcpy(dst, src); }
|
||||
|
||||
VCOS_STATIC_INLINE
|
||||
char *vcos_strncpy(char *dst, const char *src, size_t count) { return strncpy(dst, src, count); }
|
||||
|
||||
VCOS_STATIC_INLINE
|
||||
void *vcos_memcpy(void *dst, const void *src, size_t n) { memcpy(dst, src, n); return dst; }
|
||||
|
||||
VCOS_STATIC_INLINE
|
||||
void *vcos_memset(void *p, int c, size_t n) { return memset(p, c, n); }
|
||||
|
||||
VCOS_STATIC_INLINE
|
||||
int vcos_memcmp(const void *ptr1, const void *ptr2, size_t count) { return memcmp(ptr1, ptr2, count); }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - public header file
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_THREAD_H
|
||||
#define VCOS_THREAD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
/**
|
||||
* \file vcos_thread.h
|
||||
*
|
||||
* \section thread Threads
|
||||
*
|
||||
* Under Nucleus, a thread is created by NU_Create_Task, passing in the stack
|
||||
* and various other parameters. To stop the thread, NU_Terminate_Thread() and
|
||||
* NU_Delete_Thread() are called.
|
||||
*
|
||||
* Unfortunately it's not possible to emulate this API under some fairly common
|
||||
* operating systems. Under Windows you can't pass in the stack, and you can't
|
||||
* safely terminate a thread.
|
||||
*
|
||||
* Therefore, an API which is similar to the pthreads API is used instead. This
|
||||
* API can (mostly) be emulated under all interesting operating systems.
|
||||
*
|
||||
* Obviously this makes the code somewhat more complicated on VideoCore than it
|
||||
* would otherwise be - we end up with an extra mutex per thread, and some code
|
||||
* that waits for it. The benefit is that we have a single way of creating
|
||||
* threads that works consistently on all platforms (apart from stack supplying).
|
||||
*
|
||||
* \subsection stack Stack
|
||||
*
|
||||
* It's still not possible to pass in the stack address, but this can be made
|
||||
* much more obvious in the API: the relevant function is missing and the
|
||||
* CPP symbol VCOS_CAN_SET_STACK_ADDR is zero rather than one.
|
||||
*
|
||||
* \subsection thr_create Creating a thread
|
||||
*
|
||||
* The simplest way to create a thread is with vcos_thread_create() passing in a
|
||||
* NULL thread parameter argument. To wait for the thread to exit, call
|
||||
* vcos_thread_join().
|
||||
*
|
||||
* \subsection back Backward compatibility
|
||||
*
|
||||
* To ease migration, a "classic" thread creation API is provided for code
|
||||
* that used to make use of Nucleus, vcos_thread_create_classic(). The
|
||||
* arguments are not exactly the same, as the PREEMPT parameter is dropped.
|
||||
*
|
||||
*/
|
||||
|
||||
#define VCOS_AFFINITY_CPU0 _VCOS_AFFINITY_CPU0
|
||||
#define VCOS_AFFINITY_CPU1 _VCOS_AFFINITY_CPU1
|
||||
#define VCOS_AFFINITY_MASK _VCOS_AFFINITY_MASK
|
||||
#define VCOS_AFFINITY_DEFAULT _VCOS_AFFINITY_DEFAULT
|
||||
#define VCOS_AFFINITY_THISCPU _VCOS_AFFINITY_THISCPU
|
||||
|
||||
/** Report whether or not we have an RTOS at all, and hence the ability to
|
||||
* create threads.
|
||||
*/
|
||||
VCOSPRE_ int VCOSPOST_ vcos_have_rtos(void);
|
||||
|
||||
/** Create a thread. It must be cleaned up by calling vcos_thread_join().
|
||||
*
|
||||
* @param thread Filled in on return with thread
|
||||
* @param name A name for the thread. May be the empty string.
|
||||
* @param attrs Attributes; default attributes will be used if this is NULL.
|
||||
* @param entry Entry point.
|
||||
* @param arg Argument passed to the entry point.
|
||||
*/
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_thread_create(VCOS_THREAD_T *thread,
|
||||
const char *name,
|
||||
VCOS_THREAD_ATTR_T *attrs,
|
||||
VCOS_THREAD_ENTRY_FN_T entry,
|
||||
void *arg);
|
||||
|
||||
/** Exit the thread from within the thread function itself.
|
||||
* Resources must still be cleaned up via a call to thread_join().
|
||||
*
|
||||
* The thread can also be terminated by simply exiting the thread function.
|
||||
*
|
||||
* @param data Data passed to thread_join. May be NULL.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_thread_exit(void *data);
|
||||
|
||||
/** Wait for a thread to terminate and then clean up its resources.
|
||||
*
|
||||
* @param thread Thread to wait for
|
||||
* @param pData Updated to point at data provided in vcos_thread_exit or exit
|
||||
* code of thread function.
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_thread_join(VCOS_THREAD_T *thread,
|
||||
void **pData);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Create a thread using an API similar to the one "traditionally"
|
||||
* used under Nucleus.
|
||||
*
|
||||
* This creates a thread which must be cleaned up by calling vcos_thread_join().
|
||||
* The thread cannot be simply terminated (as in Nucleus and ThreadX) as thread
|
||||
* termination is not universally supported.
|
||||
*
|
||||
* @param thread Filled in with thread instance
|
||||
* @param name An optional name for the thread. NULL or "" may be used (but
|
||||
* a name will aid in debugging).
|
||||
* @param entry Entry point
|
||||
* @param arg A single argument passed to the entry point function
|
||||
* @param stack Pointer to stack address
|
||||
* @param stacksz Size of stack in bytes
|
||||
* @param priaff Priority of task, between VCOS_PRI_LOW and VCOS_PRI_HIGH, ORed with the CPU affinity
|
||||
* @param autostart If non-zero the thread will start immediately.
|
||||
* @param timeslice Timeslice (system ticks) for this thread.
|
||||
*
|
||||
* @sa vcos_thread_terminate vcos_thread_delete
|
||||
*/
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_thread_create_classic(VCOS_THREAD_T *thread,
|
||||
const char *name,
|
||||
void *(*entry)(void *arg),
|
||||
void *arg,
|
||||
void *stack,
|
||||
VCOS_UNSIGNED stacksz,
|
||||
VCOS_UNSIGNED priaff,
|
||||
VCOS_UNSIGNED timeslice,
|
||||
VCOS_UNSIGNED autostart);
|
||||
|
||||
/**
|
||||
* \brief Set a thread's priority
|
||||
*
|
||||
* Set the priority for a thread.
|
||||
*
|
||||
* @param thread The thread
|
||||
* @param pri Thread priority in VCOS_PRI_MASK bits; affinity in VCOS_AFFINITY_MASK bits.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_thread_set_priority(VCOS_THREAD_T *thread, VCOS_UNSIGNED pri);
|
||||
|
||||
/**
|
||||
* \brief Return the currently executing thread.
|
||||
*
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_THREAD_T *vcos_thread_current(void);
|
||||
|
||||
/**
|
||||
* \brief Return the thread's priority.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_UNSIGNED vcos_thread_get_priority(VCOS_THREAD_T *thread);
|
||||
|
||||
/**
|
||||
* \brief Return the thread's cpu affinity.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_UNSIGNED vcos_thread_get_affinity(VCOS_THREAD_T *thread);
|
||||
|
||||
/**
|
||||
* \brief Set the thread's cpu affinity.
|
||||
*/
|
||||
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_thread_set_affinity(VCOS_THREAD_T *thread, VCOS_UNSIGNED affinity);
|
||||
|
||||
/**
|
||||
* \brief Query whether we are in an interrupt.
|
||||
*
|
||||
* @return 1 if in interrupt context.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
int vcos_in_interrupt(void);
|
||||
|
||||
/**
|
||||
* \brief Sleep a while.
|
||||
*
|
||||
* @param ms Number of milliseconds to sleep for
|
||||
*
|
||||
* This may actually sleep a whole number of ticks.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_sleep(uint32_t ms);
|
||||
|
||||
/**
|
||||
* \brief Return the value of the hardware microsecond counter.
|
||||
*
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
uint32_t vcos_getmicrosecs(void);
|
||||
|
||||
VCOS_INLINE_DECL
|
||||
uint64_t vcos_getmicrosecs64(void);
|
||||
|
||||
#define vcos_get_ms() (vcos_getmicrosecs()/1000)
|
||||
|
||||
/**
|
||||
* \brief Return a unique identifier for the current process
|
||||
*
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_UNSIGNED vcos_process_id_current(void);
|
||||
|
||||
/** Relinquish this time slice. */
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_thread_relinquish(void);
|
||||
|
||||
/** Return the name of the given thread.
|
||||
*/
|
||||
VCOSPRE_ const char * VCOSPOST_ vcos_thread_get_name(const VCOS_THREAD_T *thread);
|
||||
|
||||
/** Change preemption. This is almost certainly not what you want, as it won't
|
||||
* work reliably in a multicore system: although you can affect the preemption
|
||||
* on *this* core, you won't affect what's happening on the other core(s).
|
||||
*
|
||||
* It's mainly here to ease migration. If you're using it in new code, you
|
||||
* probably need to think again.
|
||||
*
|
||||
* @param pe New preemption, VCOS_PREEMPT or VCOS_NO_PREEMPT
|
||||
* @return Old value of preemption.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_UNSIGNED vcos_change_preemption(VCOS_UNSIGNED pe);
|
||||
|
||||
/** Is a thread still running, or has it exited?
|
||||
*
|
||||
* Note: this exists for some fairly scary code in the video codec tests. Don't
|
||||
* try to use it for anything else, as it may well not do what you expect.
|
||||
*
|
||||
* @param thread thread to query
|
||||
* @return non-zero if thread is running, or zero if it has exited.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
int vcos_thread_running(VCOS_THREAD_T *thread);
|
||||
|
||||
/** Resume a thread.
|
||||
*
|
||||
* @param thread thread to resume
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_thread_resume(VCOS_THREAD_T *thread);
|
||||
|
||||
/*
|
||||
* Internal APIs - may not always be present and should not be used in
|
||||
* client code.
|
||||
*/
|
||||
|
||||
extern void _vcos_task_timer_set(void (*pfn)(void*), void *, VCOS_UNSIGNED ms);
|
||||
extern void _vcos_task_timer_cancel(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - thread attributes
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_THREAD_ATTR_H
|
||||
#define VCOS_THREAD_ATTR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Attributes for thread creation.
|
||||
*
|
||||
*/
|
||||
|
||||
/** Initialize thread attribute struct. This call does not allocate memory,
|
||||
* and so cannot fail.
|
||||
*
|
||||
*/
|
||||
VCOSPRE_ void VCOSPOST_ vcos_thread_attr_init(VCOS_THREAD_ATTR_T *attrs);
|
||||
|
||||
/** Set the stack address and size. If not set, a stack will be allocated automatically.
|
||||
*
|
||||
* This can only be set on some platforms. It will always be possible to set the stack
|
||||
* address on VideoCore, but on host platforms, support may well not be available.
|
||||
*/
|
||||
#if VCOS_CAN_SET_STACK_ADDR
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_thread_attr_setstack(VCOS_THREAD_ATTR_T *attrs, void *addr, VCOS_UNSIGNED sz);
|
||||
#endif
|
||||
|
||||
/** Set the stack size. If not set, a default size will be used. Attempting to call this after having
|
||||
* set the stack location with vcos_thread_attr_setstack() will result in undefined behaviour.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_thread_attr_setstacksize(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED sz);
|
||||
|
||||
/** Set the task priority. If not set, a default value will be used.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_thread_attr_setpriority(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED pri);
|
||||
|
||||
/** Set the task cpu affinity. If not set, the default will be used.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_thread_attr_setaffinity(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED aff);
|
||||
|
||||
/** Set the timeslice. If not set the default will be used.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_thread_attr_settimeslice(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED ts);
|
||||
|
||||
/** The thread entry function takes (argc,argv), as per Nucleus, with
|
||||
* argc being 0. This may be withdrawn in a future release and should not
|
||||
* be used in new code.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void _vcos_thread_attr_setlegacyapi(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED legacy);
|
||||
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_thread_attr_setautostart(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED autostart);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - timer support
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_TIMER_H
|
||||
#define VCOS_TIMER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#ifndef VCOS_PLATFORM_H
|
||||
#include "pthreads/vcos_platform.h"
|
||||
#endif
|
||||
|
||||
/** \file vcos_timer.h
|
||||
*
|
||||
* Timers are single shot.
|
||||
*
|
||||
* Timer times are in milliseconds.
|
||||
*
|
||||
* \note that timer callback functions are called from an arbitrary thread
|
||||
* context. The expiration function should do its work as quickly as possible;
|
||||
* blocking should be avoided.
|
||||
*
|
||||
* \note On Windows, the separate function vcos_timer_init() must be called
|
||||
* as timer initialization from DllMain is not possible.
|
||||
*/
|
||||
|
||||
/** Perform timer subsystem initialization. This function is not needed
|
||||
* on non-Windows platforms but is still present so that it can be
|
||||
* called. On Windows it is needed because vcos_init() gets called
|
||||
* from DLL initialization where it is not possible to create a
|
||||
* time queue (deadlock occurs if you try).
|
||||
*
|
||||
* @return VCOS_SUCCESS on success. VCOS_EEXIST if this has already been called
|
||||
* once. VCOS_ENOMEM if resource allocation failed.
|
||||
*/
|
||||
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_timer_init(void);
|
||||
|
||||
/** Create a timer in a disabled state.
|
||||
*
|
||||
* The timer is initially disabled.
|
||||
*
|
||||
* @param timer timer handle
|
||||
* @param name name for timer
|
||||
* @param expiration_routine function to call when timer expires
|
||||
* @param context context passed to expiration routine
|
||||
*
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_timer_create(VCOS_TIMER_T *timer,
|
||||
const char *name,
|
||||
void (*expiration_routine)(void *context),
|
||||
void *context);
|
||||
|
||||
|
||||
|
||||
/** Start a timer running.
|
||||
*
|
||||
* Timer must be stopped.
|
||||
*
|
||||
* @param timer timer handle
|
||||
* @param delay Delay to wait for, in ms
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_timer_set(VCOS_TIMER_T *timer, VCOS_UNSIGNED delay);
|
||||
|
||||
/** Stop an already running timer.
|
||||
*
|
||||
* @param timer timer handle
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_timer_cancel(VCOS_TIMER_T *timer);
|
||||
|
||||
/** Stop a timer and restart it.
|
||||
* @param timer timer handle
|
||||
* @param delay delay in ms
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_timer_reset(VCOS_TIMER_T *timer, VCOS_UNSIGNED delay);
|
||||
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_timer_delete(VCOS_TIMER_T *timer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - thread local storage
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_TLS_H
|
||||
#define VCOS_TLS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vcos_types.h"
|
||||
#include "pthreads/vcos_platform.h"
|
||||
|
||||
|
||||
/** Create a new thread local storage data key visible to all threads in
|
||||
* the current process.
|
||||
*
|
||||
* @param key The key to create
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_tls_create(VCOS_TLS_KEY_T *key);
|
||||
|
||||
/** Delete an existing TLS data key.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void vcos_tls_delete(VCOS_TLS_KEY_T tls);
|
||||
|
||||
/** Set the value seen by the current thread.
|
||||
*
|
||||
* @param key The key to update
|
||||
* @param v The value to set for the current thread.
|
||||
*
|
||||
* @return VCOS_SUCCESS, or VCOS_ENOMEM if memory for this slot
|
||||
* could not be allocated.
|
||||
*
|
||||
* If TLS is being emulated via VCOS then the memory required
|
||||
* can be preallocated at thread creation time
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
VCOS_STATUS_T vcos_tls_set(VCOS_TLS_KEY_T tls, void *v);
|
||||
|
||||
/** Get the value for the current thread.
|
||||
*
|
||||
* @param key The key to update
|
||||
*
|
||||
* @return The current value for this thread.
|
||||
*/
|
||||
VCOS_INLINE_DECL
|
||||
void *vcos_tls_get(VCOS_TLS_KEY_T tls);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
VideoCore OS Abstraction Layer - basic types
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef VCOS_TYPES_H
|
||||
#define VCOS_TYPES_H
|
||||
|
||||
#define VCOS_VERSION 1
|
||||
|
||||
#include <stddef.h>
|
||||
#include "pthreads/vcos_platform_types.h"
|
||||
#include "vcos_attr.h"
|
||||
|
||||
#if !defined(VCOSPRE_) || !defined(VCOSPOST_)
|
||||
#error VCOSPRE_ and VCOSPOST_ not defined!
|
||||
#endif
|
||||
|
||||
/* Redefine these here; this means that existing header files can carry on
|
||||
* using the VCHPOST/VCHPRE macros rather than having huge changes, which
|
||||
* could cause nasty merge problems.
|
||||
*/
|
||||
#ifndef VCHPOST_
|
||||
#define VCHPOST_ VCOSPOST_
|
||||
#endif
|
||||
#ifndef VCHPRE_
|
||||
#define VCHPRE_ VCOSPRE_
|
||||
#endif
|
||||
|
||||
/** Entry function for a lowlevel thread.
|
||||
*
|
||||
* Returns void for consistency with Nucleus/ThreadX.
|
||||
*/
|
||||
typedef void (*VCOS_LLTHREAD_ENTRY_FN_T)(void *);
|
||||
|
||||
/** Thread entry point. Returns a void* for consistency
|
||||
* with pthreads.
|
||||
*/
|
||||
typedef void *(*VCOS_THREAD_ENTRY_FN_T)(void*);
|
||||
|
||||
|
||||
/* Error return codes - chosen to be similar to errno values */
|
||||
typedef enum
|
||||
{
|
||||
VCOS_SUCCESS,
|
||||
VCOS_EAGAIN,
|
||||
VCOS_ENOENT,
|
||||
VCOS_ENOSPC,
|
||||
VCOS_EINVAL,
|
||||
VCOS_EACCESS,
|
||||
VCOS_ENOMEM,
|
||||
VCOS_ENOSYS,
|
||||
VCOS_EEXIST,
|
||||
VCOS_ENXIO,
|
||||
VCOS_EINTR
|
||||
} VCOS_STATUS_T;
|
||||
|
||||
/* Some compilers (MetaWare) won't inline with -g turned on, which then results
|
||||
* in a lot of code bloat. To overcome this, inline functions are forward declared
|
||||
* with the prefix VCOS_INLINE_DECL, and implemented with the prefix VCOS_INLINE_IMPL.
|
||||
*
|
||||
* That then means that in a release build, "static inline" can be used in the obvious
|
||||
* way, but in a debug build the implementations can be skipped in all but one file,
|
||||
* by using VCOS_INLINE_BODIES.
|
||||
*
|
||||
* VCOS_INLINE_DECL - put this at the start of an inline forward declaration of a VCOS
|
||||
* function.
|
||||
*
|
||||
* VCOS_INLINE_IMPL - put this at the start of an inlined implementation of a VCOS
|
||||
* function.
|
||||
*
|
||||
*/
|
||||
|
||||
/* VCOS_EXPORT - it turns out that in some circumstances we need the implementation of
|
||||
* a function even if it is usually inlined.
|
||||
*
|
||||
* In particular, if we have a codec that is usually provided in object form, if it
|
||||
* was built for a debug build it will be full of calls to vcos_XXX(). If this is used
|
||||
* in a *release* build, then there won't be any of these calls around in the main image
|
||||
* as they will all have been inlined. The problem also exists for vcos functions called
|
||||
* from assembler.
|
||||
*
|
||||
* VCOS_EXPORT ensures that the named function will be emitted as a regular (not static-inline)
|
||||
* function inside vcos_<platform>.c so that it can be linked against. Doing this for every
|
||||
* VCOS function would be a bit code-bloat-tastic, so it is only done for those that need it.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define _VCOS_INLINE inline
|
||||
#else
|
||||
#define _VCOS_INLINE __inline
|
||||
#endif
|
||||
|
||||
#if defined(NDEBUG)
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define VCOS_INLINE_DECL extern __inline__
|
||||
# define VCOS_INLINE_IMPL static __inline__
|
||||
#else
|
||||
# define VCOS_INLINE_DECL static _VCOS_INLINE /* declare a func */
|
||||
# define VCOS_INLINE_IMPL static _VCOS_INLINE /* implement a func inline */
|
||||
#endif
|
||||
|
||||
# if defined(VCOS_WANT_IMPL)
|
||||
# define VCOS_EXPORT
|
||||
# else
|
||||
# define VCOS_EXPORT VCOS_INLINE_IMPL
|
||||
# endif /* VCOS_WANT_IMPL */
|
||||
|
||||
#define VCOS_INLINE_BODIES
|
||||
|
||||
#else /* NDEBUG */
|
||||
|
||||
#if !defined(VCOS_INLINE_DECL)
|
||||
#define VCOS_INLINE_DECL extern
|
||||
#endif
|
||||
#if !defined(VCOS_INLINE_IMPL)
|
||||
#define VCOS_INLINE_IMPL
|
||||
#endif
|
||||
#define VCOS_EXPORT VCOS_INLINE_IMPL
|
||||
#endif
|
||||
|
||||
#define VCOS_STATIC_INLINE static _VCOS_INLINE
|
||||
|
||||
#if defined(__HIGHC__) || defined(__HIGHC_ANSI__)
|
||||
#define _VCOS_METAWARE
|
||||
#endif
|
||||
|
||||
/** It seems that __FUNCTION__ isn't standard!
|
||||
*/
|
||||
#if __STDC_VERSION__ < 199901L
|
||||
# if __GNUC__ >= 2 || defined(__VIDEOCORE__)
|
||||
# define VCOS_FUNCTION __FUNCTION__
|
||||
# else
|
||||
# define VCOS_FUNCTION "<unknown>"
|
||||
# endif
|
||||
#else
|
||||
# define VCOS_FUNCTION __func__
|
||||
#endif
|
||||
|
||||
#define _VCOS_MS_PER_TICK (1000/VCOS_TICKS_PER_SECOND)
|
||||
|
||||
/* Convert a number of milliseconds to a tick count. Internal use only - fails to
|
||||
* convert VCOS_SUSPEND correctly.
|
||||
*/
|
||||
#define _VCOS_MS_TO_TICKS(ms) (((ms)+_VCOS_MS_PER_TICK-1)/_VCOS_MS_PER_TICK)
|
||||
|
||||
#define VCOS_TICKS_TO_MS(ticks) ((ticks) * _VCOS_MS_PER_TICK)
|
||||
|
||||
/** VCOS version of DATESTR, from pcdisk.h. Used by the hostreq service.
|
||||
*/
|
||||
typedef struct vcos_datestr
|
||||
{
|
||||
uint8_t cmsec; /**< Centesimal mili second */
|
||||
uint16_t date; /**< Date */
|
||||
uint16_t time; /**< Time */
|
||||
|
||||
} VCOS_DATESTR;
|
||||
|
||||
/* Compile-time assert - declares invalid array length if condition
|
||||
* not met, or array of length one if OK.
|
||||
*/
|
||||
#define VCOS_CASSERT(e) extern char vcos_compile_time_check[1/(e)]
|
||||
|
||||
#define vcos_min(x,y) ((x) < (y) ? (x) : (y))
|
||||
#define vcos_max(x,y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
/** Return the count of an array. FIXME: under gcc we could make
|
||||
* this report an error for pointers using __builtin_types_compatible().
|
||||
*/
|
||||
#define vcos_countof(x) (sizeof((x)) / sizeof((x)[0]))
|
||||
|
||||
/* for backward compatibility */
|
||||
#define countof(x) (sizeof((x)) / sizeof((x)[0]))
|
||||
|
||||
#define VCOS_ALIGN_DOWN(p,n) (((ptrdiff_t)(p)) & ~((n)-1))
|
||||
#define VCOS_ALIGN_UP(p,n) VCOS_ALIGN_DOWN((ptrdiff_t)(p)+(n)-1,(n))
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define vcos_alignof(T) __alignof(T)
|
||||
#elif defined(__GNUC__)
|
||||
#define vcos_alignof(T) __alignof__(T)
|
||||
#else
|
||||
#define vcos_alignof(T) (sizeof(struct { T t; char ch; }) - sizeof(T))
|
||||
#endif
|
||||
|
||||
/** bool_t is not a POSIX type so cannot rely on it. Define it here.
|
||||
* It's not even defined in stdbool.h.
|
||||
*/
|
||||
typedef int32_t vcos_bool_t;
|
||||
typedef int32_t vcos_fourcc_t;
|
||||
|
||||
#define VCOS_FALSE 0
|
||||
#define VCOS_TRUE (!VCOS_FALSE)
|
||||
|
||||
/** Mark unused arguments to keep compilers quiet */
|
||||
#define vcos_unused(x) (void)(x)
|
||||
|
||||
/** For backward compatibility */
|
||||
typedef vcos_fourcc_t fourcc_t;
|
||||
typedef vcos_fourcc_t FOURCC_T;
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define VCOS_EXTERN_C_BEGIN extern "C" {
|
||||
#define VCOS_EXTERN_C_END }
|
||||
#else
|
||||
#define VCOS_EXTERN_C_BEGIN
|
||||
#define VCOS_EXTERN_C_END
|
||||
#endif
|
||||
|
||||
/** Variable attribute indicating the variable must be emitted even if it appears unused. */
|
||||
#if defined(__GNUC__) || defined(_VCOS_METAWARE)
|
||||
# define VCOS_ATTR_USED __attribute__ ((used))
|
||||
#else
|
||||
# define VCOS_ATTR_USED
|
||||
#endif
|
||||
|
||||
/** Variable attribute requiring specific alignment. */
|
||||
#if defined(__GNUC__) || defined(_VCOS_METAWARE)
|
||||
# define VCOS_ATTR_ALIGNED(n) __attribute__ ((aligned(n)))
|
||||
#else
|
||||
# define VCOS_ATTR_ALIGNED(n)
|
||||
#endif
|
||||
|
||||
/** Define a function as a weak alias to another function.
|
||||
* @param ret_type Function return type.
|
||||
* @param alias_name Name of the alias.
|
||||
* @param param_list Function parameter list, including the parentheses.
|
||||
* @param target_name Target function (bare function name, not a string).
|
||||
*/
|
||||
#if defined(__GNUC__) || defined(_VCOS_METAWARE)
|
||||
/* N.B. gcc allows __attribute__ after parameter list, but hcvc seems to silently ignore it. */
|
||||
# define VCOS_WEAK_ALIAS(ret_type, alias_name, param_list, target_name) \
|
||||
__attribute__ ((weak, alias(#target_name))) ret_type alias_name param_list
|
||||
#else
|
||||
# define VCOS_WEAK_ALIAS(ret_type, alias, params, target) VCOS_CASSERT(0)
|
||||
#endif
|
||||
|
||||
/** Define a function as a weak alias to another function, specified as a string.
|
||||
* @param ret_type Function return type.
|
||||
* @param alias_name Name of the alias.
|
||||
* @param param_list Function parameter list, including the parentheses.
|
||||
* @param target_name Target function name as a string.
|
||||
* @note Prefer the use of VCOS_WEAK_ALIAS - it is likely to be more portable.
|
||||
* Only use VCOS_WEAK_ALIAS_STR if you need to do pre-processor mangling of the target
|
||||
* symbol.
|
||||
*/
|
||||
#if defined(__GNUC__) || defined(_VCOS_METAWARE)
|
||||
/* N.B. gcc allows __attribute__ after parameter list, but hcvc seems to silently ignore it. */
|
||||
# define VCOS_WEAK_ALIAS_STR(ret_type, alias_name, param_list, target_name) \
|
||||
__attribute__ ((weak, alias(target_name))) ret_type alias_name param_list
|
||||
#else
|
||||
# define VCOS_WEAK_ALIAS_STR(ret_type, alias, params, target) VCOS_CASSERT(0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user