mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Merge pull request #13333 from gpsimenos/gp-events-restruct
Events directory restructuringpull/13306/head
						commit
						f20f93a648
					
				| 
						 | 
				
			
			@ -19,6 +19,7 @@
 | 
			
		|||
^features/unsupported/
 | 
			
		||||
^hal/storage_abstraction
 | 
			
		||||
^platform/cxxsupport
 | 
			
		||||
^events/tests/UNITTESTS
 | 
			
		||||
^rtos/source/TARGET_CORTEX/rtx4
 | 
			
		||||
^rtos/source/TARGET_CORTEX/rtx5
 | 
			
		||||
^targets
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,7 +100,8 @@ matrix:
 | 
			
		|||
        - |
 | 
			
		||||
          ! git grep '^#include\s["'"']mbed.h['"'"]$' -- '*.c' '*.h' '*.cpp' '*.hpp' \
 | 
			
		||||
              ':!*platform_mbed.h' ':!*TESTS/*' ':!TEST_APPS/' ':!UNITTESTS/' \
 | 
			
		||||
              ':!*tests/*' ':!*targets/*' ':!*TARGET_*' ':!*unsupported/*'
 | 
			
		||||
              ':!*tests/*' ':!*targets/*' ':!*TARGET_*' ':!*unsupported/*' \
 | 
			
		||||
              ':!*events/tests/*'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ### Docs Tests ###
 | 
			
		||||
| 
						 | 
				
			
			@ -252,10 +253,8 @@ matrix:
 | 
			
		|||
            connectivity/libraries/ppp connectivity/netsocket features/nanostack features/lwipstack features/frameworks/greentea-client \
 | 
			
		||||
            features/frameworks/utest features/frameworks/unity components BUILD
 | 
			
		||||
        - python tools/make.py -t GCC_ARM -m NUCLEO_F103RB --source=. --build=BUILD/NUCLEO_F103RB/GCC_ARM -j0
 | 
			
		||||
        # Run local equeue tests
 | 
			
		||||
        - make -C ${EVENTS}/source test
 | 
			
		||||
        # Run profiling tests
 | 
			
		||||
        - make -C ${EVENTS}/source prof | tee prof
 | 
			
		||||
        - make -C ${EVENTS}/tests/unit prof | tee prof
 | 
			
		||||
      after_success:
 | 
			
		||||
        # Update status, comparing with master if possible.
 | 
			
		||||
        - |
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,7 @@
 | 
			
		|||
#include "stdint.h"
 | 
			
		||||
#include "stdlib.h"
 | 
			
		||||
#include "USBEndpointTester.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
#include "EndpointResolver.h"
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_CONFIGURATION       (1)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@
 | 
			
		|||
/* These headers are included for child class. */
 | 
			
		||||
#include "USBDescriptor.h"
 | 
			
		||||
#include "USBDevice_Types.h"
 | 
			
		||||
#include "EventQueue.h"
 | 
			
		||||
#include "events/EventQueue.h"
 | 
			
		||||
#include "EventFlags.h"
 | 
			
		||||
#include "platform/NonCopyable.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,7 @@
 | 
			
		|||
 | 
			
		||||
#include "stdint.h"
 | 
			
		||||
#include "USBTester.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
#include "EndpointResolver.h"
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_CONFIGURATION (1)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@
 | 
			
		|||
/* These headers are included for child class. */
 | 
			
		||||
#include "USBDescriptor.h"
 | 
			
		||||
#include "USBDevice_Types.h"
 | 
			
		||||
#include "EventQueue.h"
 | 
			
		||||
#include "events/EventQueue.h"
 | 
			
		||||
#include "EventFlags.h"
 | 
			
		||||
#include "platform/NonCopyable.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -103,8 +103,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNITTEST")
 | 
			
		|||
# Set include dirs.
 | 
			
		||||
set(unittest-includes-base
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/target_h"
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/target_h/events"
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/target_h/events/equeue"
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/../events/tests/UNITTESTS/target_h"
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/../events/tests/UNITTESTS/target_h/equeue"
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/target_h/platform"
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/target_h/platform/cxxsupport"
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/target_h/drivers"
 | 
			
		||||
| 
						 | 
				
			
			@ -122,9 +122,9 @@ set(unittest-includes-base
 | 
			
		|||
  "${PROJECT_SOURCE_DIR}/../storage/kvstore/kv_config/include"
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/../drivers"
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/../hal"
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/../events"
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/../events/include"
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/../events/include/events/internal"
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/../events/source"
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/../events/internal"
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/../rtos/include"
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/../features/frameworks"
 | 
			
		||||
  "${PROJECT_SOURCE_DIR}/../features/frameworks/mbed-trace"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,27 +0,0 @@
 | 
			
		|||
 | 
			
		||||
####################
 | 
			
		||||
# UNIT TESTS
 | 
			
		||||
####################
 | 
			
		||||
 | 
			
		||||
list(REMOVE_ITEM unittest-includes ${PROJECT_SOURCE_DIR}/target_h/events ${PROJECT_SOURCE_DIR}/target_h/events/equeue)
 | 
			
		||||
 | 
			
		||||
set(unittest-includes ${unittest-includes}
 | 
			
		||||
  ../events/source
 | 
			
		||||
  ../events
 | 
			
		||||
  ../events/internal
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
set(unittest-sources
 | 
			
		||||
  ../events/source/equeue.c
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
set(unittest-test-sources
 | 
			
		||||
  events/equeue/test_equeue.cpp
 | 
			
		||||
  stubs/EqueuePosix_stub.c
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
set(unittest-test-flags
 | 
			
		||||
  -pthread
 | 
			
		||||
  -DEQUEUE_PLATFORM_POSIX
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +15,7 @@
 | 
			
		|||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "equeue.h"
 | 
			
		||||
#include "events/equeue.h"
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "equeue_stub.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,7 @@
 | 
			
		|||
#include "CellularUtil.h"
 | 
			
		||||
#include "CellularLog.h"
 | 
			
		||||
#include "events/EventQueue.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
 | 
			
		||||
namespace mbed {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,7 @@
 | 
			
		|||
#include "mbed_interface.h"
 | 
			
		||||
#include "mbed_assert.h"
 | 
			
		||||
#include "netsocket/nsapi_types.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
 | 
			
		||||
using namespace std::chrono;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,7 +23,7 @@
 | 
			
		|||
#include "mbed_wait_api.h"
 | 
			
		||||
#include "mbed_assert.h"
 | 
			
		||||
#include "netsocket/nsapi_types.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
 | 
			
		||||
#include "smsc9220_emac.h"
 | 
			
		||||
#include "smsc9220_eth_drv.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,7 @@
 | 
			
		|||
#include "scl_emac.h"
 | 
			
		||||
#include "lwip/etharp.h"
 | 
			
		||||
#include "lwip/ethip6.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
#include "scl_buffer_api.h"
 | 
			
		||||
#include "cy_result.h"
 | 
			
		||||
#include "cy_pdl.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,7 @@
 | 
			
		|||
#include "whd_emac.h"
 | 
			
		||||
#include "lwip/etharp.h"
 | 
			
		||||
#include "lwip/ethip6.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
#include "whd_wlioctl.h"
 | 
			
		||||
#include "whd_buffer_api.h"
 | 
			
		||||
#include "cybsp_wifi.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,7 +40,7 @@
 | 
			
		|||
#include "mbed_interface.h"
 | 
			
		||||
#include "mbed_assert.h"
 | 
			
		||||
#include "netsocket/nsapi_types.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
 | 
			
		||||
#include "fsl_phy.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@
 | 
			
		|||
 | 
			
		||||
#include "mbed_interface.h"
 | 
			
		||||
#include "mbed_assert.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
#include "netsocket/nsapi_types.h"
 | 
			
		||||
 | 
			
		||||
#include "gd32xx_emac.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,7 +28,7 @@
 | 
			
		|||
#include "mbed_interface.h"
 | 
			
		||||
#include "mbed_assert.h"
 | 
			
		||||
#include "netsocket/nsapi_types.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
 | 
			
		||||
//#define NU_TRACE
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,7 +40,7 @@
 | 
			
		|||
#include "mbed_interface.h"
 | 
			
		||||
#include "mbed_assert.h"
 | 
			
		||||
#include "netsocket/nsapi_types.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
 | 
			
		||||
#include "fsl_phy.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,7 @@
 | 
			
		|||
#include "mbed_interface.h"
 | 
			
		||||
#include "mbed_assert.h"
 | 
			
		||||
#include "netsocket/nsapi_types.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
 | 
			
		||||
#include "fsl_phy.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,7 +18,7 @@
 | 
			
		|||
#include "cmsis_os.h"
 | 
			
		||||
#include "mbed_interface.h"
 | 
			
		||||
#include "mbed_assert.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
#include "netsocket/nsapi_types.h"
 | 
			
		||||
#include "lwip/arch.h"
 | 
			
		||||
#include "lwip/pbuf.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,7 @@
 | 
			
		|||
#include "cmsis_os.h"
 | 
			
		||||
#include "rtos/ThisThread.h"
 | 
			
		||||
#include "netsocket/nsapi_types.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
#include "rza1_eth.h"
 | 
			
		||||
#include "rza1_eth_ext.h"
 | 
			
		||||
#include "rza1_emac.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,7 @@
 | 
			
		|||
#include "mbed.h"
 | 
			
		||||
#include "mbed_interface.h"
 | 
			
		||||
#include "mbed_assert.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
#include "netsocket/nsapi_types.h"
 | 
			
		||||
 | 
			
		||||
#include "stm32xx_emac_config.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,10 +22,10 @@
 | 
			
		|||
#include "netsocket/nsapi_types.h"
 | 
			
		||||
 | 
			
		||||
#if PPP_MBED_EVENT_QUEUE
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
#else
 | 
			
		||||
#include "Thread.h"
 | 
			
		||||
#include "EventQueue.h"
 | 
			
		||||
#include "events/EventQueue.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "mbed_poll.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,7 @@
 | 
			
		|||
#include "mbed_interface.h"
 | 
			
		||||
#include "mbed_trace.h"
 | 
			
		||||
#include "netsocket/nsapi_types.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
#include "mbed_poll.h"
 | 
			
		||||
#include "ip4string.h"
 | 
			
		||||
#include "ip6string.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,7 @@
 | 
			
		|||
#include "stddef.h"
 | 
			
		||||
#include <new>
 | 
			
		||||
#include "events/EventQueue.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
#include "platform/mbed_error.h"
 | 
			
		||||
 | 
			
		||||
// Default NetworkStack operations
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,7 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
#include "events/EventQueue.h"
 | 
			
		||||
#include "netsocket/OnboardNetworkStack.h"
 | 
			
		||||
#include "rtos/Kernel.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@
 | 
			
		|||
#include "netsocket/SocketAddress.h"
 | 
			
		||||
#include "EMAC_mock.h"
 | 
			
		||||
#include "OnboardNetworkStack_mock.h"
 | 
			
		||||
#include "EventQueue.h"
 | 
			
		||||
#include "events/EventQueue.h"
 | 
			
		||||
#include <future>
 | 
			
		||||
#include <thread>
 | 
			
		||||
#include <chrono>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,7 @@
 | 
			
		|||
#include "ByteBuffer.h"
 | 
			
		||||
#include "Mutex.h"
 | 
			
		||||
#include "EventFlags.h"
 | 
			
		||||
#include "EventQueue.h"
 | 
			
		||||
#include "events/EventQueue.h"
 | 
			
		||||
#include "Thread.h"
 | 
			
		||||
#include "Callback.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
tests/*
 | 
			
		||||
| 
						 | 
				
			
			@ -1,902 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Testing framework for the events library
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2016 ARM Limited
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#include "events/equeue.h"
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <setjmp.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Testing setup
 | 
			
		||||
static jmp_buf test_buf;
 | 
			
		||||
static int test_line;
 | 
			
		||||
static int test_failure;
 | 
			
		||||
 | 
			
		||||
#define test_assert(test) ({                                                \
 | 
			
		||||
    if (!(test)) {                                                          \
 | 
			
		||||
        test_line = __LINE__;                                               \
 | 
			
		||||
        longjmp(test_buf, 1);                                               \
 | 
			
		||||
    }                                                                       \
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
#define test_run(func, ...) ({                                              \
 | 
			
		||||
    printf("%s: ...", #func);                                               \
 | 
			
		||||
    fflush(stdout);                                                         \
 | 
			
		||||
                                                                            \
 | 
			
		||||
    if (!setjmp(test_buf)) {                                                \
 | 
			
		||||
        func(__VA_ARGS__);                                                  \
 | 
			
		||||
        printf("\r%s: \e[32mpassed\e[0m\n", #func);                         \
 | 
			
		||||
    } else {                                                                \
 | 
			
		||||
        printf("\r%s: \e[31mfailed\e[0m at line %d\n", #func, test_line);   \
 | 
			
		||||
        test_failure = true;                                                \
 | 
			
		||||
    }                                                                       \
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Test functions
 | 
			
		||||
void pass_func(void *eh)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void simple_func(void *p)
 | 
			
		||||
{
 | 
			
		||||
    (*(int *)p)++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sloth_func(void *p)
 | 
			
		||||
{
 | 
			
		||||
    usleep(10000);
 | 
			
		||||
    (*(int *)p)++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct indirect {
 | 
			
		||||
    int *touched;
 | 
			
		||||
    uint8_t buffer[7];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void indirect_func(void *p)
 | 
			
		||||
{
 | 
			
		||||
    struct indirect *i = (struct indirect *)p;
 | 
			
		||||
    (*i->touched)++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct timing {
 | 
			
		||||
    unsigned tick;
 | 
			
		||||
    unsigned delay;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void timing_func(void *p)
 | 
			
		||||
{
 | 
			
		||||
    struct timing *timing = (struct timing *)p;
 | 
			
		||||
    unsigned tick = equeue_tick();
 | 
			
		||||
 | 
			
		||||
    unsigned t1 = timing->delay;
 | 
			
		||||
    unsigned t2 = tick - timing->tick;
 | 
			
		||||
    test_assert(t1 > t2 - 10 && t1 < t2 + 10);
 | 
			
		||||
 | 
			
		||||
    timing->tick = tick;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct fragment {
 | 
			
		||||
    equeue_t *q;
 | 
			
		||||
    size_t size;
 | 
			
		||||
    struct timing timing;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void fragment_func(void *p)
 | 
			
		||||
{
 | 
			
		||||
    struct fragment *fragment = (struct fragment *)p;
 | 
			
		||||
    timing_func(&fragment->timing);
 | 
			
		||||
 | 
			
		||||
    struct fragment *nfragment = equeue_alloc(fragment->q, fragment->size);
 | 
			
		||||
    test_assert(nfragment);
 | 
			
		||||
 | 
			
		||||
    *nfragment = *fragment;
 | 
			
		||||
    equeue_event_delay(nfragment, fragment->timing.delay);
 | 
			
		||||
 | 
			
		||||
    int id = equeue_post(nfragment->q, fragment_func, nfragment);
 | 
			
		||||
    test_assert(id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct cancel {
 | 
			
		||||
    equeue_t *q;
 | 
			
		||||
    int id;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void cancel_func(void *p)
 | 
			
		||||
{
 | 
			
		||||
    struct cancel *cancel = (struct cancel *)p;
 | 
			
		||||
    equeue_cancel(cancel->q, cancel->id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct nest {
 | 
			
		||||
    equeue_t *q;
 | 
			
		||||
    void (*cb)(void *);
 | 
			
		||||
    void *data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void nest_func(void *p)
 | 
			
		||||
{
 | 
			
		||||
    struct nest *nest = (struct nest *)p;
 | 
			
		||||
    equeue_call(nest->q, nest->cb, nest->data);
 | 
			
		||||
 | 
			
		||||
    usleep(10000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Simple call tests
 | 
			
		||||
void simple_call_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    bool touched = false;
 | 
			
		||||
    equeue_call(&q, simple_func, &touched);
 | 
			
		||||
    equeue_dispatch(&q, 0);
 | 
			
		||||
    test_assert(touched);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void simple_call_in_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    bool touched = false;
 | 
			
		||||
    int id = equeue_call_in(&q, 10, simple_func, &touched);
 | 
			
		||||
    test_assert(id);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 15);
 | 
			
		||||
    test_assert(touched);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void simple_call_every_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    bool touched = false;
 | 
			
		||||
    int id = equeue_call_every(&q, 10, simple_func, &touched);
 | 
			
		||||
    test_assert(id);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 15);
 | 
			
		||||
    test_assert(touched);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void simple_post_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    int touched = false;
 | 
			
		||||
    struct indirect *i = equeue_alloc(&q, sizeof(struct indirect));
 | 
			
		||||
    test_assert(i);
 | 
			
		||||
 | 
			
		||||
    i->touched = &touched;
 | 
			
		||||
    int id = equeue_post(&q, indirect_func, i);
 | 
			
		||||
    test_assert(id);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 0);
 | 
			
		||||
    test_assert(*i->touched);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Misc tests
 | 
			
		||||
void destructor_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    int touched;
 | 
			
		||||
    struct indirect *e;
 | 
			
		||||
    int ids[3];
 | 
			
		||||
 | 
			
		||||
    touched = 0;
 | 
			
		||||
    for (int i = 0; i < 3; i++) {
 | 
			
		||||
        e = equeue_alloc(&q, sizeof(struct indirect));
 | 
			
		||||
        test_assert(e);
 | 
			
		||||
 | 
			
		||||
        e->touched = &touched;
 | 
			
		||||
        equeue_event_dtor(e, indirect_func);
 | 
			
		||||
        int id = equeue_post(&q, pass_func, e);
 | 
			
		||||
        test_assert(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 0);
 | 
			
		||||
    test_assert(touched == 3);
 | 
			
		||||
 | 
			
		||||
    touched = 0;
 | 
			
		||||
    for (int i = 0; i < 3; i++) {
 | 
			
		||||
        e = equeue_alloc(&q, sizeof(struct indirect));
 | 
			
		||||
        test_assert(e);
 | 
			
		||||
 | 
			
		||||
        e->touched = &touched;
 | 
			
		||||
        equeue_event_dtor(e, indirect_func);
 | 
			
		||||
        ids[i] = equeue_post(&q, pass_func, e);
 | 
			
		||||
        test_assert(ids[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < 3; i++) {
 | 
			
		||||
        equeue_cancel(&q, ids[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 0);
 | 
			
		||||
    test_assert(touched == 3);
 | 
			
		||||
 | 
			
		||||
    touched = 0;
 | 
			
		||||
    for (int i = 0; i < 3; i++) {
 | 
			
		||||
        e = equeue_alloc(&q, sizeof(struct indirect));
 | 
			
		||||
        test_assert(e);
 | 
			
		||||
 | 
			
		||||
        e->touched = &touched;
 | 
			
		||||
        equeue_event_dtor(e, indirect_func);
 | 
			
		||||
        int id = equeue_post(&q, pass_func, e);
 | 
			
		||||
        test_assert(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
    test_assert(touched == 3);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void allocation_failure_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    void *p = equeue_alloc(&q, 4096);
 | 
			
		||||
    test_assert(!p);
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < 100; i++) {
 | 
			
		||||
        p = equeue_alloc(&q, 0);
 | 
			
		||||
    }
 | 
			
		||||
    test_assert(!p);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cancel_test(int N)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    bool touched = false;
 | 
			
		||||
    int *ids = malloc(N * sizeof(int));
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
        ids[i] = equeue_call(&q, simple_func, &touched);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (int i = N - 1; i >= 0; i--) {
 | 
			
		||||
        test_assert(equeue_cancel(&q, ids[i]));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    free(ids);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 0);
 | 
			
		||||
    test_assert(!touched);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cancel_inflight_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    bool touched = false;
 | 
			
		||||
 | 
			
		||||
    int id = equeue_call(&q, simple_func, &touched);
 | 
			
		||||
    test_assert(equeue_cancel(&q, id));
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 0);
 | 
			
		||||
    test_assert(!touched);
 | 
			
		||||
 | 
			
		||||
    id = equeue_call(&q, simple_func, &touched);
 | 
			
		||||
    test_assert(equeue_cancel(&q, id));
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 0);
 | 
			
		||||
    test_assert(!touched);
 | 
			
		||||
 | 
			
		||||
    struct cancel *cancel = equeue_alloc(&q, sizeof(struct cancel));
 | 
			
		||||
    test_assert(cancel);
 | 
			
		||||
    cancel->q = &q;
 | 
			
		||||
    cancel->id = 0;
 | 
			
		||||
 | 
			
		||||
    id = equeue_post(&q, cancel_func, cancel);
 | 
			
		||||
    test_assert(id);
 | 
			
		||||
 | 
			
		||||
    cancel->id = equeue_call(&q, simple_func, &touched);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 0);
 | 
			
		||||
    test_assert(!touched);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cancel_unnecessarily_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    int id = equeue_call(&q, pass_func, 0);
 | 
			
		||||
    for (int i = 0; i < 5; i++) {
 | 
			
		||||
        test_assert(equeue_cancel(&q, id) == (i == 0));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    id = equeue_call(&q, pass_func, 0);
 | 
			
		||||
    equeue_dispatch(&q, 0);
 | 
			
		||||
    for (int i = 0; i < 5; i++) {
 | 
			
		||||
        test_assert(!equeue_cancel(&q, id));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool touched = false;
 | 
			
		||||
    equeue_call(&q, simple_func, &touched);
 | 
			
		||||
    for (int i = 0; i < 5; i++) {
 | 
			
		||||
        test_assert(!equeue_cancel(&q, id));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 0);
 | 
			
		||||
    test_assert(touched);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void loop_protect_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    bool touched = false;
 | 
			
		||||
    equeue_call_every(&q, 0, simple_func, &touched);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 0);
 | 
			
		||||
    test_assert(touched);
 | 
			
		||||
 | 
			
		||||
    touched = false;
 | 
			
		||||
    equeue_call_every(&q, 1, simple_func, &touched);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 0);
 | 
			
		||||
    test_assert(touched);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void break_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    bool touched = false;
 | 
			
		||||
    equeue_call_every(&q, 0, simple_func, &touched);
 | 
			
		||||
 | 
			
		||||
    equeue_break(&q);
 | 
			
		||||
    equeue_dispatch(&q, -1);
 | 
			
		||||
    test_assert(touched);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void break_no_windup_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    int count = 0;
 | 
			
		||||
    equeue_call_every(&q, 0, simple_func, &count);
 | 
			
		||||
 | 
			
		||||
    equeue_break(&q);
 | 
			
		||||
    equeue_break(&q);
 | 
			
		||||
    equeue_dispatch(&q, -1);
 | 
			
		||||
    test_assert(count == 1);
 | 
			
		||||
 | 
			
		||||
    count = 0;
 | 
			
		||||
    equeue_dispatch(&q, 55);
 | 
			
		||||
    test_assert(count > 1);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void period_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    int count = 0;
 | 
			
		||||
    equeue_call_every(&q, 10, simple_func, &count);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 55);
 | 
			
		||||
    test_assert(count == 5);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nested_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    int touched = 0;
 | 
			
		||||
    struct nest *nest = equeue_alloc(&q, sizeof(struct nest));
 | 
			
		||||
    test_assert(nest);
 | 
			
		||||
    nest->q = &q;
 | 
			
		||||
    nest->cb = simple_func;
 | 
			
		||||
    nest->data = &touched;
 | 
			
		||||
 | 
			
		||||
    int id = equeue_post(&q, nest_func, nest);
 | 
			
		||||
    test_assert(id);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 5);
 | 
			
		||||
    test_assert(touched == 0);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 5);
 | 
			
		||||
    test_assert(touched == 1);
 | 
			
		||||
 | 
			
		||||
    touched = 0;
 | 
			
		||||
    nest = equeue_alloc(&q, sizeof(struct nest));
 | 
			
		||||
    test_assert(nest);
 | 
			
		||||
    nest->q = &q;
 | 
			
		||||
    nest->cb = simple_func;
 | 
			
		||||
    nest->data = &touched;
 | 
			
		||||
 | 
			
		||||
    id = equeue_post(&q, nest_func, nest);
 | 
			
		||||
    test_assert(id);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 20);
 | 
			
		||||
    test_assert(touched == 1);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sloth_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    int touched = 0;
 | 
			
		||||
    int id = equeue_call(&q, sloth_func, &touched);
 | 
			
		||||
    test_assert(id);
 | 
			
		||||
 | 
			
		||||
    id = equeue_call_in(&q, 5, simple_func, &touched);
 | 
			
		||||
    test_assert(id);
 | 
			
		||||
 | 
			
		||||
    id = equeue_call_in(&q, 15, simple_func, &touched);
 | 
			
		||||
    test_assert(id);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 20);
 | 
			
		||||
    test_assert(touched == 3);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *multithread_thread(void *p)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t *q = (equeue_t *)p;
 | 
			
		||||
    equeue_dispatch(q, -1);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void multithread_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    int touched = 0;
 | 
			
		||||
    equeue_call_every(&q, 1, simple_func, &touched);
 | 
			
		||||
 | 
			
		||||
    pthread_t thread;
 | 
			
		||||
    err = pthread_create(&thread, 0, multithread_thread, &q);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    usleep(10000);
 | 
			
		||||
    equeue_break(&q);
 | 
			
		||||
    err = pthread_join(thread, 0);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    test_assert(touched);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void background_func(void *p, int ms)
 | 
			
		||||
{
 | 
			
		||||
    *(unsigned *)p = ms;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void background_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    int id = equeue_call_in(&q, 20, pass_func, 0);
 | 
			
		||||
    test_assert(id);
 | 
			
		||||
 | 
			
		||||
    unsigned ms;
 | 
			
		||||
    equeue_background(&q, background_func, &ms);
 | 
			
		||||
    test_assert(ms == 20);
 | 
			
		||||
 | 
			
		||||
    id = equeue_call_in(&q, 10, pass_func, 0);
 | 
			
		||||
    test_assert(id);
 | 
			
		||||
    test_assert(ms == 10);
 | 
			
		||||
 | 
			
		||||
    id = equeue_call(&q, pass_func, 0);
 | 
			
		||||
    test_assert(id);
 | 
			
		||||
    test_assert(ms == 0);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 0);
 | 
			
		||||
    test_assert(ms == 10);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
    test_assert(ms == -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void chain_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q1;
 | 
			
		||||
    int err = equeue_create(&q1, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    equeue_t q2;
 | 
			
		||||
    err = equeue_create(&q2, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    equeue_chain(&q2, &q1);
 | 
			
		||||
 | 
			
		||||
    int touched = 0;
 | 
			
		||||
 | 
			
		||||
    int id1 = equeue_call_in(&q1, 20, simple_func, &touched);
 | 
			
		||||
    int id2 = equeue_call_in(&q2, 20, simple_func, &touched);
 | 
			
		||||
    test_assert(id1 && id2);
 | 
			
		||||
 | 
			
		||||
    id1 = equeue_call(&q1, simple_func, &touched);
 | 
			
		||||
    id2 = equeue_call(&q2, simple_func, &touched);
 | 
			
		||||
    test_assert(id1 && id2);
 | 
			
		||||
 | 
			
		||||
    id1 = equeue_call_in(&q1, 5, simple_func, &touched);
 | 
			
		||||
    id2 = equeue_call_in(&q2, 5, simple_func, &touched);
 | 
			
		||||
    test_assert(id1 && id2);
 | 
			
		||||
 | 
			
		||||
    test_assert(equeue_cancel(&q1, id1));
 | 
			
		||||
    test_assert(equeue_cancel(&q2, id2));
 | 
			
		||||
 | 
			
		||||
    id1 = equeue_call_in(&q1, 10, simple_func, &touched);
 | 
			
		||||
    id2 = equeue_call_in(&q2, 10, simple_func, &touched);
 | 
			
		||||
    test_assert(id1 && id2);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q1, 30);
 | 
			
		||||
 | 
			
		||||
    test_assert(touched == 6);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q2);
 | 
			
		||||
    equeue_destroy(&q1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void unchain_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q1;
 | 
			
		||||
    int err = equeue_create(&q1, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    equeue_t q2;
 | 
			
		||||
    err = equeue_create(&q2, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    equeue_chain(&q2, &q1);
 | 
			
		||||
 | 
			
		||||
    int touched = 0;
 | 
			
		||||
    int id1 = equeue_call(&q1, simple_func, &touched);
 | 
			
		||||
    int id2 = equeue_call(&q2, simple_func, &touched);
 | 
			
		||||
    test_assert(id1 && id2);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q1, 0);
 | 
			
		||||
    test_assert(touched == 2);
 | 
			
		||||
 | 
			
		||||
    equeue_chain(&q2, 0);
 | 
			
		||||
    equeue_chain(&q1, &q2);
 | 
			
		||||
 | 
			
		||||
    id1 = equeue_call(&q1, simple_func, &touched);
 | 
			
		||||
    id2 = equeue_call(&q2, simple_func, &touched);
 | 
			
		||||
    test_assert(id1 && id2);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q2, 0);
 | 
			
		||||
    test_assert(touched == 4);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q1);
 | 
			
		||||
    equeue_destroy(&q2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Barrage tests
 | 
			
		||||
void simple_barrage_test(int N)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, N * (EQUEUE_EVENT_SIZE + sizeof(struct timing)));
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
        struct timing *timing = equeue_alloc(&q, sizeof(struct timing));
 | 
			
		||||
        test_assert(timing);
 | 
			
		||||
 | 
			
		||||
        timing->tick = equeue_tick();
 | 
			
		||||
        timing->delay = (i + 1) * 100;
 | 
			
		||||
        equeue_event_delay(timing, timing->delay);
 | 
			
		||||
        equeue_event_period(timing, timing->delay);
 | 
			
		||||
 | 
			
		||||
        int id = equeue_post(&q, timing_func, timing);
 | 
			
		||||
        test_assert(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, N * 100);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void fragmenting_barrage_test(int N)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q,
 | 
			
		||||
                            2 * N * (EQUEUE_EVENT_SIZE + sizeof(struct fragment) + N * sizeof(int)));
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
        size_t size = sizeof(struct fragment) + i * sizeof(int);
 | 
			
		||||
        struct fragment *fragment = equeue_alloc(&q, size);
 | 
			
		||||
        test_assert(fragment);
 | 
			
		||||
 | 
			
		||||
        fragment->q = &q;
 | 
			
		||||
        fragment->size = size;
 | 
			
		||||
        fragment->timing.tick = equeue_tick();
 | 
			
		||||
        fragment->timing.delay = (i + 1) * 100;
 | 
			
		||||
        equeue_event_delay(fragment, fragment->timing.delay);
 | 
			
		||||
 | 
			
		||||
        int id = equeue_post(&q, fragment_func, fragment);
 | 
			
		||||
        test_assert(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, N * 100);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct ethread {
 | 
			
		||||
    pthread_t thread;
 | 
			
		||||
    equeue_t *q;
 | 
			
		||||
    int ms;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void *ethread_dispatch(void *p)
 | 
			
		||||
{
 | 
			
		||||
    struct ethread *t = (struct ethread *)p;
 | 
			
		||||
    equeue_dispatch(t->q, t->ms);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void multithreaded_barrage_test(int N)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, N * (EQUEUE_EVENT_SIZE + sizeof(struct timing)));
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    struct ethread t;
 | 
			
		||||
    t.q = &q;
 | 
			
		||||
    t.ms = N * 100;
 | 
			
		||||
    err = pthread_create(&t.thread, 0, ethread_dispatch, &t);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
        struct timing *timing = equeue_alloc(&q, sizeof(struct timing));
 | 
			
		||||
        test_assert(timing);
 | 
			
		||||
 | 
			
		||||
        timing->tick = equeue_tick();
 | 
			
		||||
        timing->delay = (i + 1) * 100;
 | 
			
		||||
        equeue_event_delay(timing, timing->delay);
 | 
			
		||||
        equeue_event_period(timing, timing->delay);
 | 
			
		||||
 | 
			
		||||
        int id = equeue_post(&q, timing_func, timing);
 | 
			
		||||
        test_assert(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    err = pthread_join(t.thread, 0);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct count_and_queue {
 | 
			
		||||
    int p;
 | 
			
		||||
    equeue_t *q;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void simple_breaker(void *p)
 | 
			
		||||
{
 | 
			
		||||
    struct count_and_queue *caq = (struct count_and_queue *)p;
 | 
			
		||||
    equeue_break(caq->q);
 | 
			
		||||
    usleep(10000);
 | 
			
		||||
    caq->p++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void break_request_cleared_on_timeout(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 2048);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    struct count_and_queue pq;
 | 
			
		||||
    pq.p = 0;
 | 
			
		||||
    pq.q = &q;
 | 
			
		||||
 | 
			
		||||
    int id = equeue_call_every(&q, 10, simple_breaker, &pq);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 10);
 | 
			
		||||
    test_assert(pq.p == 1);
 | 
			
		||||
 | 
			
		||||
    test_assert(equeue_cancel(&q, id));
 | 
			
		||||
 | 
			
		||||
    int count = 0;
 | 
			
		||||
    equeue_call_every(&q, 10, simple_func, &count);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 55);
 | 
			
		||||
    test_assert(count > 1);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sibling_test(void)
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 1024);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    int id0 = equeue_call_in(&q, 1, pass_func, 0);
 | 
			
		||||
    int id1 = equeue_call_in(&q, 1, pass_func, 0);
 | 
			
		||||
    int id2 = equeue_call_in(&q, 1, pass_func, 0);
 | 
			
		||||
 | 
			
		||||
    struct equeue_event *e = q.queue;
 | 
			
		||||
 | 
			
		||||
    for (; e; e = e->next) {
 | 
			
		||||
        for (struct equeue_event *s = e->sibling; s; s = s->sibling) {
 | 
			
		||||
            test_assert(!s->next);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    test_assert(equeue_cancel(&q, id0));
 | 
			
		||||
    test_assert(equeue_cancel(&q, id1));
 | 
			
		||||
    test_assert(equeue_cancel(&q, id2));
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct user_allocated_event {
 | 
			
		||||
    struct equeue_event e;
 | 
			
		||||
    bool touched;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void user_allocated_event_test()
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, EQUEUE_EVENT_SIZE);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    bool touched = false;
 | 
			
		||||
    struct user_allocated_event e1 = { { 0, 0, 0, NULL, NULL, NULL, 0, -1, NULL, NULL }, 0 };
 | 
			
		||||
    struct user_allocated_event e2 = { { 0, 0, 0, NULL, NULL, NULL, 1, -1, NULL, NULL }, 0 };
 | 
			
		||||
    struct user_allocated_event e3 = { { 0, 0, 0, NULL, NULL, NULL, 1, -1, NULL, NULL }, 0 };
 | 
			
		||||
    struct user_allocated_event e4 = { { 0, 0, 0, NULL, NULL, NULL, 1, -1, NULL, NULL }, 0 };
 | 
			
		||||
    struct user_allocated_event e5 = { { 0, 0, 0, NULL, NULL, NULL, 0, -1, NULL, NULL }, 0 };
 | 
			
		||||
 | 
			
		||||
    test_assert(0 != equeue_call(&q, simple_func, &touched));
 | 
			
		||||
    test_assert(0 == equeue_call(&q, simple_func, &touched));
 | 
			
		||||
    test_assert(0 == equeue_call(&q, simple_func, &touched));
 | 
			
		||||
 | 
			
		||||
    equeue_post_user_allocated(&q, simple_func, &e1.e);
 | 
			
		||||
    equeue_post_user_allocated(&q, simple_func, &e2.e);
 | 
			
		||||
    equeue_post_user_allocated(&q, simple_func, &e3.e);
 | 
			
		||||
    equeue_post_user_allocated(&q, simple_func, &e4.e);
 | 
			
		||||
    equeue_post_user_allocated(&q, simple_func, &e5.e);
 | 
			
		||||
    test_assert(equeue_cancel_user_allocated(&q, &e3.e));
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 1);
 | 
			
		||||
 | 
			
		||||
    test_assert(true == touched);
 | 
			
		||||
    test_assert(true == e1.touched);
 | 
			
		||||
    test_assert(true == e2.touched);
 | 
			
		||||
    test_assert(false == e3.touched);
 | 
			
		||||
    test_assert(true == e4.touched);
 | 
			
		||||
    test_assert(true == e5.touched);
 | 
			
		||||
 | 
			
		||||
    equeue_dispatch(&q, 10);
 | 
			
		||||
 | 
			
		||||
    test_assert(true == touched);
 | 
			
		||||
    test_assert(true == e1.touched);
 | 
			
		||||
    test_assert(true == e2.touched);
 | 
			
		||||
    test_assert(false == e3.touched);
 | 
			
		||||
    test_assert(true == e4.touched);
 | 
			
		||||
    test_assert(true == e5.touched);
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void id_cycle()
 | 
			
		||||
{
 | 
			
		||||
    equeue_t q;
 | 
			
		||||
    int err = equeue_create(&q, 10000000);
 | 
			
		||||
    test_assert(!err);
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < 300; i++) {
 | 
			
		||||
        int id = equeue_call(&q, pass_func, 0);
 | 
			
		||||
        test_assert(id != 0);
 | 
			
		||||
        test_assert(equeue_cancel(&q, id));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    equeue_destroy(&q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    printf("beginning tests...\n");
 | 
			
		||||
 | 
			
		||||
    test_run(simple_call_test);
 | 
			
		||||
    test_run(simple_call_in_test);
 | 
			
		||||
    test_run(simple_call_every_test);
 | 
			
		||||
    test_run(simple_post_test);
 | 
			
		||||
    test_run(destructor_test);
 | 
			
		||||
    test_run(allocation_failure_test);
 | 
			
		||||
    test_run(cancel_test, 20);
 | 
			
		||||
    test_run(cancel_inflight_test);
 | 
			
		||||
    test_run(cancel_unnecessarily_test);
 | 
			
		||||
    test_run(loop_protect_test);
 | 
			
		||||
    test_run(break_test);
 | 
			
		||||
    test_run(break_no_windup_test);
 | 
			
		||||
    test_run(period_test);
 | 
			
		||||
    test_run(nested_test);
 | 
			
		||||
    test_run(sloth_test);
 | 
			
		||||
    test_run(background_test);
 | 
			
		||||
    test_run(chain_test);
 | 
			
		||||
    test_run(unchain_test);
 | 
			
		||||
    test_run(multithread_test);
 | 
			
		||||
    test_run(simple_barrage_test, 20);
 | 
			
		||||
    test_run(fragmenting_barrage_test, 20);
 | 
			
		||||
    test_run(multithreaded_barrage_test, 20);
 | 
			
		||||
    test_run(break_request_cleared_on_timeout);
 | 
			
		||||
    test_run(sibling_test);
 | 
			
		||||
    test_run(user_allocated_event_test);
 | 
			
		||||
    test_run(id_cycle);
 | 
			
		||||
    printf("done!\n");
 | 
			
		||||
    return test_failure;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
UNITTESTS/*
 | 
			
		||||
unit/
 | 
			
		||||
| 
						 | 
				
			
			@ -23,7 +23,7 @@
 | 
			
		|||
#include "unity/unity.h"
 | 
			
		||||
#include "greentea-client/test_env.h"
 | 
			
		||||
 | 
			
		||||
#include "equeue.h"
 | 
			
		||||
#include "events/equeue.h"
 | 
			
		||||
#include "mbed.h"
 | 
			
		||||
 | 
			
		||||
using namespace utest::v1;
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +15,7 @@
 | 
			
		|||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#include "gtest/gtest.h"
 | 
			
		||||
#include "equeue.h"
 | 
			
		||||
#include "events/equeue.h"
 | 
			
		||||
#include "mbed.h"
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
 | 
			
		||||
####################
 | 
			
		||||
# UNIT TESTS
 | 
			
		||||
####################
 | 
			
		||||
 | 
			
		||||
list(REMOVE_ITEM unittest-includes ${PROJECT_SOURCE_DIR}/../events/tests/UNITTESTS/target_h ${PROJECT_SOURCE_DIR}/../events/test/UNITTESTS/target_h/equeue)
 | 
			
		||||
 | 
			
		||||
set(unittest-includes ${unittest-includes}
 | 
			
		||||
  ../events/source
 | 
			
		||||
  ../events/include/events
 | 
			
		||||
  ../events/include/events/internal
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
set(unittest-sources
 | 
			
		||||
  ../events/source/equeue.c
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
set(unittest-test-sources
 | 
			
		||||
  ../events/tests/UNITTESTS/equeue/test_equeue.cpp
 | 
			
		||||
  ../events/tests/UNITTESTS/stubs/EqueuePosix_stub.c
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
set(unittest-test-flags
 | 
			
		||||
  -pthread
 | 
			
		||||
  -DEQUEUE_PLATFORM_POSIX
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ CC = gcc
 | 
			
		|||
AR = ar
 | 
			
		||||
SIZE = size
 | 
			
		||||
 | 
			
		||||
SRC += $(wildcard *.c)
 | 
			
		||||
SRC += $(wildcard ../../source/*.c)
 | 
			
		||||
OBJ := $(SRC:.c=.o)
 | 
			
		||||
DEP := $(SRC:.c=.d)
 | 
			
		||||
ASM := $(SRC:.c=.s)
 | 
			
		||||
| 
						 | 
				
			
			@ -17,7 +17,7 @@ endif
 | 
			
		|||
ifdef WORD
 | 
			
		||||
CFLAGS += -m$(WORD)
 | 
			
		||||
endif
 | 
			
		||||
CFLAGS += -I. -I.. -I../..
 | 
			
		||||
CFLAGS += -I. -I../../include
 | 
			
		||||
CFLAGS += -std=c99
 | 
			
		||||
CFLAGS += -Wall
 | 
			
		||||
CFLAGS += -D_XOPEN_SOURCE=600
 | 
			
		||||
| 
						 | 
				
			
			@ -27,13 +27,9 @@ LFLAGS += -pthread
 | 
			
		|||
 | 
			
		||||
all: $(TARGET)
 | 
			
		||||
 | 
			
		||||
test: tests/tests.o $(OBJ)
 | 
			
		||||
	$(CC) $(CFLAGS) $^ $(LFLAGS) -o tests/tests
 | 
			
		||||
	tests/tests
 | 
			
		||||
 | 
			
		||||
prof: tests/prof.o $(OBJ)
 | 
			
		||||
	$(CC) $(CFLAGS) $^ $(LFLAGS) -o tests/prof
 | 
			
		||||
	tests/prof
 | 
			
		||||
prof: prof.o $(OBJ)
 | 
			
		||||
	$(CC) $(CFLAGS) $^ $(LFLAGS) -o prof
 | 
			
		||||
	./prof
 | 
			
		||||
 | 
			
		||||
asm: $(ASM)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -53,8 +49,7 @@ size: $(OBJ)
 | 
			
		|||
 | 
			
		||||
clean:
 | 
			
		||||
	rm -f $(TARGET)
 | 
			
		||||
	rm -f tests/tests tests/tests.o tests/tests.d
 | 
			
		||||
	rm -f tests/prof tests/prof.o tests/prof.d
 | 
			
		||||
	rm -f prof prof.o prof.d
 | 
			
		||||
	rm -f $(OBJ)
 | 
			
		||||
	rm -f $(DEP)
 | 
			
		||||
	rm -f $(ASM)
 | 
			
		||||
| 
						 | 
				
			
			@ -24,9 +24,9 @@
 | 
			
		|||
#include "platform/SingletonPtr.h"
 | 
			
		||||
#include "platform/arm_hal_interrupt.h"
 | 
			
		||||
#include "platform/mbed_power_mgmt.h"
 | 
			
		||||
#include "equeue.h"
 | 
			
		||||
#include "events/equeue.h"
 | 
			
		||||
#include "events/EventQueue.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
#include "Timeout.h"
 | 
			
		||||
 | 
			
		||||
#define TRACE_GROUP "fhdr"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,7 +27,7 @@
 | 
			
		|||
#include "eventOS_scheduler.h"
 | 
			
		||||
 | 
			
		||||
#include "mbed_error.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "events/mbed_shared_queues.h"
 | 
			
		||||
#include "events/Event.h"
 | 
			
		||||
#include "ns_event_loop_mutex.h"
 | 
			
		||||
#include "ns_event_loop.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue