Commit 3102c7b8 authored by Vikram Narayanan's avatar Vikram Narayanan
Browse files

aync_kernel: Move to 64-bit ffs version



Fix typecasting,assert bugs in awe_mapper
Signed-off-by: Vikram Narayanan's avatarVikram Narayanan <vikram186@gmail.com>
parent d41f9583
......@@ -37,6 +37,29 @@
#define EXPORT_SYMBOL(x)
#endif
/* Linux kernel only provides ffs variant, which operates on 32-bit registers.
* For promoting the bsf instruction to 64-bit, intel manual suggests to use
* REX.W prefix to the instruction. However, when the operands are 64-bits, gcc
* already promotes bsf to 64-bit.
*/
static __always_inline int ffsll(long long x)
{
long long r;
/*
* AMD64 says BSFL won't clobber the dest reg if x==0; Intel64 says the
* dest reg is undefined if x==0, but their CPU architect says its
* value is written to set it to the same as before, except that the
* top 32 bits will be cleared.
*
* We cannot do this on 32 bits because at the very least some
* 486 CPUs did not behave this way.
*/
asm("bsf %1,%0"
: "=r" (r)
: "rm" (x), "0" (-1));
return r + 1;
}
/*
* Initilaizes awe mapper.
......@@ -56,8 +79,11 @@ awe_mapper_init(void)
printf("No space left for awe_map_ptr\n");
return;
}
awe_map->awe_bitmap |= ~0;
#ifdef LINUX_KERNEL
awe_map->awe_bitmap = ~0UL;
#else
awe_map->awe_bitmap = ~0LL;
#endif
set_awe_map((awe_table_t*) awe_map);
}
......@@ -102,11 +128,17 @@ _awe_mapper_create_id(awe_table_t *awe_map)
{
int id;
#ifdef LINUX_KERNEL
id = ffs(awe_map->awe_bitmap);
id = ffsll(awe_map->awe_bitmap);
#elif defined(linux)
id = __builtin_ffsll(awe_map->awe_bitmap);
#endif
awe_map->awe_bitmap &= ~(1 << (id - 1));
awe_map->awe_bitmap &= ~(1LL << (id - 1));
assert(id != 0);
#ifndef NDEBUG
if (!id)
printk("%s, id %d, bitmap %016llx\n", __func__, id, awe_map->awe_bitmap);
#endif
return id;
}
......
......@@ -22,7 +22,7 @@
struct awe_table
{
awe_t awe_list[AWE_TABLE_COUNT];
unsigned long long awe_bitmap;
long long awe_bitmap;
// uint32_t used_slots;
// uint32_t next_id;
......@@ -65,7 +65,7 @@ static inline void set_awe_map(awe_table_t * map_ptr)
static inline void
_awe_mapper_remove_id(awe_table_t *awe_map, uint32_t id)
{
assert(id < AWE_TABLE_COUNT);
assert(id <= AWE_TABLE_COUNT);
assert(!(awe_map->awe_bitmap & (1 << (id - 1))));
awe_map->awe_bitmap |= (1 << (id - 1));
}
......@@ -101,7 +101,7 @@ awe_mapper_remove_id(uint32_t id)
static inline awe_t *
_awe_mapper_get_awe(awe_table_t *awe_map, uint32_t id)
{
assert(id >= AWE_TABLE_COUNT);
assert(id <= AWE_TABLE_COUNT);
return &(awe_map->awe_list[id]);
}
......
......@@ -18,6 +18,7 @@
#include "../test_helpers.h"
#define NUM_SWITCH_MEASUREMENTS 1000000
#define NUM_AWES 64
#include "./test.c"
MODULE_LICENSE("GPL");
......@@ -60,7 +61,6 @@ static int test_ctx_switch_and_thd_creation(void)
test_ctx_switch_no_dispatch_direct();
test_ctx_switch_no_dispatch_direct_trusted();
test_ctx_switch_to_awe();
test_create_awe();
#if 0
for( i = 0; i < NUM_SWITCH_MEASUREMENTS; i++ )
......
......@@ -775,7 +775,7 @@ static int test_ctx_switch_to_awe(void)
static int test_create_awe(void)
{
unsigned long t1, t2;
unsigned int id[NUM_INNER_ASYNCS];
unsigned int id[NUM_AWES];
int i;
t1 = test_fipc_start_stopwatch();
......@@ -783,10 +783,10 @@ static int test_create_awe(void)
for(i = 0; i < NUM_SWITCH_MEASUREMENTS; i++)
{
int j;
for (j = 0; j < NUM_INNER_ASYNCS; j++) {
for (j = 0; j < NUM_AWES; j++) {
awe_mapper_create_id(&id[j]);
}
for (j = 0; j < NUM_INNER_ASYNCS; j++) {
for (j = 0; j < NUM_AWES; j++) {
awe_mapper_remove_id(id[j]);
}
......@@ -794,8 +794,8 @@ static int test_create_awe(void)
t2 = test_fipc_stop_stopwatch();
printf("Average time to create and remove and awe_ids: %lu cycles\n",
(t2 - t1)/NUM_SWITCH_MEASUREMENTS);
printf("Average time to create and remove and %d awe_ids: %lu cycles\n",
NUM_AWES, (t2 - t1)/NUM_SWITCH_MEASUREMENTS);
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment