diff options
author | Antoine Villeret <avilleret@users.sourceforge.net> | 2013-09-02 18:45:14 +0000 |
---|---|---|
committer | Antoine Villeret <avilleret@users.sourceforge.net> | 2013-09-02 18:45:14 +0000 |
commit | 37a835ccc37929ba46fe1ce2a19bc9dfcbbc81df (patch) | |
tree | 5db65e02e87cc4652e35d36c93e70c495ec473a8 | |
parent | 503d272cbda844e3980f1882afd89efd5fb3be15 (diff) |
Windows port
svn path=/trunk/externals/share_mem/; revision=17200
-rw-r--r-- | shmem-help.pd | 226 | ||||
-rw-r--r-- | shmem.c | 206 |
2 files changed, 282 insertions, 150 deletions
diff --git a/shmem-help.pd b/shmem-help.pd index dd93ddb..64c3b8f 100644 --- a/shmem-help.pd +++ b/shmem-help.pd @@ -1,102 +1,124 @@ -#N canvas 490 352 1176 549 10; -#N canvas 1 89 450 300 (subpatch) 0; -#X array array2 100 float 3; -#A 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0; -#X coords 0 1 99 -1 200 140 1; -#X restore 680 26 graph; -#X msg 83 418 memset 0 1 1 1 1 1; -#X text 215 414 write a list (or a float) to the shared memory : 1st -value is index \, other are data to store; -#X msg 52 343 memset 0 array1; -#N canvas 0 50 450 300 (subpatch) 0; -#X array array1 100 float 3; -#A 0 -0.235714 -0.25 -0.264285 -0.278571 -0.292857 -0.292857 -0.25 --0.235714 -0.192857 -0.164286 -0.121429 -0.1 -0.0785717 -0.0500004 --0.021429 -4.76837e-07 0.021428 0.0428566 0.0642851 0.0857136 0.107142 -0.121428 0.135714 0.149999 0.164285 0.182142 0.199999 0.217856 0.235713 -0.249999 0.264285 0.27857 0.292856 0.307142 0.321427 0.335713 0.349999 -0.357142 0.364284 0.371427 0.37857 0.383332 0.388094 0.392856 0.40238 -0.411903 0.421427 0.421427 0.421427 0.435713 0.435713 0.435713 0.407142 -0.37857 0.335713 0.307142 0.235713 0.214285 0.192856 0.164285 0.0928565 -0.0499994 -0.00714332 -0.0642861 -0.121429 -0.135714 -0.135714 -0.135714 --0.107143 -0.1 -0.0928574 -0.0785717 -0.0642861 -0.0642861 -0.0357147 --0.021429 -0.00714332 0.00714236 0.021428 0.0357137 0.0642851 0.0785708 -0.107142 0.121428 0.135714 0.149999 0.149999 0.164285 0.178571 0.192856 -0.207142 0.221428 0.235713 0.235713 0.249999 0.264285 0.264285 0.27857 -0.292856 0.292856; -#X coords 0 1 99 -1 200 140 1; -#X restore 475 26 graph; -#X text 166 343 set shared memory from index 0 with array1; -#X msg 68 365 memset 0 array1 50; -#X text 196 365 set shared memory from index 0 with array1 from index -50; -#X obj 36 505 shmem 1214 250; -#X text 162 505 1st argument : Identifiant of the memory segment; -#X text 21 15 shmem - shared memory manipulation; -#X text 22 37 The shmem object allow to use shared memory in Pd. It -is useful for example to exchange array between two instances of Pd. -Every shmem object can read and write to a shared memory segment that -is identified by its Id.; -#X text 21 95 When you create a shmem object \, it checks its Id. If -the id is not used \, it allows a new segment \, otherwise it address -the exisiting segment.; -#X floatatom 614 418 5 0 0 0 - - -; -#X obj 598 471 shmem 1214 250; -#X text 685 443 read one float of the table send value to the outlet -; -#X msg 598 352 memdump 0 array2; -#X text 567 274 READING MEMORY; -#X floatatom 598 495 5 0 0 0 - - -; -#X text 718 352 dump shared memory from index 0 to array2; -#X text 21 146 Work only on Linux / and Unix.; -#X text 162 521 2nd argument : size of the segment (number of float) -; -#X msg 614 443 memread \$1; -#X msg 106 475 memclear; -#X text 169 477 reset memory to 0; -#X text 475 168 array1 and array 2 are size 100; -#X msg 99 448 memset 50 5 5 5 1 1 0.1 0.2 0.3 0.4 0.5 0.6 0.7; -#X text 21 272 WRITING INTO MEMORY; -#X msg 608 374 memdump 0 array2 50; -#X text 728 374 dump shared memory from index 0 to array2 from index -50; -#X text 768 394 dump shared memory from index 0 to array2 from index -50 to index 60 (50 + 10); -#X msg 46 321 memset array1 array1 array1; -#X msg 36 301 memset array1; -#X text 149 300 set array in to shared memory; -#X text 223 321 set diferent array in to shared memory; -#X msg 568 301 memdump array2; -#X msg 584 322 memdump array2 array2 array2; -#X text 698 298 dump shared memory in an array; -#X text 769 322 dump shared memory in many array; -#X msg 78 391 memset 50 array1 0 25; -#X text 219 388 set shared memory from index 50 with array1 from index -0 to 25; -#X msg 53 197 memset array_name [array_name]; -#X msg 71 237 memset src_offset list_of_float; -#X msg 571 198 memdump array_name [array_name]; -#X msg 61 217 memset src_offset src_array_name [dest_offset [size]] -; -#X msg 583 221 memdump src_offset dest_array_name [dest_offset [size]] -; -#X msg 618 394 memdump 50 array2 0 10; -#X connect 1 0 8 0; -#X connect 3 0 8 0; -#X connect 6 0 8 0; -#X connect 13 0 22 0; -#X connect 14 0 18 0; -#X connect 16 0 14 0; -#X connect 22 0 14 0; -#X connect 23 0 8 0; -#X connect 26 0 8 0; -#X connect 28 0 14 0; -#X connect 31 0 8 0; -#X connect 32 0 8 0; -#X connect 35 0 14 0; -#X connect 36 0 14 0; -#X connect 39 0 8 0; -#X connect 46 0 14 0; +#N canvas 357 58 1176 549 10;
+#N canvas 1 89 450 300 (subpatch) 0;
+#X array array2 100 float 3;
+#A 0 -0.37143 -0.366668 -0.361906 -0.357144 -0.345716 -0.334287 -0.322858
+-0.31143 -0.300001 -0.285715 -0.27143 -0.257144 -0.242858 -0.228572
+-0.223377 -0.218183 -0.212988 -0.207793 -0.202598 -0.197403 -0.192208
+-0.187014 -0.181819 -0.176624 -0.171429 -0.157143 -0.142858 -0.138776
+-0.134694 -0.130613 -0.126531 -0.122449 -0.118368 -0.114286 -0.104082
+-0.0938779 -0.0836738 -0.0734697 -0.0632655 -0.0530614 -0.0428573 -0.0428573
+-0.0428573 -0.0428573 -0.0428573 -0.0428573 -0.0428573 -0.0428573 -0.0428573
+-0.0428573 -0.0396827 -0.0365081 -0.0333335 -0.0301588 -0.0269842 -0.0238096
+-0.020635 -0.0174604 -0.0142858 -0.0142858 -0.0142858 -0.0142858 -0.0142858
+-0.0142858 -0.0142858 -0.0142858 -0.0142858 -0.0142858 -0.0142858 -0.0142858
+-0.0142858 -0.0142858 -0.0142858 -0.0142858 -0.0142858 -0.0142858 -0.0142858
+-0.0142858 -0.0142858 -0.0142858 -0.0107143 -0.00714288 -0.00357144
+0 0.00357144 0.00714288 0.0107143 0.0142858 0.0178572 0.0214286 0.0250001
+0.0285715 0.032143 0.0357144 0.0392859 0.0428573 0.0535716 0.0642859
+0.0750003 0.27143;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 680 26 graph;
+#X msg 83 418 memset 0 1 1 1 1 1;
+#X text 215 414 write a list (or a float) to the shared memory : 1st
+value is index \, other are data to store;
+#X msg 52 343 memset 0 array1;
+#N canvas 0 50 450 300 (subpatch) 0;
+#X array array1 100 float 3;
+#A 0 0.714288 0.697405 0.680522 0.663639 0.646756 0.629872 0.612989
+0.596106 0.579223 0.56234 0.545456 0.528573 0.525398 0.522224 0.519049
+0.515875 0.5127 0.509525 0.506351 0.503176 0.500002 0.500002 0.500002
+0.500002 0.500002 0.500002 0.500002 0.492859 0.485716 0.478573 0.47143
+0.464287 0.457144 0.44762 0.438097 0.428573 0.422858 0.417144 0.41143
+0.405716 0.400001 0.400001 0.400001 0.400001 0.400001 0.400001 0.400001
+0.385715 0.37143 0.328572 0.300001 0.271429 0.257144 0.242858 0.2 0.171429
+0.15 0.128572 0.0714286 0.042857 0.0142855 -0.014286 -0.0571433 -0.100001
+-0.142858 -0.178572 -0.214287 -0.250001 -0.285716 -0.333335 -0.380954
+-0.428573 -0.471431 -0.514288 -0.557145 -0.64286 -0.728574 -0.814289
+-0.871432 -0.900003 -0.907146 -0.914289 -0.928575 -0.942861 -0.950004
+-0.957146 0.0107143 0.0142858 0.0178572 0.0214286 0.0250001 0.0285715
+0.032143 0.0357144 0.0392859 0.0428573 0.0535716 0.0642859 0.0750003
+0.27143;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 475 26 graph;
+#X text 166 343 set shared memory from index 0 with array1;
+#X msg 68 365 memset 0 array1 50;
+#X text 196 365 set shared memory from index 0 with array1 from index
+50;
+#X text 162 505 1st argument : Identifiant of the memory segment;
+#X text 21 15 shmem - shared memory manipulation;
+#X text 22 37 The shmem object allow to use shared memory in Pd. It
+is useful for example to exchange array between two instances of Pd.
+Every shmem object can read and write to a shared memory segment that
+is identified by its Id.;
+#X text 21 95 When you create a shmem object \, it checks its Id. If
+the id is not used \, it allows a new segment \, otherwise it address
+the exisiting segment.;
+#X floatatom 614 418 5 0 0 0 - - -;
+#X text 685 443 read one float of the table send value to the outlet
+;
+#X msg 598 352 memdump 0 array2;
+#X text 567 274 READING MEMORY;
+#X floatatom 598 495 5 0 0 0 - - -;
+#X text 718 352 dump shared memory from index 0 to array2;
+#X text 162 521 2nd argument : size of the segment (number of float)
+;
+#X msg 614 443 memread \$1;
+#X msg 106 475 memclear;
+#X text 169 477 reset memory to 0;
+#X text 475 168 array1 and array 2 are size 100;
+#X msg 99 448 memset 50 5 5 5 1 1 0.1 0.2 0.3 0.4 0.5 0.6 0.7;
+#X text 21 272 WRITING INTO MEMORY;
+#X msg 608 374 memdump 0 array2 50;
+#X text 728 374 dump shared memory from index 0 to array2 from index
+50;
+#X text 768 394 dump shared memory from index 0 to array2 from index
+50 to index 60 (50 + 10);
+#X msg 46 321 memset array1 array1 array1;
+#X text 149 300 set array in to shared memory;
+#X text 223 321 set diferent array in to shared memory;
+#X msg 584 322 memdump array2 array2 array2;
+#X text 698 298 dump shared memory in an array;
+#X text 769 322 dump shared memory in many array;
+#X msg 78 391 memset 50 array1 0 25;
+#X text 219 388 set shared memory from index 50 with array1 from index
+0 to 25;
+#X msg 53 147 memset array_name [array_name];
+#X msg 71 187 memset src_offset list_of_float;
+#X msg 571 198 memdump array_name [array_name];
+#X msg 61 167 memset src_offset src_array_name [dest_offset [size]]
+;
+#X msg 583 221 memdump src_offset dest_array_name [dest_offset [size]]
+;
+#X msg 618 394 memdump 50 array2 0 10;
+#X obj 35 505 shmem 1214 250;
+#X obj 598 471 shmem 1214 250;
+#X obj 679 515 print status;
+#X text 763 512 send out the id of shared memory if allocation succeed
+\, -1 otherwise;
+#X text 18 213 CHANGE ID AND SIZE;
+#X msg 34 234 allocate 1234 1024;
+#X msg 158 235 allocate 0 12;
+#X obj 16 255 t a a;
+#X msg 568 301 memdump array2;
+#X msg 37 300 memset array1;
+#X connect 1 0 42 0;
+#X connect 3 0 42 0;
+#X connect 6 0 42 0;
+#X connect 12 0 19 0;
+#X connect 14 0 43 0;
+#X connect 19 0 43 0;
+#X connect 20 0 42 0;
+#X connect 23 0 42 0;
+#X connect 25 0 43 0;
+#X connect 28 0 42 0;
+#X connect 31 0 43 0;
+#X connect 34 0 42 0;
+#X connect 41 0 43 0;
+#X connect 43 0 16 0;
+#X connect 43 1 44 0;
+#X connect 47 0 49 0;
+#X connect 48 0 49 0;
+#X connect 49 0 42 0;
+#X connect 49 1 43 0;
+#X connect 50 0 43 0;
+#X connect 51 0 42 0;
@@ -1,16 +1,30 @@ #include "m_pd.h" -#include <stdio.h> -#include <sys/shm.h> -#include <sys/stat.h> +#include <stdio.h> +#ifdef _WIN32
+ #define NOMINMAX // avoid interference between macro min and the function defined in this file... + #include <windows.h> + #include <stdio.h> + #include <conio.h> + #include <tchar.h> +#else + #include <sys/shm.h> + #include <sys/stat.h>
+#endif // _WIN32 typedef struct shmem { - t_object x_obj; - int segment_id; - t_float *share_memory; - int segment_size; + t_object x_obj;
+#ifdef _WIN32
+ HANDLE m_MapFile;
+ char m_fileMappingName[128];
+#else
+ int segment_id;
+#endif // _WIN32
+ t_outlet *m_info_out; + t_float *share_memory; + int segment_size; } t_shmem; - +
static inline t_float min(t_float x1,t_float x2) { if (x1 <= x2) { @@ -18,8 +32,13 @@ static inline t_float min(t_float x1,t_float x2) } else { return x2; } -} - +}
+
+/**
+ * \fn void shmem_set_tab(t_shmem *x, t_symbol *unused, int argc, t_atom *argv)
+ * \brief Set the table to bind to and copy its data to internal buffer.
+ *
+ */ int shmem_set_tab(t_shmem *x, t_symbol *table, int src_offset, int dest_offset, int size) { int npoints, i, index_max; @@ -41,9 +60,19 @@ int shmem_set_tab(t_shmem *x, t_symbol *table, int src_offset, int dest_offset, // post("copied=%d", i); return(i); } - +
+/**
+ * \fn void shmem_set(t_shmem *x, t_symbol *unused, int argc, t_atom *argv)
+ * \brief Handle the [memset ...( message
+ *
+ */ void shmem_set(t_shmem *x, t_symbol *unused, int argc, t_atom *argv) -{ +{
+ if ( !x->share_memory ){
+ error("Create a valid shared memory before setting data !");
+ return;
+ }
+ int i, j, index_max, shmem_offset, array_offset, size; if (argc < 1) { @@ -87,29 +116,39 @@ int shmem_dump_tab(t_shmem *x, t_symbol *table, int src_offset, int dest_offset, t_garray *a; t_word *vec; int i, index_max, vecsize; - + t_symbol *s = table; i=0; - + if (!(a = (t_garray *)pd_findbyclass(s, garray_class))) pd_error(x, "%s: no such array", s->s_name); - else if (!garray_getfloatwords(a, &vecsize, &vec)) + else if (!garray_getfloatwords(a, &vecsize, &vec)) pd_error(x, "%s: bad template for tabwrite", s->s_name); - else { - + else { + index_max = min(x->segment_size-src_offset, vecsize-dest_offset); index_max=min(index_max, size); for (i=0; i<index_max; i++) vec[i+dest_offset].w_float = x->share_memory[i+src_offset]; - } + } garray_redraw(a); // post("copied=%d", i); return(i); } - +
+/**
+ * void shmem_dump(t_shmem *x, t_symbol *unused, int argc, t_atom *argv)
+ * \brief Handle the [memdump ...( message
+ *
+ */ void shmem_dump(t_shmem *x, t_symbol *unused, int argc, t_atom *argv) -{ +{
+ if ( !x->share_memory ){
+ error("Create a valid shared memory before dumping data !");
+ return;
+ }
+ int i, j, shmem_offset, dest_offset, size; if (argc < 1) { @@ -141,57 +180,127 @@ void shmem_dump(t_shmem *x, t_symbol *unused, int argc, t_atom *argv) size = atom_getfloatarg(3,argc,argv); } shmem_dump_tab(x, s, shmem_offset, dest_offset, size); - } + } } void shmem_read(t_shmem *x, t_float index) -{ +{
+ if ( !x->share_memory ) return; int shmem_offset; - + shmem_offset = index; if (shmem_offset < 0) shmem_offset = 0; if (shmem_offset > x->segment_size-1) shmem_offset = x->segment_size-1; - // post("i=%d", offset); + // post("i=%d", offset); outlet_float(x->x_obj.ob_outlet, x->share_memory[shmem_offset]); } - -t_class *shmem_class; - -void *shmem_new( t_floatarg id, t_floatarg size) -{ - struct shmid_ds shmbuffer; - // post ("id, size: %f, %f", id, size); - t_shmem *x = (t_shmem *)pd_new(shmem_class); - - x->segment_size = (int)size; - x->segment_id = shmget ((int)id, sizeof(t_float)*x->segment_size, - IPC_CREAT | S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH); +
+/**
+ * \fn void shmem_allocate(t_shmem *x, int id, int size)
+ * \brief Allocate a new shared memory segment.
+ *
+ */
+
+void shmem_allocate(t_shmem *x, t_float fId, t_float fSize)
+{
+ int id = (int) fId;
+ x->segment_size = (int) fSize;
+#ifdef _WIN32
+ if ( x->share_memory ) UnmapViewOfFile( x->share_memory );
+ if ( x->m_MapFile ) CloseHandle( x->m_MapFile );
+
+ sprintf(x->m_fileMappingName, "puredata-FileMappingObject_%d", id);
+
+ x->m_MapFile = CreateFileMapping(
+ INVALID_HANDLE_VALUE, // use paging file
+ NULL, // default security
+ PAGE_READWRITE, // read/write access
+ (x->segment_size & 0xFFFFFFFF00000000) >> 32, // maximum object size (high-order DWORD)
+ x->segment_size & 0xFFFFFFFF, // maximum object size (low-order DWORD)
+ x->m_fileMappingName); // name of mapping object
+
+ if (x->m_MapFile == NULL)
+ {
+ error("Could not create file mapping object %s - error %ld.",x->m_fileMappingName, GetLastError());
+ outlet_float(x->m_info_out, -1);
+ return;
+ }
+
+ x->share_memory = (t_float*) MapViewOfFile(x->m_MapFile, // handle to map object
+ FILE_MAP_ALL_ACCESS, // read/write permission
+ 0,
+ 0,
+ x->segment_size);
+
+ if ( !x->share_memory ){
+ error("Could not get a view of file %s - error %ld",x->m_fileMappingName, GetLastError());
+ outlet_float(x->m_info_out, -1);
+ return;
+ } else {
+ verbose(0,"File mapping object %s successfully created.",x->m_fileMappingName);
+ }
+
+#else
+
+ struct shmid_ds shmbuffer; +
+ x->segment_id = shmget (id, sizeof(t_float)*x->segment_size, + IPC_CREAT | S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH); if(x->segment_id>0) { - x->share_memory = (t_float*) shmat (x->segment_id, 0, 0); - // post("shmem memory attached at address %p\n", x->share_memory); + x->share_memory = (t_float*) shmat (x->segment_id, 0, 0); + // post("shmem memory attached at address %p\n", x->share_memory); - shmctl (x->segment_id, IPC_STAT, &shmbuffer); - // post ("segment size: %d\n", shmbuffer.shm_segsz); + shmctl (x->segment_id, IPC_STAT, &shmbuffer); + // post ("segment size: %d\n", shmbuffer.shm_segsz); if ((int)shmbuffer.shm_segsz < (int)sizeof(t_float)*x->segment_size) { // there was a problem, set object meme size to 0 error("could not allocate shmem memory Id : %d, size %d", (int)id, x->segment_size ); - x->segment_size = 0; + x->segment_size = 0;
+ outlet_float(x->m_info_out, -1); } } else { error("could not allocate shmem memory Id : %d, size %d", (int)id, x->segment_size ); - x->segment_size = 0; - } + x->segment_size = 0;
+ outlet_float(x->m_info_out, -1); + }
+#endif // _WIN32
+ outlet_float(x->m_info_out, id);
+}
- outlet_new(&x->x_obj, 0); +t_class *shmem_class; +
+/**
+ * \fn void shmem_new(t_floatarg id, t_floatarg size)
+ * \brief Create a new instance of object.
+ *
+ * \param t_floatarg id : a unique id defining the shared memory segment
+ * \param t_floatarg size : size of the memory segment
+ *
+ */ +void *shmem_new( t_floatarg id, t_floatarg size) +{ + // post ("id, size: %f, %f", id, size); + t_shmem *x = (t_shmem *)pd_new(shmem_class);
+
+ x->share_memory = NULL;
+
+ outlet_new(&x->x_obj, 0);
+ x->m_info_out = outlet_new(&x->x_obj, 0);
+ shmem_allocate(x, id, size); return (void *)x; -} +}
void shmem_free(t_shmem *x) -{ +{
+#ifdef _WIN32
+ if ( x->share_memory ) UnmapViewOfFile( x->share_memory );
+ if ( x->m_MapFile ) CloseHandle( x->m_MapFile );
+#else shmdt (x->share_memory); - shmctl (x->segment_id, IPC_RMID, 0); + shmctl (x->segment_id, IPC_RMID, 0);
+#endif // _WIN32 } void shmem_clear(t_shmem *x) @@ -208,6 +317,7 @@ void shmem_setup(void) class_addmethod(shmem_class, (t_method)shmem_set, gensym("memset"), A_GIMME, 0); class_addmethod(shmem_class, (t_method)shmem_dump, gensym("memdump"), A_GIMME, 0); class_addmethod(shmem_class, (t_method)shmem_clear, gensym("memclear"), 0); - class_addmethod(shmem_class, (t_method)shmem_read, gensym("memread"),A_DEFFLOAT, 0); + class_addmethod(shmem_class, (t_method)shmem_read, gensym("memread"),A_DEFFLOAT, 0);
+ class_addmethod(shmem_class, (t_method)shmem_allocate, gensym("allocate"),A_FLOAT, A_FLOAT, 0); } |