Forking processes / 2012-01-11 16:03:49
Thanks to binkd and other sources on the Internet, I think that I was able to correctly use the ixemul.library to "fork" processes . Here is a code snippet:
/*
* fork.c -- An example of using ixemul.library pseudo-forking function
*
* Copyright (c) 2011 Tygre (yann-gael@gueheneuc.net)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <stdio.h>
#include <ix.h>
#define MAX_COUNT 5
#define BUF_SIZE 100
/*
* The function that will be called by two separate processes.
* It just prints out MAX_COUNT times a counter while sleeping
* in between each print to show the "forking".
*/
static void forked_print(char *id)
{
pid_t pid = getpid();
int i;
char buf[BUF_SIZE];
srand(time(NULL));
sprintf(buf, "%s pid is %d\n", id, pid);
write(1, buf, strlen(buf));
for (i = 1; i <= MAX_COUNT; i++) {
sprintf(buf, "%s, with pid %d, value = %d\n", id, pid, i);
write(1, buf, strlen(buf));
sleep(rand() % 4);
}
sprintf(buf, "%s, with pid %d, just quitted!\n", id, pid);
write(1, buf, strlen(buf));
}
/*
* This function does the "magic" of "forking" the main process.
* It is heavily inspired by the function "branch" available in
* the 0.9.9 release of "binkd" in the file "branch.c".
* Below is the copying permission statement from "branch.c":
*
* branch.c -- Create co-processes
*
* branch.c is a part of binkd project
*
* Copyright (C) 1996-1998 Dima Maloff, 5047/13
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. See COPYING.
*/
static int branch(register void (*F) (void *), register void *arg, register size_t size)
{
char buf[BUF_SIZE];
register int rc;
static char *tmp;
/*
* We print out some information regarding the "arg" and its "size".
*/
sprintf(buf, "Before ix_vfork, arg: %d, size: %d\n", arg, size);
write(1, buf, strlen(buf));
if(!(rc = ix_vfork()))
{
vfork_setup_child();
/*
* We make our own copy of arg for the child as the parent
* may destroy it before the child finish to use it.
*/
if(size > 0)
{
if((tmp = malloc(size)) == NULL)
{
perror("Malloc failed");
return -1;
}
else
{
memcpy(tmp, arg, size);
}
}
else
{
tmp = 0;
}
/*
* We print out some information regarding the "arg" and its copy,
* "tmp".
* It is important to note that the pointer value for "arg" did not change
* after the "forking" because it is not a true "forking" but rather the
* creation of a thread.
* See http://binkd.sourcearchive.com/documentation/0.9.9plus-p20060809-1/branch_8c-source.html
*/
sprintf(buf, "Before ix_vfork, arg: %d, tmp: %d\n", arg, tmp);
write(1, buf, strlen(buf));
ix_vfork_resume();
F(tmp);
free(tmp);
_exit(0);
}
else if (rc < 0)
{
sprintf(buf, "ix_vfork: %s\n", strerror(errno));
write(1, buf, strlen(buf));
}
return rc;
}
int main(void)
{
char id[2];
/*
* We "fork" the function "forked_print", using "C" to denote the child.
*/
sprintf(id, "C");
if(branch((void *) forked_print, (void *) id, sizeof(id)) < 0)
{
perror("Cannot branch!");
}
else
{
/*
* We call the function "forked_print" in the parent process, using "P".
*/
sprintf(id, "P");
sleep(3);
forked_print(id);
}
exit(0);
}
To (cross-)compile this code (for example in CygWin), just call:
/usr/local/amiga/bin/m68k-amigaos-gcc.exe fork.c -o fork
Running the fork program in WinUAE typically outputs:
Before ix_vfork, arg: ...10, size: 2
Before ix_vfork, arg: ...10, tmp: ...28
C pid is ...60
C, with pid ...60, value = 1
C, with pid ...60, value = 2
C pid is ...36
P, with pid ...36, value = 1
C, with pid ...60, value = 3
P, with pid ...36, value = 2
C, with pid ...60, value = 4
P, with pid ...36, value = 3
P, with pid ...36, value = 4
C, with pid ...60, value = 5
P, with pid ...36, value = 5
P, with pid ...36, just quitted!
C, with pid ...60, just quitted!
|