mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-29 00:11:16 +01:00
Merge pull request #975 from Kijewski/issue-974
core: change in bitarithm implementation
This commit is contained in:
commit
8637fe107e
@ -15,47 +15,36 @@
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bitarithm.h"
|
||||
|
||||
unsigned bitarithm_msb(unsigned v)
|
||||
{
|
||||
register unsigned r; // result of log2(v) will go here
|
||||
|
||||
#if ARCH_32_BIT
|
||||
register unsigned shift;
|
||||
|
||||
r = (v > 0xFFFF) << 4; v >>= r;
|
||||
shift = (v > 0xFF ) << 3; v >>= shift; r |= shift;
|
||||
shift = (v > 0xF ) << 2; v >>= shift; r |= shift;
|
||||
shift = (v > 0x3 ) << 1; v >>= shift; r |= shift;
|
||||
r |= (v >> 1);
|
||||
#else
|
||||
r = 0;
|
||||
while (v >>= 1) { // unroll for more speed...
|
||||
r++;
|
||||
if ((signed) v >= 0) {
|
||||
v &= -v;
|
||||
return bitarithm_lsb(v);
|
||||
}
|
||||
else {
|
||||
return sizeof (v) * 8 - 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
unsigned bitarithm_lsb(register unsigned v)
|
||||
{
|
||||
register unsigned r = 0;
|
||||
|
||||
while ((v & 0x01) == 0) {
|
||||
unsigned bitarithm_lsb(unsigned v)
|
||||
{
|
||||
unsigned r = 0;
|
||||
while ((v & 1) == 0) {
|
||||
v >>= 1;
|
||||
r++;
|
||||
};
|
||||
|
||||
}
|
||||
return r;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
unsigned bitarithm_bits_set(unsigned v)
|
||||
{
|
||||
unsigned c; // c accumulates the total bits set in v
|
||||
|
||||
4
tests/test_bitarithm_timings/Makefile
Normal file
4
tests/test_bitarithm_timings/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
PROJECT = test_bitarithm_timings
|
||||
include ../Makefile.tests_common
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
87
tests/test_bitarithm_timings/main.c
Normal file
87
tests/test_bitarithm_timings/main.c
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2014 René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Measure the speed of the function in bitarithm.c
|
||||
*
|
||||
* @author René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bitarithm.h"
|
||||
#include "hwtimer.h"
|
||||
|
||||
#define TIMEOUT_S (5)
|
||||
#define TIMEOUT_US (TIMEOUT_S * 1000 * 1000)
|
||||
#define TIMEOUT (HWTIMER_TICKS(TIMEOUT_US))
|
||||
#define PER_ITERATION (4)
|
||||
|
||||
static void callback(void *done_)
|
||||
{
|
||||
volatile int *done = done_;
|
||||
*done = 1;
|
||||
}
|
||||
|
||||
static void run_test(const char *name, unsigned (*test)(unsigned))
|
||||
{
|
||||
volatile int done = 0;
|
||||
unsigned i = 0;
|
||||
unsigned long count = 0;
|
||||
|
||||
hwtimer_set(TIMEOUT, callback, (void *) &done);
|
||||
do {
|
||||
if (i++ == -1u) {
|
||||
i = 1;
|
||||
}
|
||||
|
||||
volatile unsigned r;
|
||||
for (unsigned j = 0; j < PER_ITERATION; ++j) {
|
||||
r = test(i);
|
||||
r = test(-1u - i);
|
||||
r = test(~i);
|
||||
r = test(~(-1u - i));
|
||||
}
|
||||
(void) r;
|
||||
|
||||
++count;
|
||||
} while (done == 0);
|
||||
|
||||
printf("+ %s: %lu iterations per second\r\n", name, (4*PER_ITERATION) * count / TIMEOUT_S);
|
||||
}
|
||||
|
||||
#define run_test(test) run_test(#test, test)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Start.\r\n");
|
||||
|
||||
run_test(bitarithm_msb);
|
||||
run_test(bitarithm_lsb);
|
||||
run_test(bitarithm_bits_set);
|
||||
|
||||
printf("Done.\r\n");
|
||||
return 0;
|
||||
}
|
||||
6
tests/test_ipc_pingpong/Makefile
Normal file
6
tests/test_ipc_pingpong/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
PROJECT = test_ipc_pingpong
|
||||
include ../Makefile.tests_common
|
||||
|
||||
DISABLE_MODULE += auto_init
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
112
tests/test_ipc_pingpong/main.c
Normal file
112
tests/test_ipc_pingpong/main.c
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief IPC pingpong test
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* @author René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "thread.h"
|
||||
#include "msg.h"
|
||||
#include "kernel.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#define LIMIT 1000
|
||||
|
||||
static char stacks[3][KERNEL_CONF_STACKSIZE_MAIN];
|
||||
static int pids[3];
|
||||
|
||||
static void first_thread(void)
|
||||
{
|
||||
puts("1st starting.");
|
||||
for (unsigned i = 0; i < LIMIT; ++i) {
|
||||
msg_t m;
|
||||
m.content.value = i;
|
||||
msg_send_receive(&m, &m, pids[1]);
|
||||
|
||||
DEBUG("%u: Got msg with content %i\n", i, m.content.value);
|
||||
if (m.content.value != i + 1) {
|
||||
puts("ERROR. 1st");
|
||||
return;
|
||||
}
|
||||
}
|
||||
puts("1st done.");
|
||||
}
|
||||
|
||||
static void second_thread(void)
|
||||
{
|
||||
puts("2nd starting.");
|
||||
while (1) {
|
||||
msg_t m1;
|
||||
msg_receive(&m1);
|
||||
DEBUG("2nd: got msg from %i: %i\n", m1.sender_pid, m1.content.value);
|
||||
|
||||
msg_t m2;
|
||||
m2.content.value = m1.content.value + 1;
|
||||
msg_send_receive(&m2, &m2, pids[2]);
|
||||
if (m2.content.value != m1.content.value) {
|
||||
puts("ERROR. 2nd");
|
||||
return;
|
||||
}
|
||||
|
||||
++m1.content.value;
|
||||
msg_reply(&m1, &m1);
|
||||
if (m1.content.value == LIMIT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
puts("2nd done.");
|
||||
}
|
||||
|
||||
static void third_thread(void)
|
||||
{
|
||||
puts("3rd starting.");
|
||||
while (1) {
|
||||
msg_t m;
|
||||
msg_receive(&m);
|
||||
DEBUG("3rd: got msg from %i: %i\n", m.sender_pid, m.content.value);
|
||||
|
||||
--m.content.value;
|
||||
msg_reply(&m, &m);
|
||||
|
||||
if (m.content.value == LIMIT - 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
puts("3rd done.");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
puts("Main thread start.");
|
||||
|
||||
pids[0] = thread_create(stacks[0], sizeof (stacks[0]),
|
||||
PRIORITY_MAIN - 1, CREATE_WOUT_YIELD | CREATE_STACKTEST,
|
||||
first_thread, "1st");
|
||||
pids[1] = thread_create(stacks[1], sizeof (stacks[1]),
|
||||
PRIORITY_MAIN - 2, CREATE_WOUT_YIELD | CREATE_STACKTEST,
|
||||
second_thread, "2nd");
|
||||
pids[2] = thread_create(stacks[2], sizeof (stacks[2]),
|
||||
PRIORITY_MAIN - 3, CREATE_WOUT_YIELD | CREATE_STACKTEST,
|
||||
third_thread, "3nd");
|
||||
|
||||
puts("Main thread done.");
|
||||
return 0;
|
||||
}
|
||||
73
tests/test_ipc_pingpong/tests/01-test
Executable file
73
tests/test_ipc_pingpong/tests/01-test
Executable file
@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env expect
|
||||
|
||||
set pid [spawn make term]
|
||||
puts "-*- Spawened $pid -*-\n"
|
||||
|
||||
set result 0
|
||||
|
||||
set timeout 5
|
||||
if { $result == 0 } {
|
||||
expect {
|
||||
"Main thread start." {}
|
||||
timeout { set result 1 }
|
||||
}
|
||||
}
|
||||
|
||||
set timeout 1
|
||||
if { $result == 0 } {
|
||||
expect {
|
||||
"Main thread done." {}
|
||||
timeout { set result 1 }
|
||||
}
|
||||
}
|
||||
if { $result == 0 } {
|
||||
expect {
|
||||
"3rd starting." {}
|
||||
timeout { set result 1 }
|
||||
}
|
||||
}
|
||||
if { $result == 0 } {
|
||||
expect {
|
||||
"2nd starting." {}
|
||||
timeout { set result 1 }
|
||||
}
|
||||
}
|
||||
if { $result == 0 } {
|
||||
expect {
|
||||
"1st starting." {}
|
||||
timeout { set result 1 }
|
||||
}
|
||||
}
|
||||
|
||||
set timeout 10
|
||||
if { $result == 0 } {
|
||||
expect {
|
||||
"3rd done." {}
|
||||
timeout { set result 1 }
|
||||
}
|
||||
}
|
||||
set timeout 1
|
||||
if { $result == 0 } {
|
||||
expect {
|
||||
"2nd done." {}
|
||||
timeout { set result 1 }
|
||||
}
|
||||
}
|
||||
if { $result == 0 } {
|
||||
expect {
|
||||
"1st done." {}
|
||||
timeout { set result 1 }
|
||||
}
|
||||
}
|
||||
|
||||
if { $result == 0 } {
|
||||
puts "\n-*- Test successful! -*-\n"
|
||||
} else {
|
||||
puts "\n-*- TEST HAD ERRORS! -*-\n"
|
||||
}
|
||||
spawn kill -15 $pid
|
||||
sleep 1
|
||||
spawn kill -9 $pid
|
||||
wait
|
||||
close
|
||||
exit $result
|
||||
@ -157,6 +157,13 @@ static void test_bitarithm_msb_random(void)
|
||||
dice roll ;-) */
|
||||
}
|
||||
|
||||
static void test_bitarithm_msb_all(void)
|
||||
{
|
||||
for (unsigned shift = 0; shift < sizeof (unsigned) * 8 - 1; ++shift) {
|
||||
TEST_ASSERT_EQUAL_INT(shift, bitarithm_msb(1 << shift));
|
||||
}
|
||||
}
|
||||
|
||||
static void test_bitarithm_lsb_one(void)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_INT(0, bitarithm_lsb(1));
|
||||
@ -164,7 +171,8 @@ static void test_bitarithm_lsb_one(void)
|
||||
|
||||
static void test_bitarithm_lsb_limit(void)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_INT(0, bitarithm_lsb(UINT_MAX));
|
||||
unsigned shift = sizeof (unsigned) * 8 - 1;
|
||||
TEST_ASSERT_EQUAL_INT(shift, bitarithm_lsb(1u << shift));
|
||||
}
|
||||
|
||||
static void test_bitarithm_lsb_random(void)
|
||||
@ -173,6 +181,13 @@ static void test_bitarithm_lsb_random(void)
|
||||
dice roll ;-) */
|
||||
}
|
||||
|
||||
static void test_bitarithm_lsb_all(void)
|
||||
{
|
||||
for (unsigned shift = 0; shift < sizeof (unsigned) * 8 - 1; ++shift) {
|
||||
TEST_ASSERT_EQUAL_INT(shift, bitarithm_lsb(1u << shift));
|
||||
}
|
||||
}
|
||||
|
||||
static void test_bitarithm_bits_set_null(void)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_INT(0, bitarithm_bits_set(0));
|
||||
@ -205,6 +220,7 @@ Test *tests_core_bitarithm_tests(void)
|
||||
new_TestFixture(test_SETBIT_null_one),
|
||||
new_TestFixture(test_SETBIT_one_null),
|
||||
new_TestFixture(test_SETBIT_one_random),
|
||||
|
||||
new_TestFixture(test_CLRBIT_null_null),
|
||||
new_TestFixture(test_CLRBIT_null_limit),
|
||||
new_TestFixture(test_CLRBIT_limit_null),
|
||||
@ -212,12 +228,17 @@ Test *tests_core_bitarithm_tests(void)
|
||||
new_TestFixture(test_CLRBIT_null_one),
|
||||
new_TestFixture(test_CLRBIT_one_null),
|
||||
new_TestFixture(test_CLRBIT_one_random),
|
||||
|
||||
new_TestFixture(test_bitarithm_msb_one),
|
||||
new_TestFixture(test_bitarithm_msb_limit),
|
||||
new_TestFixture(test_bitarithm_msb_random),
|
||||
new_TestFixture(test_bitarithm_msb_all),
|
||||
|
||||
new_TestFixture(test_bitarithm_lsb_one),
|
||||
new_TestFixture(test_bitarithm_lsb_limit),
|
||||
new_TestFixture(test_bitarithm_lsb_random),
|
||||
new_TestFixture(test_bitarithm_lsb_all),
|
||||
|
||||
new_TestFixture(test_bitarithm_bits_set_null),
|
||||
new_TestFixture(test_bitarithm_bits_set_one),
|
||||
new_TestFixture(test_bitarithm_bits_set_limit),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user