Commit | Line | Data |
---|---|---|
646d19a4 BVA |
1 | #ifndef CONFIG_NO_SHM |
2 | /* | |
3 | * Bionic doesn't support SysV shared memory, so implement it using ashmem | |
4 | */ | |
5 | #include <stdio.h> | |
6 | #include <linux/ashmem.h> | |
7 | #include <linux/shm.h> | |
8 | #include <android/api-level.h> | |
d9705059 | 9 | #ifdef CONFIG_ASHAREDMEMORY_CREATE |
646d19a4 BVA |
10 | #include <android/sharedmem.h> |
11 | #else | |
12 | #define ASHMEM_DEVICE "/dev/ashmem" | |
13 | #endif | |
14 | #define shmid_ds shmid64_ds | |
15 | #define SHM_HUGETLB 04000 | |
16 | ||
17 | static inline int shmctl(int __shmid, int __cmd, struct shmid_ds *__buf) | |
18 | { | |
19 | int ret=0; | |
20 | if (__cmd == IPC_RMID) | |
21 | { | |
22 | int length = ioctl(__shmid, ASHMEM_GET_SIZE, NULL); | |
23 | struct ashmem_pin pin = {0 , length}; | |
24 | ret = ioctl(__shmid, ASHMEM_UNPIN, &pin); | |
25 | close(__shmid); | |
26 | } | |
27 | return ret; | |
28 | } | |
29 | ||
d9705059 | 30 | #ifdef CONFIG_ASHAREDMEMORY_CREATE |
646d19a4 BVA |
31 | static inline int shmget(key_t __key, size_t __size, int __shmflg) |
32 | { | |
33 | char keybuf[11]; | |
34 | ||
35 | sprintf(keybuf, "%d", __key); | |
36 | ||
37 | return ASharedMemory_create(keybuf, __size + sizeof(uint64_t)); | |
38 | } | |
39 | #else | |
40 | static inline int shmget(key_t __key, size_t __size, int __shmflg) | |
41 | { | |
42 | int fd,ret; | |
43 | char keybuf[11]; | |
44 | ||
45 | fd = open(ASHMEM_DEVICE, O_RDWR); | |
46 | if (fd < 0) | |
47 | return fd; | |
48 | ||
49 | sprintf(keybuf,"%d",__key); | |
50 | ret = ioctl(fd, ASHMEM_SET_NAME, keybuf); | |
51 | if (ret < 0) | |
52 | goto error; | |
53 | ||
54 | /* Stores size in first 8 bytes, allocate extra space */ | |
55 | ret = ioctl(fd, ASHMEM_SET_SIZE, __size + sizeof(uint64_t)); | |
56 | if (ret < 0) | |
57 | goto error; | |
58 | ||
59 | return fd; | |
60 | ||
61 | error: | |
62 | close(fd); | |
63 | return ret; | |
64 | } | |
65 | #endif | |
66 | ||
67 | static inline void *shmat(int __shmid, const void *__shmaddr, int __shmflg) | |
68 | { | |
69 | size_t size = ioctl(__shmid, ASHMEM_GET_SIZE, NULL); | |
70 | /* Needs to be 8-byte aligned to prevent SIGBUS on 32-bit ARM */ | |
71 | uint64_t *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, __shmid, 0); | |
72 | /* Save size at beginning of buffer, for use with munmap */ | |
73 | *ptr = size; | |
74 | return ptr + 1; | |
75 | } | |
76 | ||
77 | static inline int shmdt (const void *__shmaddr) | |
78 | { | |
79 | /* Find mmap size which we stored at the beginning of the buffer */ | |
80 | uint64_t *ptr = (uint64_t *)__shmaddr - 1; | |
81 | size_t size = *ptr; | |
82 | return munmap(ptr, size); | |
83 | } | |
84 | #endif |