3 * Copyright 2003,2005 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
7 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Radio; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
30 #ifdef HAVE_SYS_TYPES_H
31 #include <sys/types.h>
33 #ifdef HAVE_SYS_MMAN_H
38 #include <gr_pagesize.h>
39 #include <gr_tmp_path.h>
40 #include <gr_vmcircbuf_createfilemapping.h>
43 gr_vmcircbuf_createfilemapping::gr_vmcircbuf_createfilemapping (int size)
46 #if !defined(HAVE_CREATEFILEMAPPING)
47 fprintf (stderr, "%s: createfilemapping is not available\n",__FUNCTION__);
48 throw std::runtime_error ("gr_vmcircbuf_createfilemapping");
50 static int s_seg_counter = 0;
52 if (size <= 0 || (size % gr_pagesize ()) != 0){
53 fprintf (stderr, "gr_vmcircbuf_createfilemapping: invalid size = %d\n", size);
54 throw std::runtime_error ("gr_vmcircbuf_createfilemapping");
58 snprintf (seg_name, sizeof (seg_name), "/gnuradio-%d-%d", getpid (), s_seg_counter);
60 d_handle = CreateFileMapping(INVALID_HANDLE_VALUE, // use paging file
61 NULL, // default security
62 PAGE_READWRITE, // read/write access
63 0, // max. object size
65 seg_name); // name of mapping object
68 if (d_handle == NULL || d_handle == INVALID_HANDLE_VALUE){
70 snprintf (msg, sizeof (msg), "gr_vmcircbuf_mmap_createfilemapping: CreateFileMapping [%s] :%d", seg_name,(int)GetLastError());
72 throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
76 d_first_copy = d_second_copy = NULL;
78 while (i++ < 8 && d_second_copy == NULL){
79 // keep the first map allocation to force allocation in a new address
81 LPVOID first_tmp = d_first_copy;
83 d_first_copy = MapViewOfFile((HANDLE)d_handle, // handle to map object
84 FILE_MAP_WRITE, // read/write permission
89 if (d_first_copy == NULL){
91 UnmapViewOfFile(first_tmp);
93 CloseHandle(d_handle); // cleanup
95 snprintf (msg, sizeof (msg),
96 "gr_vmcircbuf_mmap_createfilemapping: MapViewOfFile (1) :%d", (int)GetLastError());
98 throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
101 // NOTE: d_second_copy will be NULL if MapViewFileEx() fails to allocate the
102 // requested address space
103 d_second_copy = MapViewOfFileEx((HANDLE)d_handle, // handle to map object
104 FILE_MAP_WRITE, // read/write permission
108 (char *)d_first_copy + size);//(LPVOID) ((char *)d_first_copy + size));
111 UnmapViewOfFile(first_tmp);
114 fprintf (stderr,"gr_vmcircbuf_mmap_createfilemapping: contiguous? mmap %p %p %p %p, %d\n",
115 (char *)d_first_copy, (char *)d_second_copy, size, (char *)d_first_copy + size,i);
119 if (d_second_copy == NULL){ // cleanup
120 fprintf (stderr,"gr_vmcircbuf_mmap_createfilemapping: non contiguous mmap - %p %p %p %p\n",
121 d_first_copy, d_second_copy, size, (char *)d_first_copy + size);
122 UnmapViewOfFile(d_first_copy);
123 CloseHandle(d_handle); // cleanup
124 throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
127 // Now remember the important stuff
128 d_base = (char *) d_first_copy;
130 #endif /*HAVE_CREATEFILEMAPPING*/
133 gr_vmcircbuf_createfilemapping::~gr_vmcircbuf_createfilemapping ()
135 #ifdef HAVE_CREATEFILEMAPPING
136 if (UnmapViewOfFile(d_first_copy) == 0)
138 perror ("gr_vmcircbuf_createfilemapping: UnmapViewOfFile(d_first_copy)");
141 if (UnmapViewOfFile(d_second_copy) == 0)
143 perror ("gr_vmcircbuf_createfilemapping: UnmapViewOfFile(d_second_copy)");
146 CloseHandle(d_handle);
150 // ----------------------------------------------------------------
151 // The factory interface
152 // ----------------------------------------------------------------
155 gr_vmcircbuf_factory *gr_vmcircbuf_createfilemapping_factory::s_the_factory = 0;
157 gr_vmcircbuf_factory *
158 gr_vmcircbuf_createfilemapping_factory::singleton ()
161 return s_the_factory;
162 s_the_factory = new gr_vmcircbuf_createfilemapping_factory ();
163 return s_the_factory;
167 gr_vmcircbuf_createfilemapping_factory::granularity ()
169 #ifdef HAVE_CREATEFILEMAPPING
170 // return 65536;//TODO, check, is this needed or can we just use gr_pagesize()
171 SYSTEM_INFO system_info;
172 GetSystemInfo(&system_info);
173 //fprintf(stderr,"win32 AllocationGranularity %p\n",(int)system_info.dwAllocationGranularity);
174 return (int)system_info.dwAllocationGranularity;
176 return gr_pagesize ();
181 gr_vmcircbuf_createfilemapping_factory::make (int size)
185 return new gr_vmcircbuf_createfilemapping (size);