Add a comment that explains why this header has no multiple inclusion guards.
[mplayer/greg.git] / osdep / shmem.c
blob24e3310ccb03916336fea4c83275524dec6030c9
1 /*
2 * shmem.c - Shared memory allocation
3 *
4 * based on mpg123's xfermem.c by
5 * Oliver Fromme <oliver.fromme@heim3.tu-clausthal.de>
6 * Sun Apr 6 02:26:26 MET DST 1997
7 */
9 #include "config.h"
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
15 #include <errno.h>
16 #include <sys/types.h>
17 #include <sys/time.h>
18 #include <sys/uio.h>
19 #ifdef HAVE_SYS_MMAN_H
20 #include <sys/mman.h>
21 #elif defined(__BEOS__)
22 #include <mman.h>
23 #endif
24 #include <sys/socket.h>
25 #include <fcntl.h>
27 #include "mp_msg.h"
29 #ifdef AIX
30 #include <sys/select.h>
31 #endif
33 #ifdef HAVE_SHM
34 #include <sys/ipc.h>
35 #include <sys/shm.h>
36 #endif
38 #if defined(MAP_ANONYMOUS) && !defined(MAP_ANON)
39 #define MAP_ANON MAP_ANONYMOUS
40 #endif
42 static int shmem_type=0;
44 void* shmem_alloc(int size){
45 void* p;
46 static int devzero = -1;
47 while(1){
48 switch(shmem_type){
49 case 0: // ========= MAP_ANON|MAP_SHARED ==========
50 #ifdef MAP_ANON
51 p=mmap(0,size,PROT_READ|PROT_WRITE,MAP_ANON|MAP_SHARED,-1,0);
52 if(p==MAP_FAILED) break; // failed
53 mp_dbg(MSGT_OSDEP, MSGL_DBG2, "shmem: %d bytes allocated using mmap anon (%p)\n",size,p);
54 return p;
55 #else
56 // system does not support MAP_ANON at all (e.g. solaris 2.5.1/2.6), just fail
57 mp_dbg(MSGT_OSDEP, MSGL_DBG3, "shmem: using mmap anon failed\n");
58 #endif
59 break;
60 case 1: // ========= MAP_SHARED + /dev/zero ==========
61 if (devzero == -1 && (devzero = open("/dev/zero", O_RDWR, 0)) == -1) break;
62 p=mmap(0,size,PROT_READ|PROT_WRITE,MAP_SHARED,devzero,0);
63 if(p==MAP_FAILED) break; // failed
64 mp_dbg(MSGT_OSDEP, MSGL_DBG2, "shmem: %d bytes allocated using mmap /dev/zero (%p)\n",size,p);
65 return p;
66 case 2: { // ========= shmget() ==========
67 #ifdef HAVE_SHM
68 struct shmid_ds shmemds;
69 int shmemid;
70 if ((shmemid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0600)) == -1) break;
71 if ((p = shmat(shmemid, 0, 0)) == (void *)-1){
72 mp_msg(MSGT_OSDEP, MSGL_ERR, "shmem: shmat() failed: %s\n", strerror(errno));
73 shmctl (shmemid, IPC_RMID, &shmemds);
74 break;
76 if (shmctl(shmemid, IPC_RMID, &shmemds) == -1) {
77 mp_msg(MSGT_OSDEP, MSGL_ERR, "shmem: shmctl() failed: %s\n", strerror(errno));
78 if (shmdt(p) == -1) perror ("shmdt()");
79 break;
81 mp_dbg(MSGT_OSDEP, MSGL_DBG2, "shmem: %d bytes allocated using SHM (%p)\n",size,p);
82 return p;
83 #else
84 mp_msg(MSGT_OSDEP, MSGL_FATAL, "shmem: no SHM support was compiled in!\n");
85 return(NULL);
86 #endif
88 default:
89 mp_msg(MSGT_OSDEP, MSGL_FATAL,
90 "FATAL: Cannot allocate %d bytes of shared memory :(\n",size);
91 return NULL;
93 ++shmem_type;
97 void shmem_free(void* p,int size){
98 switch(shmem_type){
99 case 0:
100 case 1:
101 if(munmap(p,size)) {
102 mp_msg(MSGT_OSDEP, MSGL_ERR, "munmap failed on %p %d bytes: %s\n",
103 p,size,strerror(errno));
105 break;
106 case 2:
107 #ifdef HAVE_SHM
108 if (shmdt(p) == -1)
109 mp_msg(MSGT_OSDEP, MSGL_ERR, "shmfree: shmdt() failed: %s\n",
110 strerror(errno));
111 #else
112 mp_msg(MSGT_OSDEP, MSGL_ERR, "shmfree: no SHM support was compiled in!\n");
113 #endif
114 break;