Skip to content

Instantly share code, notes, and snippets.

@Arseny-N
Created November 11, 2014 19:29
Show Gist options
  • Save Arseny-N/840607bdc8f88b7941df to your computer and use it in GitHub Desktop.
Save Arseny-N/840607bdc8f88b7941df to your computer and use it in GitHub Desktop.
Casts to anonymus structures
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef char s8;
struct byte {
u8 b0:1;
u8 b1:1;
u8 b2:1;
u8 b3:1;
u8 b4:1;
u8 b5:1;
u8 b6:1;
u8 b7:1;
};
#define nn_cast(var, body) (( struct body __attribute__ ((packed)) *) &(var))
#define where(scope, body) ({ struct scope this; void __fn__ body; __fn__(); &this; })
int main ( int argc, char * argv [] )
{
u8 array[] = {
0xff,
0xaa,
0xaa,
0xfa
};
u16 aa = (
(
struct {
u8 one;
u16 two;
u8 three;
} __attribute__ ((packed)) *
)
(void*)&array
) -> two;
u8 aa2 = nn_cast(array, {
u8 garbadge[3];
u8 delicious_byte;
})->delicious_byte;
u8 bit4 = nn_cast(array, {
u8 garbadge[3];
struct byte byte;
})->byte.b4;
u16 v = *((u16 *)nn_cast(array, {
u16 wired_filed:10;
})), v2 = nn_cast(array, {
u16 wired_filed:10;
})->wired_filed;
{
u8 vvvar;
vvvar = 22;
};
u8 d = where({
u8 a;
},{
this.a = 4;
})->a;
printf("%4d %4x %4x %4x\n", sizeof(struct byte), aa, aa2, bit4);
printf("%4x %4x\n", v, v2);
printf("%4x\n", d);
printf(" %4x\n", *((u32*)array));
return 0;
}
Can't set required sheduling policy, proceeding with default.
Oops, sounds bad - results might be compromised.
-- NTIMES: 1048576
-- NNTIMES: 2048
-- 6194486 byte mask
-- 6478781 byte cast
-- 6477362 byte cast with fileds
-- NTIMES: 1048576
-- NNTIMES: 2048
-- 6245994 byte mask
-- 6518088 byte cast
-- 6522689 byte cast with fileds
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long u64;
typedef char s8;
typedef short s16;
typedef int s32;
typedef long s64;
typedef void (*run_test_t)(void);
#define lambda(rtype, body) ({ rtype __fn__ body; __fn__; })
#define __cast(var, body, what) (( what body __attribute__ ((packed)) *) &(var))
#define st_cast(var, body) __cast(var, body, struct)
#define un_cast(var, body) __cast(var, body, union)
#define en_cast(var, body) __cast(var, body, enum)
#define NTIMES 1048576
#define NNTIMES 2048
#define asm_comment(s) // __asm__(" ; "s) /* Breaks code */
#define execute(op, op_asm) op
//#define execute(op, op_asm) __asm__(op_asm)
u64 rdtsc(void)
{
u32 lo,hi;
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
return ((u64)hi << 32) | lo;
}
inline u64 start_timer(void)
{
return rdtsc();
}
inline u64 stop_timer(u64 timerid)
{
u64 curr = rdtsc();
return curr > timerid ? curr - timerid : __LONG_MAX__ - timerid + curr;
}
int set_max_prio(int policy)
{
pid_t pid = getpid();
struct sched_param sp;
int max_prio = sched_get_priority_max(policy);
if(max_prio == -1) {
fprintf(stderr, "Can't get max prio, proceeding with default prio and sheduling policy.\n");
return -1;
}
sp.sched_priority = max_prio;
if ( sched_setscheduler ( pid, policy, &sp ) == -1 ) {
fprintf(stderr, "Can't set required sheduling policy, proceeding with default.\n");
return -1;
}
return 0;
}
int main ( int argc, char * argv [] )
{
u8 byte_mask, byte_cast, byte_cast2;
u32 var = 0xDEADC0FE;
u64 timerid, time;
int i, j;
struct {
char *name;
run_test_t test;
u64 cycles;
} tests[] = {
{
.name = "byte mask",
.test = lambda(void, (){
int i;
for(i=0; i<NTIMES; ++i) {
execute( byte_mask = (var & 0xff00) >> 8,
"movl -8(%rbp), %eax\n"
"andl $65280, %eax\n"
"shrl $8, %eax\n"
"movb %al, -1(%rbp)\n");
}
})
},{
.name = "byte cast",
.test = lambda(void, (){
int i;
for(i=0; i<NTIMES; ++i)
execute( byte_cast = st_cast(var, {
u8 dummy;
u8 value;
})->value,
"leaq -8(%rbp), %rax\n"
"movzbl 1(%rax), %eax\n"
"movb %al, -3(%rbp)\n" );
})
},{
.name = "byte cast with fileds",
.test = lambda(void, (){
int i;
for(i=0; i<NTIMES; ++i)
execute(byte_cast2 = st_cast(var, {
u16 dummy:8;
u16 value:8;
})->value,
"leaq -8(%rbp), %rax\n"
"movzbl 1(%rax), %eax\n"
"movb %al, -4(%rbp)\n");
})
},
};
size_t size = sizeof(tests)/sizeof(tests[0]);
if(set_max_prio(SCHED_FIFO) == -1)
fprintf(stderr, "Oops, sounds bad - results might be compromised.\n");
for(j=0; j < NNTIMES; ++j) {
for(i=0; i<size; ++i) {
timerid = start_timer();
tests[i].test();
tests[i].cycles += stop_timer(timerid);
}
}
printf("\n -- NTIMES: %d\n -- NNTIMES: %d\n", NTIMES, NNTIMES);
for(i=0; i<size; ++i)
printf(" -- %d %s\n", tests[i].cycles/NNTIMES, tests[i].name);
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment