CWPLCAP%PACEVM.BITNET@cunyvm.cuny.edu (Anthony Passante) (06/22/89)
DEAR RELAY,( VERY VERY SORRY FOR THE LONG APPEND ) I wrote to you on Friday 06/16 under the name "DESPERATELY TRYING". I discussed my problem with multitasking on the Amiga with C. The problem was (and still is) that I can't get two tasks to run at the same time. Infact, I cannot even get one task added from the main program. I believe that all is set up correctly, but, when I step through the code in the debugger, the system locks up at the statement AddTask(). I have received and tried few suggestions, but, nothing has worked so far. So, I have uploaded my source code in hope that someone who is more familiar with the system and multitasking may be able to assist me. All suggestions are greatly appreciated.(again, sorry for long append) #include <stdio.h> #include <exec/types.h> #include <exec/tasks.h> #include <exec/memory.h> #include <exec/ports.h> #include <exec/semaphores.h> #include <exec/execbase.h> #define bufsize 4 #define nitems 4 #define STACK_SIZE 4000 APTR AllocMem(); struct string_msg { struct Message str_message; char string81|; }; int qbufsize|; /* and | represent square brackets */ int mutex, filled, empty; int count = 0; int front = 1; int rear = 0; void wait(sig_var) /***************/ int *sig_var; { struct SignalSemaphore *semaphore; int not_finished; not_finished = 1; semaphore = (struct SignalSemaphore *) FindSemaphore("MuxSemaphore"); if (semaphore != NULL) { do { ObtainSemaphore(Semaphore); if (*sig_var > 0) { --(*sig_var); not_finished = 0; } ReleaseSemaphore(semaphore); } while (not_finished); } else { printf("Could not find MuxSemaphore.\n"); exit(1); } return; } void signal(sig_var) /****************/ int *sig_var; { struct SignalSemaphore *semaphore; semaphore = (struct SignalSemaphore *) FindSemaphore("MuxSemaphore"); if (semaphore != NULL) { ObtainSemaphore(semaphore); ++(*sig_var); }ReleaseSemaphore(semaphore); } else { printf("Could not find MuxSemaphore.\n"); exit(1); } return; } void addtoq(x) /*******************/ int *x; { count = count + 1; rear = (rear % bufsize) + 1; qrear| = *x;/* the is left square braket and | right sqr. brkt */ } void deletefromq(x) /*********************/ int *x; { count = count - 1; *x = qfront|;/* | are square brackets */ front = (front % bufsize) + 1; } void produce() /***********************/ { int item; struct string_msg *message; struct MsgPort *output_port; output_port = (struct MsgPort *) FindPort("Output Port"); for(item = 1;item <= nitems; item++) { wait(&mutex); wait(&empty); addtoq(&item); message = (struct string_msg *) AllocMem(sizeof(struct string_msg), MEMF_CLEAR MEMF_PUBLIC); if (message != NULL && output_port != NULL) { sprintf(message->string, "%d from P", item); PutMsg(output_port, message); } signal(&mutex); signal(&filled); } message = (struct string_msg *) AllocMem(sizeof(struct string_msg), MEMF_CLEAR MEMF_PUBLIC); if (message != NULL && output_port != NULL) { strcpy(message->string, "exit P"); PutMsg(output_port, message); } RemTask(FindTask(NULL)); } void consume() /************************/ { int item; struct string_msg *message; struct MsgPort *output_port; output_port = (struct MsgPort *) FindPort("Output Port"); do { wait(&filled); wait(&mutex); deletefromq(&item); essage = (struct string_msg *) AllocMem(sizeof(struct string_msg), MEMF_CLEAR MEMF_PUBLIC); if (message != NULL && output_port != NULL) { sprintf(message->string, "%d from C", item); PutMsg(output_port, message); } signal(&mutex); signal(&empty); } while(item != nitems); message = (struct string_msg *) AllocMem(sizeof(struct string_msg), MEMF_CLEAR MEMF_PUBLIC); if (message != NULL && output_port != NULL) { strcpy(message->string, "exit C"); PutMsg(output_port, message); } RemTask(FindTask(NULL)); } main() /**********************************/ { extern struct ExecBase *SysBase; struct Task *makeit; struct Task *eatit; struct MsgPort output_port; struct string_msg *message; int makeit_not_done; int eatit_not_done; struct SignalSemaphore MuxSemaphore; InitSemaphore(&MuxSemaphore); MuxSemaphore.ss_Link.ln_Name = "MuxSemaphore"; MuxSemaphore.ss_Link.ln_Pri = 0; MuxSemaphore.ss_Link.ln_Type = NT_SEMAPHORE; Enqueue(&SysBase->SemaphoreList, &MuxSemaphore); makeit = (struct Task *) AllocMem(sizeof(struct Task), MEMF_PUBLIC MEMF_CLEAR); makeit->tc_SPLower = (APTR) AllocMem(STACK_SIZE, 0); makeit->tc_SPUpper = (APTR) ((ULONG) (makeit->tc_SPLower) + STACK_SIZE); makeit->tc_SPReg = makeit->tc_SPUpper; makeit->tc_Node.ln_Type = NT_TASK; makeit->tc_Node.ln_Name = "makeit.task"; eatit = (struct Task *) AllocMem(sizeof(struct Task), MEMF_PUBLIC MEMF_CLEAR); eatit->tc_SPLower = (APTR) AllocMem(STACK_SIZE, 0); eatit->tc_SPUpper = (APTR) ((ULONG) (eatit->tc_SPLower) + STACK_SIZE); eatit->tc_SPReg = eatit->tc_SPUpper; eatit->tc_Node.ln_Type = NT_TASK; eatit->tc_Node.ln_Name = "eatit.task"; mutex = 1; filled = 0; empty = 1; output_port.mp_Node.ln_Name = "Output Port"; output_port.mp_Node.ln_Type = NT_MSGPORT; AddPort(&output_port); AddTask(makeit, produce, 0); /* THIS IS WHERE THE PROG HALTS */ AddTask(eatit, consume, 0); /* DOES NOT GET ANY FURTHER THAN HERE* makeit_not_done = 1; eatit_not_done = 1; while(makeit_not_done eatit_not_done) { message = (struct string_msg *) WaitPort(&output_port); message = (struct string_msg *) GetMsg(&output_port); printf("%s\n", message->string); if (strcmp(message->string, "exit P") == 0) makeit_not_done = 0; if (strcmp(message->string, "exit C") == 0) eatit_not_done = 0; FreeMem(message, sizeof(struct string_msg)); } while (FindTask("makeit.task") != NULL FindTask("eatit.task") != NULL) ; RemPort(&output_port); RemSemaphore(&MuxSemaphore); FreeMem(makeit->tc_SPLower, STACK_SIZE); FreeMem(eatit->tc_SPLower, STACK_SIZE); FreeMem(makeit, sizeof(struct Task)); FreeMem(eatit, sizeof(struct Task)); }