I cannot answer your question about performance, but you have prompted me
to create a simple example with POSIX shared memory. Attached are two
files, producer.c and consumer.scm. The producer (a C program) writes
strings to a POSIX shared memory file, and the consumer (a Scheme program)
reads them, prints them and then unlinks the buffer. The producer uses
mmap, as Dan mentioned in his reply. This may be clunky, but there is no
need to worry about synchronization.
Using e.g. Linux shmget for shared memory between threads _might_  give you
higher performance, but then you have to mess around with semaphores and so
on. I will not have time to adapt the code you link to, but I can help  if
you are having trouble with a particular construct in posix-shm.

   -Ivan







On Sun, May 5, 2013 at 8:07 AM, Jörg F. Wittenberger <
joerg.wittenber...@softeyes.net> wrote:

> On May 4 2013, Ivan Raikov wrote:
>
>   I think you can try to have native threads by running a separate instance
>> of the Chicken runtime for each thread, but are you sure that you will
>> really achieve a significant speedup over Unix processes and/or MPI?
>> It's not the early nineties anymore... I suggest prototyping  code and
>> running real-world benchmarks first.
>>
>
> Hm.  I dunno, I'm old school.
>
> So far I have at least one case, where I've been resorting to native
> threads because I didn't see another solution.  Maybe you/anybody
> could enlighten me?
>
> The case at hand: I'm running sqlite queries, which can take a long time.
> I don't want to block the chicken system while those are busy. Worse: I'm
> using the sqlite VFS to get the actual data blocks ... from chicken, hence
> the chicken thread MUST not wait for sqlite... (for reference an old
> version of the code is here http://lists.nongnu.org/**
> archive/html/chicken-users/**2010-01/msg00046.html<http://lists.nongnu.org/archive/html/chicken-users/2010-01/msg00046.html>)
>
> As I said: I'm old school - could I really expect a reasonable performance
> from running a separate sqlite process and cop the data back and forth
> between the processes?  Suggestion how to do this are welcome!
>
>
>  On Sat, May 4, 2013 at 8:39 AM, Dan Leslie <d...@ironoxide.ca> wrote:
>>
> ...
>
>  Relatedly, is anyone poking at implementing native threads?
>>> I've been digging around a bit but haven't had much time to progress very
>>> far.
>>>
>>
> In fact I'm contemplating about this for a while and never got the
> courage to try.  (Especially because I don't see how I could create
> a half-way meaningful benchmark beforehand to judge the gain/loss
> early in the development process.)
>
> The bottleneck for me is usually blocking on i/o.  Wrt. this I do not
> expect (as in wild guess - no benchmarks done) much from multiple
> threads.
>
> However some things I'm doing are just computations.  Am I thinking
> "early nineties" style when I assume that chicken will utilize only
> one cpu core?  If so, I'd prefer not spare the others all the time.
>
> My problem: I can't see a good way to share chicken-managed memory
> between threads.  I recall having seen a paper on using a dedicated
> thread for memory allocation...but can't find it anymore.
>
> Nevertheless: maybe it would be feasible to do all second gen
> gc in a dedicated thread and force a minor gc before passing data
> between threads?  Would it?
>
>
> Best
>
> /Jörg
>
>
>
> ........
>
>
>
>
>
>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>        /* For mode constants */
#include <unistd.h>
#include <fcntl.h>           /* For O_* constants */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define BUFFER_SIZE 32768
#define BUFFER_NAME "/shmtest1"

void buffer_create(int size, int *fileno, char **addr) 
{
  int perms = 0600;
  char *laddr;
  *addr = 0; 

  *fileno = shm_open(BUFFER_NAME, O_CREAT | O_RDWR, perms);
  if (errno > 0) 
    {
      perror("failed to create shared memory file handle");
      exit (1);
    }

  if ((ftruncate(*fileno, size)) == -1)
    {    /* Sets the size */
      perror("ftruncate failed on shared memory file handle");
      exit(1);
    }

  laddr = (char*)mmap(NULL, size, PROT_WRITE, MAP_SHARED, *fileno, 0);
  if (errno > 0) 
    {
      perror ("failed to mmap shared memory file handle");
      exit (1);
    }

  *addr = laddr;

}


void buffer_clear(char **sbuff, char *start) 
{
  *sbuff = start;
}

int buffer_size(char *sbuff, char *start) 
{
  return (sbuff-start);
}

void buffer_close(int fileno, char *start) 
{
  if ((munmap(start, BUFFER_SIZE)) == -1)
    {
      perror("munmap failed on shared buffer");
      exit(1);
    }
    
  if ((close(fileno)) == -1)
    {
      perror("close failed on shared buffer file handle");
      exit(1);
    }
    
}

void insert_item(char *item, char **shared_buffer, char *shared_start) 
{
  int n = strlen(item);
  memcpy (*shared_buffer, item, n);
  *shared_buffer = *shared_buffer+n;
}


int main(int argc, const char **argv)
{
  char *shared_start, *shared_buffer;
  int shared_fileno;

  buffer_create(BUFFER_SIZE, &shared_fileno, &shared_start);

  buffer_clear(&shared_buffer, shared_start); // prepare buffer for jobs

  int i = 0;
  char s[30];

  while(i<1000) 
    {
      memset(s,sizeof(s),0);
      sprintf (s, "Hello world #%d", i);
      insert_item(s, &shared_buffer, shared_start);
      printf ("shared_buffer = %p\n", shared_buffer);
      i = i+1;
    }

  buffer_close (shared_fileno, shared_start);
 
  return 0;
}

Attachment: consumer.scm
Description: Binary data

_______________________________________________
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users

Reply via email to