1
0
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:
Thomas Eichinger 2014-06-18 11:11:57 +02:00
commit 8637fe107e
7 changed files with 319 additions and 27 deletions

View File

@ -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

View File

@ -0,0 +1,4 @@
PROJECT = test_bitarithm_timings
include ../Makefile.tests_common
include $(RIOTBASE)/Makefile.include

View 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;
}

View File

@ -0,0 +1,6 @@
PROJECT = test_ipc_pingpong
include ../Makefile.tests_common
DISABLE_MODULE += auto_init
include $(RIOTBASE)/Makefile.include

View 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;
}

View 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

View File

@ -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),