jimg@hp-ptp.HP.COM (Jim_Garrison) (09/14/90)
Hello, I've trying to use Amiga Semaphores, as a mechanism to let only one program access a particular resource at a time. I'm using the Amiga Programmers Reference by Eugene Mortimer, as a reference for using the semaphores. I seem to recall that there is either some problem with the description of semaphores in this book, or there are problems with the way Amiga semaphores work. I'm using an A2500 with Amigados 1.3 and Lattice 5.05 C compiler. I've provided some code which seems like it should work, but doesn't. If two copies of this program are run at the same time, the first copy should get the resource, and the second copy should wait until the first copy is done. Right now, FindSemaphore("test1") returns null in both programs, so they both access the resource, and mess each other up. Am I using FindSemaphore() wrong, or am I using AddSemaphore() incorrectly? I'd sure appreciate any light shed on this. Thanks in advance, Jim Garrison (jimg@hpiatmh) Hewlett Packard Industrial Applications Center (408) 746-5349 Sample program follows: /* IPC.C - This is a test program, so I can see how Amiga semaphores work. * * 09/13/90 - Created by Jim Garrison. */ #include <stdio.h> #include <libraries/dosextens.h> #include <exec/semaphores.h> #include <exec/memory.h> main() { struct SignalSemaphore *sem; int error; sem = FindSemaphore("test1"); if (!sem) { sem = AllocMem(sizeof(struct SignalSemaphore), MEMF_PUBLIC | MEMF_CLEAR); printf("Making a semaphore\n"); sem->ss_Link.ln_Name = "test1"; sem->ss_Link.ln_Pri = 1; error = AddSemaphore(sem); printf("Addsem error = %d\n", error); } else printf("Got an existing semaphore\n"); ObtainSemaphore(sem); printf("Pausing ....\n"); /* Do something with some resource. */ ReleaseSemaphore(sem); printf("Done\n"); }
jjszucs@cbmvax.commodore.com (John J. Szucs) (09/18/90)
In article <2290004@hp-ptp.HP.COM> jimg@hp-ptp.HP.COM (Jim_Garrison) writes: > >Hello, > >I've trying to use Amiga Semaphores, as a mechanism to let only one program >access a particular resource at a time. I'm using the Amiga Programmers >Reference by Eugene Mortimer, as a reference for using the semaphores. I >seem to recall that there is either some problem with the description of >semaphores in this book, or there are problems with the way Amiga semaphores >work. I'm using an A2500 with Amigados 1.3 and Lattice 5.05 C compiler. > [stuff deleted] > >Thanks in advance, > > >Jim Garrison (jimg@hpiatmh) >Hewlett Packard >Industrial Applications Center >(408) 746-5349 [code deleted] Under Kickstart/Workbench Release 1.3, the exec.library/AddSemaphore function does not work properly. Use the following: void LocalAddSemaphore(struct SignalSemaphore *SignalSemaphore) { SignalSemaphore-.ss_Link.ln_Type=NT_SIGNALSEM; InitSemaphore(SignalSemaphore); Forbid(); Enqueue(&SysBase->SemaphoreList,SignalSemaphore); Permit(); } This is documented in the AutoDocs (available from CATS). The function is correct under Kickstart/Workbench Release 2.0. ================================================================================ || John J. Szucs || The opinions expressed are my own and || || Systems Evaluation Group || in no way represent the opinions or || || Product Assurance Department || policies of Commodore Technology, Inc. || || Commodore Technology, Inc. || or any associated entity. || ================================================================================ ...{rutgers|uunet|pyramid}!cbmvax!jjszucs jjszucs@cbmvax.commodore.com "Everything is deeply intertwingled." - Ted Nelson, Computer Lib/Dream Machines
jimg@hp-ptp.HP.COM (Jim_Garrison) (09/18/90)
jjszucs@cbmvax.commodore.com (John J. Szucs) / 10:40 am Sep 17, 1990 / writes: > >Under Kickstart/Workbench Release 1.3, the exec.library/AddSemaphore function >does not work properly. Aha! Great! Thanks a bunch, now I can get back to work. (Working a on a spooling program to print 2 pages per page on a LaserJet (or compatible) printer.) > >Use the following: > >void LocalAddSemaphore(struct SignalSemaphore *SignalSemaphore) >{ > SignalSemaphore-.ss_Link.ln_Type=NT_SIGNALSEM; > InitSemaphore(SignalSemaphore); > Forbid(); > Enqueue(&SysBase->SemaphoreList,SignalSemaphore); > Permit(); >} > Okay! >This is documented in the AutoDocs (available from CATS). Uh, where can I write to, so I can get these? I'd sure like to get these docs that relate to AmigaDOS 2.0 also. > >The function is correct under Kickstart/Workbench Release 2.0. ^^^^^^^^ AddSemaphore, I presume. Now, if I can only get 2.0! Thanks John, for your help, I appreciate being able to get this kind of support over the net. Regards, Jim Garrison Hewlett Packard
jjszucs@cbmvax.commodore.com (John J. Szucs) (09/20/90)
In article <2290005@hp-ptp.HP.COM> jimg@hp-ptp.HP.COM (Jim_Garrison) writes: [referring to AutoDocs and other developer materials] >Uh, where can I write to, so I can get these? I'd sure like to get these >docs that relate to AmigaDOS 2.0 also. CATS is Commodore Applications and Technical Support (previously known as Commodore-Amiga Technical Support). The address is: Commodore Business Machines, Inc. CATS 1200 Wilson Drive West Chester PA 19380 CATS can provide you with all the necessary information on availibility, prices, etc. >Thanks John, for your help, I appreciate being able to get this kind of support >over the net. I'm glad to help! >Jim Garrison ================================================================================ || John J. Szucs || The opinions expressed are my own and || || Systems Evaluation Group || in no way represent the opinions or || || Product Assurance Department || policies of Commodore Technology, Inc. || || Commodore Technology, Inc. || or any associated entity. || ================================================================================ ...{rutgers|uunet|pyramid}!cbmvax!jjszucs jjszucs@cbmvax.commodore.com "Everything is deeply intertwingled." - Ted Nelson, Computer Lib/Dream Machines
valentin@cbmvax.commodore.com (Valentin Pepelea) (09/21/90)
In article <2290004@hp-ptp.HP.COM> jimg@hp-ptp.HP.COM (Jim_Garrison) writes: > > I've trying to use Amiga Semaphores, as a mechanism to let only one program > access a particular resource at a time. I'm using the Amiga Programmers > Reference by Eugene Mortimer, as a reference for using the semaphores. I > seem to recall that there is either some problem with the description of > semaphores in this book, or there are problems with the way Amiga semaphores > work. I'm using an A2500 with Amigados 1.3 and Lattice 5.05 C compiler. The problem is with the semaphore calls. First of all, the AddSemaphore() function expect a parameter in the wrong register. Take a look ROM Kernel Reference Manual: Includes&Autodocs for a work-around. The blue-greenish manual. Valentin -- The Goddess of democracy? "The tyrants Name: Valentin Pepelea may distroy a statue, but they cannot Phone: (215) 431-9327 kill a god." UseNet: cbmvax!valentin@uunet.uu.net - Ancient Chinese Proverb Claimer: I not Commodore spokesman be
jimg@hp-ptp.HP.COM (Jim_Garrison) (09/21/90)
Hello again, I tried adding the LocalAddSemaphores() which John Suchs suggested to my program. It still doesn't work! Please note that I am using NAMED semaphores here, maybe that's what's causing my problems. Even after I have run this program once (or more) FindSemaphore(name) still returns NULL. Do named semaphores work? Or am I still not initializing my named semaphore incorrectly? What I want to happen is that if two of these programs are run at one time, only one will get (Create) the semaphore and the other will wait (sleep) until the first one calls ReleaseSemaphore(sem). This way, I can queue up any number of copies of this program, and each one will wait it's turn for the resource (the printer) which cannot be shared. Thanks again, Jim Garrison (jimg@hpiatmh) Hewlett Packard Industrial Applications Center (408) 746-5349 PS - I have sent in for the ordering information, so I can get the autodocs. Sample program follows: /* IPC.C - This is a test program, so I can see how Amiga semaphores work. * * 09/13/90 - Created by Jim Garrison. * 09/18/90 - Added in LocalAddSemaphore() suggested by John Suchs. */ #include <stdio.h> #include <libraries/dosextens.h> #include <exec/execbase.h> #include <exec/semaphores.h> #include <exec/memory.h> extern ExecBase *SysBase; struct IntuitionBase *IB; main() { struct SignalSemaphore *sem; int error; /* This next ALWAYS returns a NULL, no matter how many times I run this * program. */ sem = FindSemaphore("test1"); if (!sem) { /* I'm typing this in from memory, so this next line might not be right * but I am doing it correctly in the code on my Amiga at home. */ if ((IB = OpenLibrary("intuition.library", LIBRARY_REV)) == NULL) exit(1); sem = AllocMem(sizeof(struct SignalSemaphore), MEMF_PUBLIC | MEMF_CLEAR); printf("Making a semaphore\n"); LocalAddSemaphore(sem, "test1"); } else printf("Got an existing semaphore\n"); ObtainSemaphore(sem); printf("Pausing ....\n"); /* Do something with some resource. */ ReleaseSemaphore(sem); printf("Done\n"); } void LocalAddSemaphore(struct SignalSemaphore *SignalSemaphore, char *name) { SignalSemaphore->ss_Link.ln_Type=NT_SIGNALSEM; SignalSemaphore->ss_Link.ln_Name = name; SignalSemaphore->ss_Link.ln_Pri = 1; InitSemaphore(SignalSemaphore); Forbid(); Enqueue(&SysBase->SemaphoreList,SignalSemaphore); Permit(); }
rosenber@ra.abo.fi (Robin Rosenberg INF) (09/23/90)
Clearly the documentation on AddSemaphore() is misleading. Set the
name and priority _after_ InitSemaphore(). You don't need to set the
type since InitSemahore() does that. So it becomes:
(Could this be added to introduction to comp.sys.amiga.tech since a lot of
people get bitten by AddSemaphore() )
void LocalAddSemaphore(struct SignalSemaphore *SignalSemaphore, char *name)
{
InitSemaphore(SignalSemaphore);
SignalSemaphore->ss_Link.ln_Name = name;
SignalSemaphore->ss_Link.ln_Pri = 1;
Forbid();
Enqueue(&SysBase->SemaphoreList,SignalSemaphore);
Permit();
}
griffith@eecs.cs.pdx.edu (Michael Griffith) (09/24/90)
jimg@hp-ptp.HP.COM (Jim_Garrison) writes: >Hello again, >I tried adding the LocalAddSemaphores() which John Suchs suggested to my >program. It still doesn't work! Please note that I am using NAMED semaphores >here, maybe that's what's causing my problems. Even after I have run this >program once (or more) FindSemaphore(name) still returns NULL. Do named >semaphores work? Or am I still not initializing my named semaphore >incorrectly? What I want to happen is that if two of these programs are run >/* IPC.C - This is a test program, so I can see how Amiga semaphores work. > * > * 09/13/90 - Created by Jim Garrison. > * 09/18/90 - Added in LocalAddSemaphore() suggested by John Suchs. > */ >void LocalAddSemaphore(struct SignalSemaphore *SignalSemaphore, char *name) >{ > SignalSemaphore->ss_Link.ln_Type=NT_SIGNALSEM; > SignalSemaphore->ss_Link.ln_Name = name; > SignalSemaphore->ss_Link.ln_Pri = 1; > InitSemaphore(SignalSemaphore); > Forbid(); > Enqueue(&SysBase->SemaphoreList,SignalSemaphore); > Permit(); >} It seems to me that your problem is thus: You are temporarily allocating space (for the duration of your program) for the name string in your node, but rather than making a permanent copy you are just setting the pointer ln_Name to point to it. Your program then terminates, freeing the memory allocated for the string. Something else uses this memory, overwriting your string and making it impossible for FindSemaphore to locate it. Try the following inserted in place of the line where you set ln_Name: SignalSemaphore->ss_Link.ln_Name = AllocMem(sizeof(char)*(strlen(name)+1), MEMF_PUBLIC); strcpy(SignalSemaphore->ss_Link.ln_Name,name); /* I know this could be more elegant, and you should check to make sure the allocation is succesful, but since it's just a test... ;) */ Anyways, hope that helps. | Michael Griffith | If I had an opinion it certainly | | griffith@eecs.ee.pdx.edu | wouldn't be the same one as | | ...!tektronix!psueea!eecs!griffith | Portland State University anyways. |
valentin@cbmvax.commodore.com (Valentin Pepelea) (09/25/90)
In article <2290006@hp-ptp.HP.COM> jimg@hp-ptp.HP.COM (Jim_Garrison) writes: > > I tried adding the LocalAddSemaphores() which John Suchs suggested to my > program. It still doesn't work! Please note that I am using NAMED semaphores > here, maybe that's what's causing my problems. Even after I have run this > program once (or more) FindSemaphore(name) still returns NULL. Do named > semaphores work? > ... > Sample program follows: > ... > LocalAddSemaphore(sem, "test1"); All right, here's what's happening. While you are allocating the semaphore structure dynamically, the string "test1" is part of the program's global variables. When the program exits, all variables disappear. Therefore when you first run the program, the semaphore is indeed added properly to the system. But as soon as the program exits, the "test1" string is freed, and the memory in which it resided is likely to be soon overwritten. Do an AllocMem() for the name field of the semaphore, then copy the string in there. That will do it. Valentin -- The Goddess of democracy? "The tyrants Name: Valentin Pepelea may distroy a statue, but they cannot Phone: (215) 431-9327 kill a god." UseNet: cbmvax!valentin@uunet.uu.net - Ancient Chinese Proverb Claimer: I not Commodore spokesman be
jimg@hp-ptp.HP.COM (Jim_Garrison) (09/25/90)
Well, I did try InitSemaphore() before initializing the name and priority of my semaphore. I also made sure that I allocated (AllocMem'ed) some space for the semaphore name. IT STILL DOESN'T WORK! Boy, I'd sure appreciate it if someone could mail me, or post some source code for named semaphores that works (Especially the FindSemaphore() part.) I even tried booting up as a 68000, instead of the 68030, to no avail. Darn, and I thought this whole thing with semaphores was going to take me a few minutes! Thanks everyone for your replies and suggestions, Jim Garrison Hewlett Packard (408) 746-5349
jimg@hp-ptp.HP.COM (Jim_Garrison) (09/26/90)
I just got some messages from another machine, that indicated someone has been trying to mail me something related to this problem. It appears that they're trying to mail to me on the machine where I posted these notes from, but I don't have a mail account on that machine. If you are trying to mail me, please try: jimg@hpiatmh.hp.com or just post it to notes, if it's not too big. Thanks again, Jim Garrison Hewlett Packard jimg@hpiatmh.hp.com (408) 746-5349
jimg@hp-ptp.HP.COM (Jim_Garrison) (09/27/90)
Yahoo, thanks to Peter Xrbfk, I now have working Amiga semaphores. I guess that my problem was that FindSemaphore() doesn't work either. I have included Peter's example program which works fine for me. As someone else mentioned, I think it might be a good idea to include this information in the Amiga introduction. Thank you all for your help, Jim Garrison Hewlett Packard jimg@hpiatmh (408) 746-5349 >Hi, Jim. > >I suppose it was I who tried to post this to you at the wrong address. > >This works on my A500, ie. creates the semaphore once, and finds it >afterwards. It did not work with FindSemaphore() which seems to have >a slight hitch in that it expects the name in A1 and not in A0 as indicated >in the .fd file. One could consider this to be an error of the compiler >makers who have not noticed this. > >With Aztec C 3.4 this program does the trick, but it shouldn't >be compiler dependent. > >I hope this works for you too. > > > - Peter (poe@daimi.aau.dk) > ---- cut here ---- /* sem.c */ /* Created 26-Sep-90 by Peter Xrbfk. This works on my A500 (KS 33.180 / WB 34.20) */ #include "exec/types.h" #include "exec/semaphores.h" #include "exec/execbase.h" #include "exec/memory.h" #include "stdio.h" struct Node *FindName(); void *AllocMem(); char *strcpy(); extern struct ExecBase *SysBase; /* Define private version of FindSemaphore() because FindSemaphore() really expects the namepointer in A1 and not in A0 as indicated in the .fd files */ #define FindSem(s) (struct SignalSemaphore *)FindName(&SysBase->SemaphoreList,s) main() { struct SignalSemaphore *ss; char *str; if(!(ss = FindSem("MySem"))) { printf("didn't find semaphore\n"); ss = (struct SignalSemaphore *) AllocMem((long)sizeof(struct SignalSemaphore), MEMF_PUBLIC|MEMF_CLEAR); /* assume ok */ InitSemaphore(ss); str = AllocMem(10L,MEMF_PUBLIC); ss->ss_Link.ln_Name = strcpy(str,"MySem"); ss->ss_Link.ln_Pri = 0; printf("adding it\n"); /* add it */ Forbid(); AddTail(&SysBase->SemaphoreList,ss); Permit(); printf("semaphore created and added\n"); } /* use it for something */ ObtainSemaphore(ss); printf("bla\n"); ReleaseSemaphore(ss); }