Article View: comp.sys.atari.st
Article #38723Preloading revised
From: Leo de Wit
Date: Thu, 11 May 1989 07:10
Date: Thu, 11 May 1989 07:10
167 lines
5702 bytes
5702 bytes
For those who might be interested, here's a demo program that preloads
some programs (whose pathnames are supplied on the command line), then
executes them. It uses the Pexec variants 3, 4 and 5 to do so. Compiled
with Lattice C.
Enjoy!
Leo.
---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8
/* preload.c */
/* Demo and routines for preloading programs */
/* Author: L.J.M. de Wit - 05/11/89 */
/* This source and its use are PD */
#include <stdio.h>
#include <osbind.h>
#define MAXLOADED 16
#define DEFMNEED 0x1200 /* default memory reservation for heap + stack */
#define ARGSTRLEN 122
#define FAIL 1
#define OK 0
typedef struct img_id {
char name[64];
long basepag;
} img_id;
int _mneed = 20000; /* This program is Mshrinked to this size by Lattice C */
img_id load_img[MAXLOADED];
int nloaded = 0;
/* Main is a demo: all args are taken to be paths of executables; they're
* preloaded, then executed 10 times, then unloaded.
*/
main(argc,argv)
int argc;
char **argv;
{
int i,j;
for (i = 1; i < argc; i++) {
if (preload(argv[i],0) == FAIL) {
exit(1);
}
}
printf("Preloaded all\n");
for (j = 0; j < 10; j++) {
for (i = 1; i < argc; i++) {
printf("Executing \"%s\" for the %dth time\n",argv[i],j+1);
execute(argv[i],"");
}
}
for (i = 1; i < argc; i++) {
if (unload(argv[i]) == FAIL) {
exit(1);
}
}
}
int preload(progname,memneed) /* Preload an executable */
char *progname;
long memneed;
{
long basaddr;
int i, fd;
if (memneed == 0) {
memneed = DEFMNEED; /* Default mem for heap and stack */
}
for (i = 0; i < MAXLOADED; i++) {
if (load_img[i].basepag == 0L) { /* Found an unused slot */
break;
}
}
if (i == MAXLOADED) { /* All slots in use */
fprintf(stderr,"Max no. of programs (%d) loaded\n",MAXLOADED);
return FAIL;
}
if ((fd = Fopen(progname,0)) < 0) { /* Progname must exist as file */
fprintf(stderr,"Cannot open %s\n",progname);
return FAIL;
}
Fclose(fd);
basaddr = Pexec(3,progname,"",(char *)0);
if (basaddr == -66) { /* Program file in wrong format */
Fclose(fd); /* This fixes a GEMDOS bug */
fprintf(stderr,"%s not in TOS program format\n",progname);
return FAIL;
}
if (basaddr < 0) { /* Any other error */
fprintf(stderr,"%s failed with error code %d\n",progname,basaddr);
return FAIL;
}
strcpy(load_img[i].name,progname);
load_img[i].basepag = basaddr;
/* Now add to memneed the program's own requirements */
memneed += 0x100 + /* Base page */
((long *)basaddr)[3] + /* Text length */
((long *)basaddr)[5] + /* Data length */
((long *)basaddr)[7] + /* Bss length */
1; /* For even adjustment */
memneed &= ~1; /* Make it even */
Mshrink(basaddr,memneed); /* Now shrink to required size */
return OK;
}
int unload(progname) /* Unload an executable */
char *progname;
{
int i;
for (i = 0; i < MAXLOADED; i++) {
if ((load_img[i].basepag != 0L)
&& !strcmp(load_img[i].name,progname)) { /* Found it */
Mfree(load_img[i].basepag); /* Free it */
load_img[i].basepag = 0L; /* Mark slot unused */
return OK;
}
}
fprintf(stderr,"%s: command was not loaded\n",progname);
return FAIL;
}
int execute(cmd,tail) /* Execute a preloaded program */
char *cmd, *tail; /* Prog. path & argstring */
{
int err_co, i;
long bp, newbp;
char newtail[128];
int v;
for (i = 0; i < MAXLOADED; i++) {
if ((load_img[i].basepag != 0L)
&& !strcmp(cmd,load_img[i].name)) { /* Found it */
break;
}
}
if (i == MAXLOADED) { /* Not found */
fprintf(stderr,"%s: command was not loaded\n",cmd);
return FAIL;
}
if (strlen(tail) >= 128) { /* Tail must not be too long */
fprintf(stderr,"%s: command tail too long\n",cmd);
return FAIL;
}
bp = load_img[i].basepag; /* Just for short */
strcpy(newtail+1,tail); /* Prepare real tail */
newtail[0] = (unsigned)strlen(tail); /* Length byte */
newbp = (long)Pexec(5,(char *)0,newtail,(char *)0); /* Create basepage */
Mshrink(newbp,256); /* Shrink to 256 bytes */
for (v = 1; v < 8; v++) { /* Copy over lengths and vectors */
((long *)newbp)[v] = ((long *)bp)[v];/* from existing basepage */
}
err_co = Pexec(4,(char *)0,newbp,(char *)0); /* Now execute it */
Mfree(((long *)newbp)[11]); /* Free environment space */
Mfree(newbp); /* and the basepage itself */
return err_co;
}
---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8
Technical Details
Message-ID:
<1028@philmds.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!ames!sun-barr!texsun!pitstop!sundc!seismo!uunet!mcvax!hp4nl!phigate!philmds!leoShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!ames!sun-barr!texsun!pitstop!sundc!seismo!uunet!mcvax!hp4nl!phigate!philmds!leo From: leo@philmds.UUCP (Leo de Wit) Newsgroups: comp.sys.atari.st Subject: Preloading revised Message-ID: <1028@philmds.UUCP> Date: 11 May 89 07:10:39 GMT Reply-To: leo@philmds.UUCP (Leo de Wit) Organization: Philips I&E DTS Eindhoven Lines: 167