Faster globals access on Sparc (part 2)

In previous post I described faster variable access for Sparc CPUs, but this approach has a problem: process need to have specific virtual address mapped in, and not used by other parts of an application. To achieve this, syscall mmap(2) with MAP_FIXED flag could be used, but it has pretty nasty feature, namely

If a MAP_FIXED request is successful, the mapping established by mmap() replaces any previous mappings for the process's pages in the range [pa, pa + len).

So we need some way to allocate address at predefined location with checks for previous mapping. Lucky enough, shmat(2) does check for overlapping mappings, so following piece of code could be used to allocate 1 page at fixed address GLOBAL_BASE:
do {
    int ps = getpagesize();
     
    int shmid = shmget(IPC_PRIVATE, ps, 0600);
    if (shmid == -1) {
      perror("shmget");
      break;
    }
    
    void\* addr = shmat(shmid, GLOBAL_BASE, 0);
    if (addr != (void\*)GLOBAL_BASE) {
      break;
    }
    
    void\* addr2 = mmap((char\*)addr, ps, PROT_READ | PROT_WRITE, 
                       MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0);
    if (addr != addr2) {
      break;
    }
    
    if (shmctl(shmid, IPC_RMID, NULL) < 0) {
      perror("shmctl");
      break;
    }
    
    return;
  } while (0);

  fatal1("cannot initialize fast globals access, check if address %p not taken",
         GLOBAL_BASE);
Another problem this approach solves, is atomicity of virtual address space mapping (especially relevant for MT applications). One could try to read /proc//maps and check if particular address space region isn't taken, but this approach is racy (no way to lock process mappings outsize of kernel, so in between another thread could potentially get the same address).
Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

nike

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today