Initial steps for a scheduler process

This commit is contained in:
Chris Young 2014-11-21 23:46:22 +00:00
parent fe56795205
commit f8d8d218d8
3 changed files with 129 additions and 38 deletions

View File

@ -2689,12 +2689,11 @@ void ami_get_msg(void)
{
ULONG winsignal = 1L << sport->mp_SigBit;
ULONG appsig = 1L << appport->mp_SigBit;
ULONG schedulesig = 1L << msgport->mp_SigBit;
ULONG schedulesig = 1L << schedulermsgport->mp_SigBit; /* \todo create schedulermsgport */
ULONG ctrlcsig = SIGBREAKF_CTRL_C;
uint32 signal = 0;
fd_set read_fd_set, write_fd_set, except_fd_set;
int max_fd = -1;
struct TimerRequest *timermsg = NULL;
struct MsgPort *printmsgport = ami_print_get_msgport();
ULONG printsig = 0;
ULONG helpsignal = ami_help_signal();
@ -2742,8 +2741,8 @@ void ami_get_msg(void)
ami_print_cont();
}
if(signal & schedulesig) {
if((timermsg = (struct TimerRequest *)GetMsg(msgport))) {
if(signal & schedulesig) { /* \todo rewrite */
while((timermsg = (struct TimerRequest *)GetMsg(msgport))) {
ReplyMsg((struct Message *)timermsg);
schedule_run();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008, 2011 Chris Young <chris@unsatisfactorysoftware.co.uk>
* Copyright 2008 - 2014 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -29,6 +29,10 @@
#include "amiga/schedule.h"
static struct TimeRequest *tioreq;
struct Device *TimerBase;
struct TimerIFace *ITimer;
struct nscallback
{
struct TimeVal tv;
@ -37,6 +41,18 @@ struct nscallback
struct TimeRequest *treq;
};
struct ami_schedule_message {
struct Message msg;
int type;
struct nscallback *nscb;
}
enum {
AMI_S_SCHEDULE = 0,
AMI_S_STARTUP,
AMI_S_EXIT
};
static PblHeap *schedule_list;
/**
@ -219,9 +235,9 @@ void schedule_run(void)
callback(p);
}
static void ami_schedule_open_timer(void)
static struct MsgPort *ami_schedule_open_timer(void)
{
msgport = AllocSysObjectTags(ASOT_PORT,
struct MsgPort *msgport = AllocSysObjectTags(ASOT_PORT,
ASO_NoTrack,FALSE,
TAG_DONE);
@ -235,36 +251,45 @@ static void ami_schedule_open_timer(void)
TimerBase = (struct Device *)tioreq->Request.io_Device;
ITimer = (struct TimerIFace *)GetInterface((struct Library *)TimerBase,"main",1,NULL);
return msgport;
}
static void ami_schedule_close_timer(void)
static void ami_schedule_close_timer(struct MsgPort *msgport)
{
if(ITimer) DropInterface((struct Interface *)ITimer);
CloseDevice((struct IORequest *) tioreq);
FreeSysObject(ASOT_IOREQUEST,tioreq);
FreeSysObject(ASOT_PORT,msgport);
FreeSysObject(ASOT_IOREQUEST, tioreq);
FreeSysObject(ASOT_PORT, msgport);
}
/* exported function documented in amiga/schedule.h */
bool ami_schedule_create(void)
/**
* Initialise amiga scheduler
*
* /return true if initialised ok or false on error.
*/
struct MsgPort *ami_schedule_create(void)
{
ami_schedule_open_timer();
struct MsgPort *msgport = ami_schedule_open_timer();
schedule_list = pblHeapNew();
if(schedule_list == PBL_ERROR_OUT_OF_MEMORY) return false;
if(schedule_list == PBL_ERROR_OUT_OF_MEMORY) return NULL;
pblHeapSetCompareFunction(schedule_list, ami_schedule_compare);
return true;
return msgport;
}
/* exported function documented in amiga/schedule.h */
void ami_schedule_free(void)
/**
* Finalise amiga scheduler
*
*/
void ami_schedule_free(struct MsgPort *msgport)
{
schedule_remove_all();
pblHeapFree(schedule_list); // this should be empty at this point
schedule_list = NULL;
ami_schedule_close_timer();
ami_schedule_close_timer(msgport);
}
/* exported function documented in amiga/schedule.h */
@ -293,3 +318,83 @@ nserror ami_schedule(int t, void (*callback)(void *p), void *p)
return NSERROR_OK;
}
static int32 ami_scheduler_process(STRPTR args, int32 length, APTR execbase)
{
struct Process *proc = (struct Process *)FindTask(NULL);
struct MsgPort *nsmsgport = proc->pr_Task.tc_UserData;
struct MsgPort *schedulermsgport = IExec->AllocSysObjectTags(ASOT_PORT, TAG_END);
struct MsgPort *timermsgport = ami_schedule_create();
bool running = true;
struct TimerRequest *timermsg = NULL;
struct ami_schedule_message *schedulemsg = NULL;
ULONG schedulesig = 1L << schedulermsgport->mp_SigBit;
ULONG timersig = 1L << timermsgport->mp_SigBit;
uint32 signalmask = schedulesig | timersig;
uint32 signal = 0;
/* Send a startup message to the message port we were given when we were created.
* This tells NetSurf where to send scheduler events to. */
struct ami_schedule_message *asmsg = IExec->AllocSysObjectTags(ASOT_MESSAGE,
ASOMSG_Size, sizeof(struct ami_schedule_message),
ASOMSG_ReplyPort, schedulermsgport,
TAG_END);
asmsg.type = AMI_S_STARTUP;
PutMsg(nsmsgport, asmsg);
/* Main loop for this process */
while(running) {
signal = Wait(signalmask);
if(signal & timersig) {
while((timermsg = (struct TimerRequest *)GetMsg(timermsgport))) {
schedule_run(); /* \todo get top scheduled event and signal nsmsgport to run the callback */
ReplyMsg((struct Message *)timermsg);
}
}
if(signal & schedulesig) {
while((asmsg = (struct ami_schedule_message *)GetMsg(schedulermsgport))) {
/* \todo if it's a reply, free stuff
if(asmsg->nscb) FreeVec(asmg->nscb);
FreeSysObject(ASOT_Message, asmsg);
*/
//ReplyMsg((struct Message *)asmsg);
}
}
}
ami_schedule_free(timermsgport);
return RETURN_OK;
}
/**
* Create a new process for the scheduler.
*
* \param nsmsgport Message port to send scheduler events to.
* \return NSERROR_OK on success or error code on faliure.
*/
nserror ami_scheduler_process_create(struct MsgPort *nsmsgport)
{
struct Process *proc = CreateNewProcTags(
NP_Name, "NetSurf scheduler",
NP_Entry, ami_schedule_process,
NP_Child, TRUE,
NP_StackSize, 16384,
NP_Priority, 1,
NP_UserData, nsmsgport,
TAG_DONE);
if(proc == NULL) {
return NSERROR_NOMEM;
}
return NSERROR_OK;
}

View File

@ -18,15 +18,8 @@
#ifndef AMIGA_SCHEDULE_H
#define AMIGA_SCHEDULE_H
#include <proto/timer.h>
#include "amiga/os3support.h"
struct Device *TimerBase;
struct TimerIFace *ITimer;
struct TimeRequest *tioreq;
struct MsgPort *msgport;
/**
* Schedule a callback.
*
@ -40,19 +33,6 @@ struct MsgPort *msgport;
*/
nserror ami_schedule(int t, void (*callback)(void *p), void *p);
/**
* Initialise amiga scheduler
*
* /return true if initialised ok or false on error.
*/
bool ami_schedule_create(void);
/**
* Finalise amiga scheduler
*
*/
void ami_schedule_free(void);
/**
* Process events up to current time.
*
@ -62,5 +42,12 @@ void ami_schedule_free(void);
*/
void schedule_run(void);
/**
* Create a new process for the scheduler.
*
* \param nsmsgport Message port to send timer events to.
* \return NSERROR_OK on success or error code on faliure.
*/
nserror ami_scheduler_process_create(struct MsgPort *nsmsgport);
#endif