Created
November 11, 2014 19:29
-
-
Save Arseny-N/840607bdc8f88b7941df to your computer and use it in GitHub Desktop.
Casts to anonymus structures
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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