# Accessing real life registers with c

## kayve

I am hoping to access real life synchronization primitives and I am not sure how to probe and check what I can do and where to look.  I googled "atomic register" and that led me to see about this header file "atomic.h" I've sequestered a copy to look at with my nonroot user

```

#ifdef CONFIG_X86_32

# include "atomic_32.h"

#else

# include "atomic_64.h"

#endif

```

OK.  I THINK I'm 64 bit.. (but how can I be sure?? I am pretty darn sure).. so I grabbed this file:

```
            

kayve-gentoo / # cat /home/kayve/murphy/CSc720/project/c_barrier/atomic_64.h 

#ifndef _ASM_X86_ATOMIC_64_H

#define _ASM_X86_ATOMIC_64_H

#include <linux/types.h>

#include <asm/alternative.h>

#include <asm/cmpxchg.h>

/*

 * Atomic operations that C can't guarantee us.  Useful for

 * resource counting etc..

 */

#define ATOMIC_INIT(i)   { (i) }

/**

 * atomic_read - read atomic variable

 * @v: pointer of type atomic_t

 *

 * Atomically reads the value of @v.

 */

#define atomic_read(v)      ((v)->counter)

/**

 * atomic_set - set atomic variable

 * @v: pointer of type a

```

OK. I'm being silly. I feel scared now.

----------

## kayve

I really don't know exactly, but all I need is an instruction or two to access whatever is in my hardware hopefully an atomic register but perhaps I can redesign the algorithm around what I have.

```

kayve-gentoo / # cat /proc/cpuinfo 

processor   : 0

vendor_id   : GenuineIntel

cpu family   : 6

model      : 23

model name   : Intel(R) Core(TM)2 Duo CPU     T6400  @ 2.00GHz

stepping   : 10

cpu MHz      : 1200.000

cache size   : 2048 KB

physical id   : 0

siblings   : 2

core id      : 0

cpu cores   : 2

apicid      : 0

initial apicid   : 0

fdiv_bug   : no

hlt_bug      : no

f00f_bug   : no

coma_bug   : no

fpu      : yes

fpu_exception   : yes

cpuid level   : 13

wp      : yes

flags      : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs bts pni dtes64 monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm

bogomips   : 3989.34

clflush size   : 64

power management:

processor   : 1

vendor_id   : GenuineIntel

cpu family   : 6

model      : 23

model name   : Intel(R) Core(TM)2 CPU         T6400  @ 2.00GHz

stepping   : 10

cpu MHz      : 1200.000

cache size   : 2048 KB

physical id   : 0

siblings   : 2

core id      : 1

cpu cores   : 2

apicid      : 1

initial apicid   : 1

fdiv_bug   : no

hlt_bug      : no

f00f_bug   : no

coma_bug   : no

fpu      : yes

fpu_exception   : yes

cpuid level   : 13

wp      : yes

flags      : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs bts pni dtes64 monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm

bogomips   : 3989.79

clflush size   : 64

power management:

kayve-gentoo / # ls /proc

1      2      3855  4449  4659  7     950          iomem       pagetypeinfo

10     20793  388   4450  4661  7175  acpi         ioports     partitions

10346  220    389   4451  4667  7266  asound       irq         schedstat

10347  221    390   4452  4682  7287  buddyinfo    kallsyms    scsi

10366  224    3908  4453  4699  776   bus          kcore       self

1040   225    4     4454  4725  783   cgroups      key-users   slabinfo

10935  3      4077  453   4729  786   cmdline      keys        stat

10945  305    4080  458   4734  787   cpuinfo      kmsg        swaps

10946  306    4083  4587  4772  8     crypto       kpagecount  sys

10969  307    4095  459   4881  830   devices      kpageflags  sysrq-trigger

10990  312    4103  4590  5     8347  diskstats    loadavg     sysvipc

12551  317    4112  4603  6     843   dma          locks       timer_list

12554  320    4114  4604  6498  883   dri          mdstat      timer_stats

12555  3297   4229  4611  656   884   driver       meminfo     tty

13     3298   4380  4614  659   9     execdomains  misc        uptime

15129  3360   4392  4629  662   905   fb           modules     version

16     3552   441   4637  665   906   filesystems  mounts      vmallocinfo

17150  3773   4413  4647  668   9118  fs           mtrr        vmstat

19561  3854   442   4649  671   9137  interrupts   net         zoneinfo

kayve-gentoo / # cat /proc/version

Linux version 2.6.30-gentoo-r8 (root@kayve-laptop) (gcc version 4.3.4 (Gentoo 4.3.4 p1.0, pie-10.1.5) ) #1 SMP Wed Nov 18 21:14:23 PST 2009

kayve-gentoo / # cat /proc/meminfo

MemTotal:        2975328 kB

MemFree:         1990060 kB

Buffers:           84856 kB

Cached:           427304 kB

SwapCached:            0 kB

Active:           640040 kB

Inactive:         284260 kB

Active(anon):     518612 kB

Inactive(anon):        8 kB

Active(file):     121428 kB

Inactive(file):   284252 kB

Unevictable:           8 kB

Mlocked:               8 kB

HighTotal:       2098504 kB

HighFree:        1251328 kB

LowTotal:         876824 kB

LowFree:          738732 kB

SwapTotal:       1060280 kB

SwapFree:        1060280 kB

Dirty:                 0 kB

Writeback:             0 kB

AnonPages:        412148 kB

Mapped:           110076 kB

Slab:              47400 kB

SReclaimable:      34636 kB

SUnreclaim:        12764 kB

PageTables:         2928 kB

NFS_Unstable:          0 kB

Bounce:                0 kB

WritebackTmp:          0 kB

CommitLimit:     2547944 kB

Committed_AS:     964900 kB

VmallocTotal:     122880 kB

VmallocUsed:       10116 kB

VmallocChunk:     112100 kB

HugePages_Total:       0

HugePages_Free:        0

HugePages_Rsvd:        0

HugePages_Surp:        0

Hugepagesize:       4096 kB

DirectMap4k:       16376 kB

DirectMap4M:      892928 kB

kayve-gentoo / # cat /proc/locks

1: POSIX  ADVISORY  WRITE 10366 08:03:1441885 0 EOF

2: POSIX  ADVISORY  WRITE 3552 08:03:1417268 1073741824 1073742335

3: POSIX  ADVISORY  WRITE 3552 08:03:1417260 0 EOF

4: POSIX  ADVISORY  WRITE 10366 08:03:1534173 0 EOF

5: POSIX  ADVISORY  WRITE 10366 08:03:1796414 0 EOF

6: POSIX  ADVISORY  WRITE 10366 08:03:1794303 0 EOF

7: POSIX  ADVISORY  READ  10366 08:03:18473387 0 EOF

8: POSIX  ADVISORY  READ  10366 08:03:18835594 0 EOF

9: POSIX  ADVISORY  READ  10366 08:03:18473362 0 EOF

10: POSIX  ADVISORY  READ  10366 08:03:18473385 0 EOF

11: POSIX  ADVISORY  READ  10366 08:03:18835593 0 EOF

12: POSIX  ADVISORY  WRITE 4772 08:03:1441852 1073741824 1073742335

13: POSIX  ADVISORY  WRITE 4772 08:03:1441866 1073741824 1073742335

14: POSIX  ADVISORY  WRITE 4772 08:03:1441847 0 EOF

15: FLOCK  ADVISORY  WRITE 4228 08:03:18129154 0 EOF

```

----------

## theotherjoe

Some time ago I was playing around with lockfree data structures

and ran into the following article about atomic operations being

part of the current GCC. Not sure when those were included (4.1?)

but I tested some using gcc-4.3 and worked as expected:

http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html

NB. the gcc.gnu.org server seems to be down currently.

----------

## kayve

I haven't tried to implement the atomic stuff yet.. but I tried to include the header file, both by 

```

#include <atomic.h>

```

and 

```

#include "atomic.h"

```

WIth the file copied to the current working directory.. it didn't compile:

```

kayve@kayve-gentoo ~/murphy/CSc720/project/c_barrier $ gcc -o calc_pi calc_pi.c

In file included from atomic.h:4,

                 from calc_pi.c:3:

atomic_64.h:5:29: error: asm/alternative.h: No such file or directory

atomic_64.h:6:25: error: asm/cmpxchg.h: No such file or directory

In file included from atomic.h:4,

                 from calc_pi.c:3:

atomic_64.h:39: error: expected declaration specifiers or '...' before 'atomic_t'

atomic_64.h: In function 'atomic_add':

atomic_64.h:41: error: expected string literal before 'LOCK_PREFIX'

atomic_64.h: At top level:

atomic_64.h:53: error: expected declaration specifiers or '...' before 'atomic_t'

atomic_64.h: In function 'atomic_sub':

atomic_64.h:55: error: expected string literal before 'LOCK_PREFIX'

atomic_64.h: At top level:

atomic_64.h:69: error: expected declaration specifiers or '...' before 'atomic_t'

atomic_64.h: In function 'atomic_sub_and_test':

atomic_64.h:73: error: expected string literal before 'LOCK_PREFIX'

atomic_64.h: At top level:

atomic_64.h:85: error: expected ')' before '*' token

atomic_64.h:98: error: expected ')' before '*' token

atomic_64.h:113: error: expected ')' before '*' token

atomic_64.h:131: error: expected ')' before '*' token

atomic_64.h:150: error: expected declaration specifiers or '...' before 'atomic_t'

atomic_64.h: In function 'atomic_add_negative':

atomic_64.h:154: error: expected string literal before 'LOCK_PREFIX'

atomic_64.h: At top level:

atomic_64.h:167: error: expected declaration specifiers or '...' before 'atomic_t'

atomic_64.h: In function 'atomic_add_return':

atomic_64.h:170: error: expected string literal before 'LOCK_PREFIX'

atomic_64.h: At top level:

atomic_64.h:176: error: expected declaration specifiers or '...' before 'atomic_t'

atomic_64.h: In function 'atomic_sub_return':

atomic_64.h:178: error: 'v' undeclared (first use in this function)

atomic_64.h:178: error: (Each undeclared identifier is reported only once

atomic_64.h:178: error: for each function it appears in.)

atomic_64.h:178: error: too many arguments to function 'atomic_add_return'

atomic_64.h: At top level:

atomic_64.h:213: error: expected declaration specifiers or '...' before 'atomic64_t'

atomic_64.h: In function 'atomic64_add':

atomic_64.h:215: error: expected string literal before 'LOCK_PREFIX'

atomic_64.h: At top level:

atomic_64.h:227: error: expected declaration specifiers or '...' before 'atomic64_t'

atomic_64.h: In function 'atomic64_sub':

atomic_64.h:229: error: expected string literal before 'LOCK_PREFIX'

atomic_64.h: At top level:

atomic_64.h:243: error: expected declaration specifiers or '...' before 'atomic64_t'

atomic_64.h: In function 'atomic64_sub_and_test':

atomic_64.h:247: error: expected string literal before 'LOCK_PREFIX'

atomic_64.h: At top level:

atomic_64.h:259: error: expected ')' before '*' token

atomic_64.h:272: error: expected ')' before '*' token

atomic_64.h:287: error: expected ')' before '*' token

atomic_64.h:305: error: expected ')' before '*' token

atomic_64.h:324: error: expected declaration specifiers or '...' before 'atomic64_t'

atomic_64.h: In function 'atomic64_add_negative':

atomic_64.h:328: error: expected string literal before 'LOCK_PREFIX'

atomic_64.h: At top level:

atomic_64.h:341: error: expected declaration specifiers or '...' before 'atomic64_t'

atomic_64.h: In function 'atomic64_add_return':

atomic_64.h:344: error: expected string literal before 'LOCK_PREFIX'

atomic_64.h: At top level:

atomic_64.h:350: error: expected declaration specifiers or '...' before 'atomic64_t'

atomic_64.h: In function 'atomic64_sub_return':

atomic_64.h:352: error: 'v' undeclared (first use in this function)

atomic_64.h:352: error: too many arguments to function 'atomic64_add_return'

atomic_64.h: At top level:

atomic_64.h:373: error: expected ')' before '*' token

atomic_64.h:399: error: expected ')' before '*' token

atomic_64.h: In function 'atomic_inc_short':

atomic_64.h:423: error: expected string literal before 'LOCK_PREFIX'

atomic_64.h: In function 'atomic_or_long':

atomic_64.h:437: error: expected string literal before 'LOCK_PREFIX'

atomic_64.h:458:32: error: asm-generic/atomic.h: No such file or directory

calc_pi.c: In function 'main':

calc_pi.c:19: warning: format not a string literal and no format arguments

calc_pi.c:20: warning: passing argument 1 of 'perror' from incompatible pointer type

calc_pi.c:22: warning: format '%d' expects type 'int', but argument 2 has type '__time_t'

calc_pi.c:23: warning: format '%d' expects type 'int', but argument 2 has type 'long int'

kayve@kayve-gentoo ~/murphy/CSc720/project/c_barrier $ cat calc_pi.c 

#include <stdio.h>

#include <stdlib.h>

#include "atomic.h"

#include <time.h>

#include <pthread.h>

#define THOUSAND 1000L

#define MILLION 1000000L

#define BILLION 1000000000L

int main (int argc, char *argv[]) {

  struct timespec t_res, t_begin, t_end;

  char *msg_buf[256];

  if (clock_getres(CLOCK_REALTIME, &t_res)) {

    sprintf("%s: failed to get clock resolution\0",argv[0]);

    perror(&msg_buf[0]);

  }

  printf("second resolution: %d", t_res.tv_sec);

  printf("nanosecond resolution: %d", t_res.tv_nsec);

}

stb_await() {

```

----------

## kayve

```

kayve@kayve-gentoo ~/murphy/CSc720/project/c_barrier $ gcc -v

Using built-in specs.

Target: i686-pc-linux-gnu

Configured with: /var/tmp/portage/sys-devel/gcc-4.3.4/work/gcc-4.3.4/configure --prefix=/usr --bindir=/usr/i686-pc-linux-gnu/gcc-bin/4.3.4 --includedir=/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include --datadir=/usr/share/gcc-data/i686-pc-linux-gnu/4.3.4 --mandir=/usr/share/gcc-data/i686-pc-linux-gnu/4.3.4/man --infodir=/usr/share/gcc-data/i686-pc-linux-gnu/4.3.4/info --with-gxx-include-dir=/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4 --host=i686-pc-linux-gnu --build=i686-pc-linux-gnu --disable-altivec --disable-fixed-point --enable-nls --without-included-gettext --with-system-zlib --disable-checking --disable-werror --enable-secureplt --disable-multilib --enable-libmudflap --disable-libssp --enable-libgomp --disable-libgcj --with-arch=i686 --enable-languages=c,c++,treelang,fortran --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --with-bugurl=http://bugs.gentoo.org/ --with-pkgversion='Gentoo 4.3.4 p1.0, pie-10.1.5'

Thread model: posix

gcc version 4.3.4 (Gentoo 4.3.4 p1.0, pie-10.1.5) 

kayve@kayve-gentoo ~/murphy/CSc720/project/c_barrier $ 

```

----------

## kayve

I don't know how to use this function atomic_dec_and_test(atomic_t*v)

```

4 

35 stb_await() {

36    atomic_t *v;

37    atomic_dec_and_test(v);

38 }

calc_pi.c:36: error: 'v' undeclared (first use in this function)

kayve@kayve-gentoo ~/murphy/CSc720/project/c_barrier $ gcc -I/usr/src/linux-2.6.30-gentoo-r8/arch/x86/include/ -lrt -o calc_pi calc_pi.c

In file included from /usr/src/linux-2.6.30-gentoo-r8/arch/x86/include/asm/atomic_64.h:5,

                 from /usr/src/linux-2.6.30-gentoo-r8/arch/x86/include/asm/atomic.h:4,

                 from calc_pi.c:3:

/usr/src/linux-2.6.30-gentoo-r8/arch/x86/include/asm/alternative.h:45: error: expected specifier-qualifier-list before 'u8'

In file included from /usr/src/linux-2.6.30-gentoo-r8/arch/x86/include/asm/atomic.h:4,

```

----------

