Пример #1
0
int main()
{
    struct Process *child;
    
    struct TagItem tags[] =
    {
	{ NP_Entry,         (IPTR) entry              },
    	{ NP_Cli,           (IPTR) TRUE               },
        { NP_Name,          (IPTR) "test"             },
        { NP_NotifyOnDeath, (IPTR) TRUE               },
        { TAG_DONE,         0                         }
    };
    
    child = CreateNewProc(tags);
    
    if(child)
    {
	ULONG childid = GetETask((struct Task*) child)->et_UniqueID;
	Printf("Waiting for child with id %d\n", childid);
	ChildWait(childid);
	Printf("Child exited, freeing child\n");
	ChildFree(childid);
    }
    else
	PrintFault(IoErr(), "Couldn't create child process");
    return 0;
}
Пример #2
0
int main()
{
    tmpname = mktemp("T:flockXXXXXX");
    int fd = open(tmpname, O_CREAT);
    TEST((fd != -1));

    TEST((flock(fd, LOCK_SH|LOCK_NB) == 0));
    TEST((flock(fd, LOCK_UN) == 0));

    TEST((flock(fd, LOCK_EX|LOCK_NB) == 0));
    TEST((flock(fd, LOCK_UN) == 0));

    TEST((flock(fd, LOCK_SH) == 0));
    TEST((flock(fd, LOCK_UN) == 0));

    TEST((flock(fd, LOCK_EX) == 0));
    TEST((flock(fd, LOCK_UN) == 0));

    close(fd);

    /* Create NPROCS processes increasing counter ITERATIONS times in an ugly 
       way */
    int counter = 0;
    struct Process *procs[NPROCS];
    ULONG ids[NPROCS];
    struct TagItem tags[] =
    {
	{ NP_Entry,         (IPTR) entry     },
        { NP_Name,          (IPTR) "flocker" },
        { NP_Output,        (IPTR) Output()  },
        { NP_CloseOutput,   (IPTR) FALSE     },
        { NP_UserData,      (IPTR) &counter  },
        { NP_NotifyOnDeath, (IPTR) TRUE      },
        { TAG_DONE,         0                }
    };

    int i;
    InitSemaphore(&sem);
    for(i = 0; i < NPROCS; i++)
    {
	procs[i] = CreateNewProc(tags);
	TEST((procs[i]));
	ids[i] = GetETask(procs[i])->et_UniqueID;
	Signal((struct Task *)procs[i], SIGBREAKF_CTRL_C);
    }
    
    for(i = 0; i < NPROCS; i++)
    {
	ChildWait(ids[i]);
	ChildFree(ids[i]);
    }
    putchar('\n');
    
    TEST((counter == NPROCS * ITERATIONS));
    
    cleanup();
    return OK;
}
Пример #3
0
int uae_start_thread (const TCHAR *name, void *(*f)(void *), void *arg, uae_thread_id *tid)
{
    struct MsgPort *replyport;
    struct Process *newtask = NULL;
    struct TagItem procTags[] =
    {
        { NP_Name,	   (IPTR) NULL},
        { NP_StackSize,	   (IPTR)(64 * 1024)},
        { NP_Entry,	   (IPTR) do_thread},
        //{ NP_Output,		   Output ()},
        //{ NP_Input,		   Input ()},
        //{ NP_CloseOutput,	   FALSE},
        //{ NP_CloseInput,	   FALSE},
        { TAG_DONE, 0}
    };

#warning Do we need to care for priorities here? WinUAE does..
    if(!name)
        procTags[0].ti_Data = (IPTR)default_name;
    else
        procTags[0].ti_Data = (IPTR)name;

    bug("[JUAE:PX] %s('%s', f %lx, arg %lx, tid %lx)\n", __PRETTY_FUNCTION__, procTags[0].ti_Data, f, arg, tid);

    replyport = CreateMsgPort();
    if(!replyport) {
        write_log("ERROR: Unable to create MsgPort!\n");
    }

    newtask = CreateNewProc (procTags);

    bug("[JUAE:PX] %s: Process @ %p, MsgPort @ %p\n", __PRETTY_FUNCTION__, newtask, newtask->pr_MsgPort);

    if(newtask) {
        struct startupmsg msg;

        msg.msg.mn_ReplyPort = replyport;
        msg.msg.mn_Length    = sizeof msg;
        msg.func             = f;
        msg.arg              = arg;
        PutMsg (&newtask->pr_MsgPort, (struct Message*)&msg);
        WaitPort (replyport);
    }
    DeleteMsgPort (replyport);

    if(tid) {
        *tid=newtask;
    }

    return (newtask != 0);
}
Пример #4
0
static int WBOpen(LIBBASETYPEPTR LIBBASE)
{
    ObtainSemaphore(&(WorkbenchBase->wb_InitializationSemaphore));

    if (!(WorkbenchBase->wb_Initialized))
    {
        struct CommandLineInterface *cli;
        
        /* Duplicate the search path ---------------------------------------*/
        if ((cli = Cli()) != NULL)
        {
            WorkbenchBase->wb_SearchPath = DuplicateSearchPath
            (
                cli->cli_CommandDir
            );
        }
    
        const struct TagItem 	     tags[]=
        {
            {NP_Entry    , (IPTR)WorkbenchHandler      },
            {NP_Name     , (IPTR)"Workbench Handler"   },
			{NP_UserData , (IPTR)WorkbenchBase      },
			{NP_StackSize, 8129 			           },
            {TAG_DONE    , 0     	    	    	   }
        };
        
        /* Start workbench handler -----------------------------------------*/
        if ((CreateNewProc(tags)) != NULL)
        {
            /* Prevent expunging while the handler is running */
            AROS_ATOMIC_INC(WorkbenchBase->LibNode.lib_OpenCnt);
        }
        else
        {
            // FIXME: free resources
            return FALSE;
        }
        
        WorkbenchBase->wb_Initialized = TRUE;
    }

    ReleaseSemaphore(&(WorkbenchBase->wb_InitializationSemaphore));

    return TRUE;
} /* L_OpenLib */
Пример #5
0
int main()
{
    struct Process *child;
    
    struct TagItem tags[] =
    {
	{ NP_Entry,         (IPTR) entry              },
    	{ NP_Cli,           (IPTR) TRUE               },
        { NP_Name,          (IPTR) "test"             },
        { NP_NotifyOnDeath, (IPTR) TRUE               },
        { TAG_DONE,         0                         }
    };
    
    child = CreateNewProc(tags);
    
    if(child)
    {
	ULONG childstatus;
	ULONG childid = GetETask((struct Task*) child)->et_UniqueID;
	Printf("Checking status value for non-existing child id\n");
	childstatus = ChildStatus(-1);
	assert(childstatus == CHILD_NOTFOUND);
	Printf("Result: CHILD_NOTFOUND\n");
	Printf("Checking status value for running child id\n");
	childstatus = ChildStatus(childid);
	assert(childstatus == CHILD_ACTIVE);
	Printf("Result: CHILD_ACTIVE\n");
	ChildWait(childid);
	Printf("Checking status value for died child id\n");
	childstatus = ChildStatus(childid);
	assert(childstatus == CHILD_EXITED);
	Printf("Result: CHILD_EXITED\n");
	ChildFree(childid);
	Printf("Checking status value for freed child id\n");
	childstatus = ChildStatus(childid);
	assert(childstatus == CHILD_NOTFOUND);
	Printf("Result: CHILD_NOTFOUND\n");
    }
    else
	PrintFault(IoErr(), "Couldn't create child process");
    return 0;
}
Пример #6
0
ULONG _AHIsub_Start(
    ULONG Flags,
    struct AHIAudioCtrlDrv *AudioCtrl,
    struct DriverBase*      AHIsubBase )
{
  struct FilesaveBase* FilesaveBase = (struct FilesaveBase*) AHIsubBase;

  AHIsub_Stop(Flags, AudioCtrl);

  if(Flags & AHISF_PLAY)
  {
    ULONG savebufferlength;

    if(!(dd->fs_MixBuffer = AllocVec(AudioCtrl->ahiac_BuffSize, MEMF_ANY)))
      return AHIE_NOMEM;

    dd->fs_SaveBufferSize = AudioCtrl->ahiac_MaxBuffSamples;

    // S16 has two buffers (L/R) instead
    if((AudioCtrl->ahiac_Flags & AHIACF_STEREO) && dd->fs_Format != FORMAT_S16)
    {
      dd->fs_SaveBufferSize <<=1;
    }

    if(dd->fs_SaveBufferSize < SAVEBUFFERSIZE)
    {
      dd->fs_SaveBufferSize = SAVEBUFFERSIZE;
    }

    savebufferlength = dd->fs_SaveBufferSize;


    switch(dd->fs_Format)
    {
      case FORMAT_8SVX:
        break;

      case FORMAT_AIFF:
        savebufferlength <<= 1;
        break;

      case FORMAT_AIFC:
        savebufferlength <<= 1;
        break;

      case FORMAT_S16:
        savebufferlength <<= 1;
        break;

      case FORMAT_WAVE:
        savebufferlength <<= 1;
        break;

      default:
        break;
    }


    if(!(dd->fs_SaveBuffer = AllocVec(savebufferlength, MEMF_ANY)))
    {
      return AHIE_NOMEM;
    }

    if ((AudioCtrl->ahiac_Flags & AHIACF_STEREO) && dd->fs_Format == FORMAT_S16)
    {
      if(!(dd->fs_SaveBuffer2 = AllocVec(savebufferlength, MEMF_ANY)))
      {
        return AHIE_NOMEM;
      }
    }

    if(AslRequest(dd->fs_FileReq,NULL))
    {
      struct TagItem proctags[] =
      {
	{ NP_Entry,     (ULONG) SlaveEntry },
	{ NP_Name,      (ULONG) LibName    },
	{ NP_Priority,  -1                 }, // It's a number cruncher...
	{ NP_StackSize, 10000,             },
	{ TAG_DONE,     0                  }
      };

      Forbid();

      dd->fs_SlaveTask = CreateNewProc( proctags );
      
      if( dd->fs_SlaveTask != NULL )
      {
        dd->fs_SlaveTask->pr_Task.tc_UserData = AudioCtrl;
      }

      Permit();

      if(dd->fs_SlaveTask)
      {
        Wait(1L<<dd->fs_MasterSignal);  // Wait for slave to come alive
        if(dd->fs_SlaveTask == NULL)    // Is slave alive or dead?
        {
          return AHIE_UNKNOWN;
        }
      }
      else
      {
        return AHIE_NOMEM;
      }
    }
    else
    {
      if(IoErr())
      {
        return AHIE_NOMEM;    //error occured
      }
      else
      {
        return AHIE_ABORTED;  //requester cancelled
      }
    }
  }

  if(Flags & AHISF_RECORD)
  {
    if(!(dd->fs_RecBuffer = AllocVec(RECBUFFERSIZE*4,MEMF_ANY)))
    {
      return AHIE_NOMEM;
    }

    if(AslRequest(dd->fs_RecFileReq,NULL))
    {
      struct TagItem proctags[] =
      {
	{ NP_Entry,     (ULONG) RecSlaveEntry },
	{ NP_Name,      (ULONG) LibName       },
	{ NP_Priority,  1                     },  // Make it steady...
	{ TAG_DONE,     0                     }
      };

      Delay(TICKS_PER_SECOND);         // Wait for window to close etc...

      Forbid();

      dd->fs_RecSlaveTask = CreateNewProc( proctags );
	
      if( dd->fs_RecSlaveTask != NULL )
      {
        dd->fs_RecSlaveTask->pr_Task.tc_UserData = AudioCtrl;
      }

      Permit();

      if(dd->fs_RecSlaveTask)
      {
        Wait(1L<<dd->fs_RecMasterSignal);  // Wait for slave to come alive
        if(dd->fs_RecSlaveTask == NULL)    // Is slave alive or dead?
        {
          return AHIE_UNKNOWN;
        }
      }
      else
      {
        return AHIE_NOMEM;
      }
    }
    else
    {
      if(IoErr())
      {
        return AHIE_NOMEM;    //error occured
      }
      else
      {
        return AHIE_ABORTED;  //requester cancelled
      }
    }
  }

  return AHIE_OK;
}
Пример #7
0
pid_t __vfork(jmp_buf env)
{
    struct Task *this = FindTask(NULL);
    struct vfork_data *udata = AllocMem(sizeof(struct vfork_data), MEMF_ANY | MEMF_CLEAR);
    if(udata == NULL)
    {
	errno = ENOMEM;
	longjmp(env, -1);	
    }
    D(bug("__vfork: allocated udata %p\n", udata));
    bcopy(env, &udata->vfork_jump, sizeof(jmp_buf));

    struct TagItem tags[] =
    {
	{ NP_Entry,         (IPTR) launcher  },
	{ NP_CloseInput,    (IPTR) FALSE     },
	{ NP_CloseOutput,   (IPTR) FALSE     },
	{ NP_CloseError,    (IPTR) FALSE     },
        { NP_Cli,           (IPTR) TRUE      },
        { NP_Name,          (IPTR) "vfork()" },
        { NP_UserData,      (IPTR) udata     },
        { NP_NotifyOnDeath, (IPTR) TRUE      },
        { TAG_DONE,         0                }
    };

    udata->parent = this;
    
    struct arosc_privdata *ppriv = __get_arosc_privdata();
    udata->ppriv = ppriv;
    
    /* Store parent's vfork_data to restore it later */
    udata->prev = __get_arosc_privdata()->acpd_vfork_data;
    D(bug("__vfork: Saved old parent's vfork_data: %p\n", udata->prev));
                                        
    D(bug("__vfork: backuping startup buffer\n"));
    /* Backup startup buffer */
    CopyMem(&__aros_startup_jmp_buf, &udata->startup_jmp_buf, sizeof(jmp_buf));

    D(bug("__vfork: Allocating parent signal\n"));
    /* Allocate signal for child->parent communication */
    udata->parent_signal = AllocSignal(-1);
    if(udata->parent_signal == -1)
    {
	/* Couldn't allocate the signal, return -1 */
	FreeMem(udata, sizeof(struct vfork_data));
	errno = ENOMEM;
	longjmp(udata->vfork_jump, -1);    
    }
    
    D(bug("__vfork: Creating child\n"));
    udata->child = (struct Task*) CreateNewProc(tags);

    if(udata->child == NULL)
    {
	/* Something went wrong, return -1 */
	FreeMem(udata, sizeof(struct vfork_data));
	errno = ENOMEM; /* Most likely */
	longjmp(env, -1);
    }
    D(bug("__vfork: Child created %p, waiting to finish setup\n", udata->child));
    udata->child_id = GetETaskID(udata->child);
    D(bug("__vfork: Got unique child id: %d\n", udata->child_id));

    /* Wait for child to finish setup */
    Wait(1 << udata->parent_signal);
    
    if(udata->child_errno)
    {
	/* An error occured during child setup */
	errno = udata->child_errno;
	longjmp(env, -1);
    }
    
    D(bug("__vfork: Setting jmp_buf at %p in %p\n", __aros_startup, &__aros_startup_jmp_buf));
    if(setjmp(__aros_startup_jmp_buf))
    {
	D(bug("__vfork: child exited\n or executed\n"));

	if(!GETUDATA->child_executed)
	{
	    D(bug("__vfork: not executed\n"));
	    ((struct aros_startup*) GetIntETask(GETUDATA->child)->iet_startup)->as_startup_error = __aros_startup_error;
	    D(bug("__vfork: Signaling child\n"));
	    Signal(GETUDATA->child, 1 << GETUDATA->child_signal);
	}

	D(bug("__vfork: Waiting for child to finish using udata\n"));
	/* Wait for child to finish using GETUDATA */
	Wait(1 << GETUDATA->parent_signal);

	D(bug("__vfork: fflushing\n"));
	fflush(NULL);

	D(bug("__vfork: restoring old fd_array\n"));
	/* Restore parent's old fd_array */
	((struct arosc_privdata *) GetIntETask(GETUDATA->parent)->iet_acpd)->acpd_fd_mempool = GETUDATA->parent_acpd_fd_mempool;
	((struct arosc_privdata *) GetIntETask(GETUDATA->parent)->iet_acpd)->acpd_numslots = GETUDATA->parent_acpd_numslots;
	((struct arosc_privdata *) GetIntETask(GETUDATA->parent)->iet_acpd)->acpd_fd_array =  GETUDATA->parent_acpd_fd_array;

	D(bug("__vfork: restoring startup buffer\n"));
	/* Restore parent startup buffer */
	CopyMem(&GETUDATA->startup_jmp_buf, &__aros_startup_jmp_buf, sizeof(jmp_buf));

	D(bug("__vfork: freeing parent signal\n"));
	FreeSignal(GETUDATA->parent_signal);

        errno = GETUDATA->child_errno;
        
	FreeAndJump(GETUDATA);
	assert(0); /* not reached */
        return (pid_t) 1;
    }

    /* Remember parent fd descriptor table */
    udata->parent_acpd_fd_mempool = ppriv->acpd_fd_mempool;
    udata->parent_acpd_numslots = ppriv->acpd_numslots;
    udata->parent_acpd_fd_array = ppriv->acpd_fd_array;
    
    /* Pretend to be running as the child created by vfork */
    ppriv->acpd_vfork_data = udata;
    ppriv->acpd_flags |= PRETEND_CHILD;
    ppriv->acpd_fd_mempool = udata->cpriv->acpd_fd_mempool;
    ppriv->acpd_numslots = udata->cpriv->acpd_numslots;
    ppriv->acpd_fd_array = udata->cpriv->acpd_fd_array;
    
    D(bug("__vfork: Jumping to jmp_buf %p\n", &udata->vfork_jump));
    D(bug("__vfork: ip: %p, stack: %p\n", udata->vfork_jump[0].retaddr, udata->vfork_jump[0].regs[_JMPLEN - 1]));
    vfork_longjmp(udata->vfork_jump, 0);
    assert(0); /* not reached */
    return (pid_t) 0;
}
Пример #8
0
// Launch a generic process
int ASM L_IPC_Launch(
	REG(a0, struct ListLock *list),
	REG(a1, IPCData **storage),
	REG(a2, char *name),
	REG(d0, ULONG entry),
	REG(d1, ULONG stack),
	REG(d2, ULONG data),
	REG(a3, struct Library *dos_base),
	REG(a6, struct MyLibrary *libbase))
{
	struct LibData *libdata;
	IPCData *ipc;
	BOOL path=0;
	struct TagItem *tags;

	#ifdef __amigaos4__
	libbase = dopuslibbase_global;
	#endif
	
	// Want path?
	if (stack&IPCF_GETPATH) path=1;

	// Get data pointer
	libdata=(struct LibData *)libbase->ml_UserData;

	// Clear storage
	if (storage) *storage=0;

	// Allocate data
	if (!(ipc=AllocVec(sizeof(IPCData),MEMF_CLEAR)) ||
		!((tags=AllocVec(sizeof(struct TagItem)*8,MEMF_ANY))))
	{
		FreeVec(ipc);
		return 0;
	}

	// Store memory and list pointers
	ipc->memory=libdata->memory;
	ipc->list=list;

	// Fill out process tags
	tags[0].ti_Tag=NP_Entry;
	tags[0].ti_Data = IPC_GET_ENTRY(entry);
	tags[1].ti_Tag=NP_Name;
	tags[1].ti_Data=(ULONG)name;
	tags[2].ti_Tag=NP_WindowPtr;
	tags[2].ti_Data=(ULONG)-1;
	tags[3].ti_Tag=NP_StackSize;
	tags[3].ti_Data=IPCM_STACK(stack);
	tags[4].ti_Tag=NP_Priority;
	tags[4].ti_Data=0;

	#if defined(__MORPHOS__)
	if (IPC_GET_CODETYPE(entry) == CODETYPE_PPC)
	{
		tags[3].ti_Tag = NP_CodeType;		// Overwriting NP_StackSize (it is not required in PPC native code)
		tags[3].ti_Data = IPC_GET_CODETYPE(entry);
	}
	#endif

	// Want a path?
	if (path)
	{
		BPTR pathlist;

#define DOpusBase (libdata->dopus_base)
		// Lock path list
		GetSemaphore(&libdata->path_lock,SEMF_SHARED,0);

		// Get path list copy
		pathlist=GetDosPathList(libdata->path_list);

		// Unlock path list
		FreeSemaphore(&libdata->path_lock);
#undef DOpusBase

		// Fill out tags
		tags[5].ti_Tag=NP_Cli;
		tags[5].ti_Data=TRUE;
		tags[6].ti_Tag=NP_Path;
		tags[6].ti_Data=(ULONG)pathlist;
		tags[7].ti_Tag=TAG_END;
	}
	else tags[5].ti_Tag=TAG_END;

#define DOSBase (dos_base)
	// Launch process
	ipc->proc=CreateNewProc(tags);
#undef DOSBase

	// Free tags now
	FreeVec(tags);

	// Failed to launch?
	if (!ipc->proc)
	{
		FreeVec(ipc);
		return 0;
	}

	// Store pointer
	if (storage) *storage=ipc;

	// Send startup message
	return L_IPC_Startup(ipc,(APTR)data,0);
}
Пример #9
0
static void __startup_detach(void)
{
    struct CommandLineInterface *cli;
    struct Process              *newproc;
    BPTR                         mysegment = NULL;
    STRPTR                       detached_name;

    D(bug("Entering __startup_detach(\"%s\", %d, %x)\n", argstr, argsize, SysBase));

    cli = Cli();
    /* Without a CLI detaching makes no sense, just jump to
       the real program.  */
    if (!cli)
    {
        __startup_entries_next();
    }  
    else
    {
        mysegment = cli->cli_Module;
        cli->cli_Module = NULL;

        detached_name = __detached_name ? __detached_name : (STRPTR)FindTask(NULL)->tc_Node.ln_Name;
    
        {
            struct TagItem tags[] =
            {
                { NP_Seglist,   (IPTR)mysegment            },
                { NP_Entry,     (IPTR)&__detach_trampoline },
                { NP_Name,      (IPTR)detached_name        },
                { NP_Arguments, (IPTR)__argstr             },
                { NP_Cli,       TRUE                       },
                { TAG_DONE,     0                          }
            };

            __detacher_process = (struct Process *)FindTask(NULL);

            /* CreateNewProc() will take care of freeing the seglist */
            newproc = CreateNewProc(tags);
        }

        if (!newproc)
        {
            cli->cli_Module = mysegment;
            __detached_return_value = RETURN_ERROR;
        }
        else
            while (!__detacher_go_away) Wait(SIGF_SINGLE);

        if (__detached_return_value != RETURN_OK)
        {
            PutStr(FindTask(NULL)->tc_Node.ln_Name); PutStr(": Failed to detach.\n");
        }
    
        if (newproc)
        {
            Forbid();
            Signal(&newproc->pr_Task, SIGF_SINGLE);
        }

        __aros_startup.as_startup_error = __detached_return_value;
    }

    D(bug("Leaving __startup_detach\n"));
}
Пример #10
0
static APTR createnewproctags(APTR DOSBase,ULONG Tag,...)
{ return CreateNewProc((struct TagItem *)&Tag); }