Beispiel #1
0
void    svc( SYSTEM_CALL_DATA *SystemCallData ) {
    short               call_type;
    static short        do_print = 10;
    short               i;
	INT32				Time;
	static long         SleepTimer;
	INT32               atLock = -1;


    call_type = (short)SystemCallData->SystemCallNumber;
    if ( do_print > 0 ) {
        printf( "SVC handler: %s\n", call_names[call_type]);
        for (i = 0; i < SystemCallData->NumberOfArguments - 1; i++ ){
        	 //Value = (long)*SystemCallData->Argument[i];
             printf( "Arg %d: Contents = (Decimal) %8ld,  (Hex) %8lX\n", i,
             (unsigned long )SystemCallData->Argument[i],
             (unsigned long )SystemCallData->Argument[i]);
        }
		do_print--;
	}

	switch (call_type){
		//get time service call
		case SYSNUM_GET_TIME_OF_DAY:  //This value is found in syscalls.h
			CALL(MEM_READ( Z502ClockStatus, &Time ));
			*SystemCallData->Argument[0] = Time;

			break;
		//terminate system call
		case SYSNUM_TERMINATE_PROCESS:
			CALL(MEM_READ( Z502ClockStatus, &Time ));
			if(SystemCallData->Argument[0] == -1)
			{ 
				if(current_PCB_PTR->p_id==0)  
				{
					CALL(Z502Halt());  
					break;
				}	

				else
					if(timerHead != NULL)
					{
						if(Time>TimerStatusTime)
							{
								start_timer(5);
								CALL(Dispatcher());
								break;
							}
						else
						CALL(Dispatcher());
						break;
					}
					else{
					CALL(Dispatcher());
					break;}
			

                break;
			}
			else if(SystemCallData->Argument[0] == -2)
			{
			*SystemCallData->Argument[1] = ERR_SUCCESS;
			CALL(Z502Halt());
			break;
			}
			else
			{
				S_PCB *temp = readyHead;
				S_PCB *prev = NULL;
				while(temp != NULL)
				{
					if(temp->p_id ==SystemCallData->Argument[0])
					{
						if(temp->next == NULL)
						{
							*SystemCallData->Argument[1] = ERR_SUCCESS;
							break;
						}
						else
						{
							*SystemCallData->Argument[1] = ERR_SUCCESS;
							prev->next = temp->next;
							break;
						}
					}
					else
					{
						prev = temp;
						temp = temp->next;
						*SystemCallData->Argument[1] = ERR_SUCCESS;
						break;
					}

				}
				if(temp ==  NULL)
				{
					*SystemCallData->Argument[1] = CANNOTTERMINATE ;
				}

			}
			break;
		case SYSNUM_SLEEP:
			//overTimeModify();
			schedular_printer(SLEEP);
		    SleepTimer = SystemCallData->Argument[0];
			CALL(MEM_READ( Z502ClockStatus, &Time ));
			current_PCB_PTR->p_time = Time + SleepTimer;
			lockTimer();
			CALL(addToTimerQ(current_PCB_PTR));
			unlockTimer();
			if(Time<(timerHead->p_time))        //compare the wake time with current time 
                    {
                    CALL(start_timer(SleepTimer));
                    CALL(Dispatcher());
                    }
                else{                  //if wake time is smaller than now, it need wake up immedately
                    CALL(start_timer(5));
                    CALL(Dispatcher());
                    }
			break;
		case SYSNUM_CREATE_PROCESS:
			os_create_process(SystemCallData->Argument[0], SystemCallData->Argument[1],SystemCallData->Argument[2],SystemCallData->Argument[3],SystemCallData->Argument[4],NOTRUN);
			break;
		case SYSNUM_GET_PROCESS_ID:
			os_get_process_id(SystemCallData->Argument[0], SystemCallData->Argument[1],SystemCallData->Argument[2]);
			break;
		case SYSNUM_SUSPEND_PROCESS:
			os_suspend_process(SystemCallData->Argument[0], SystemCallData->Argument[1]);
			break;
		case SYSNUM_RESUME_PROCESS:
			os_resume_process(SystemCallData->Argument[0], SystemCallData->Argument[1]);
			break;
		case SYSNUM_CHANGE_PRIORITY:
			os_change_priority(SystemCallData->Argument[0], SystemCallData->Argument[1],SystemCallData->Argument[2]);
			break;
		case SYSNUM_SEND_MESSAGE:
			os_send_message(SystemCallData->Argument[0], SystemCallData->Argument[1],SystemCallData->Argument[2],SystemCallData->Argument[3]);
			break;
		case SYSNUM_RECEIVE_MESSAGE:
			os_receive_message(SystemCallData->Argument[0], SystemCallData->Argument[1],SystemCallData->Argument[2],SystemCallData->Argument[3],SystemCallData->Argument[4],SystemCallData->Argument[5]);
			break;
		default:
			printf( "ERROR! Call type not reconginzed!\n");
			printf( "Call_type is - %i\n", call_type);
	}
}
Beispiel #2
0
void    svc( SYSTEM_CALL_DATA *SystemCallData ) {
    short               call_type;
    static short        do_print = 10;
    short               i;
    int                 Time;
    int                 ID;
    int                 k=0,m=0,n=0;
    int                 PR;
    int                 sid,tid,mlen;
    int                 actual_length;
    long                tmp;
    INT32               diskstatus;
    long                tmpid;
    void                *next_context;
    char                *tmpmsg;
    PCB                 *head;
    PCB                 *head1;
    PCB *pcb = (PCB *)malloc(sizeof(PCB));


    call_type = (short)SystemCallData->SystemCallNumber;
    if ( do_print > 0 ) {
        printf( "SVC handler: %s\n", call_names[call_type]);
        for (i = 0; i < SystemCallData->NumberOfArguments - 1; i++ ) {
            //Value = (long)*SystemCallData->Argument[i];
            printf( "Arg %d: Contents = (Decimal) %8ld,  (Hex) %8lX\n", i,
                    (unsigned long )SystemCallData->Argument[i],
                    (unsigned long )SystemCallData->Argument[i]);
        }
    }
    switch(call_type) {
    case SYSNUM_GET_TIME_OF_DAY:
        MEM_READ(Z502ClockStatus, &Time);
        //Z502_REG1=Time;
        *SystemCallData->Argument[0]=Time;
        break;

    case SYSNUM_TERMINATE_PROCESS:
        tmpid = (long)SystemCallData->Argument[0];
        if(tmpid>=0) {
            os_delete_process_ready(tmpid);
            Z502_REG9 = ERR_SUCCESS;
        }
        else if(tmpid == -1)
        {
            head =Running;
            Running = NULL;
            while(readyfront==NULL&&timerfront==NULL) {
                Z502Halt();
            }
            //free(head);
            dispatcher();
            Z502SwitchContext( SWITCH_CONTEXT_SAVE_MODE, &(Running->context) );
        }
        else
            Z502Halt();
        break;
    //the execution of sleep();
    case SYSNUM_SLEEP:
        start_timer( (int)SystemCallData->Argument[0] );

        break;
    case SYSNUM_GET_PROCESS_ID:
        *SystemCallData->Argument[1] = os_get_process_id((char *)SystemCallData->Argument[0]);
        break;
    case SYSNUM_CREATE_PROCESS:
        strcpy(pcb->Processname , (char *)SystemCallData->Argument[0]);
        pcb->Priority = (long)SystemCallData->Argument[2];
        head = readyfront;
        head1 = readyfront;
        if(Pid < 20) {
            if(pcb->Priority >0) {
                if(readyfront == NULL&&readyrear == NULL) {
                    readyfront = pcb;
                    readyrear = pcb;
                    //*SystemCallData->Argument[4] = ERR_SUCCESS;
                    Z502_REG9 = ERR_SUCCESS;
                    pcb->pid = Pid;
                    pcb->next=NULL;
                    Toppriority = pcb->Priority;
                    *SystemCallData->Argument[3] = Pid;
                    //pcb->context = (void *)SystemCallData->Argument[1];
                    Z502MakeContext( &next_context, (void *)SystemCallData->Argument[1], USER_MODE );
                    pcb->context = next_context;
                    Pid++;
                }
                else if(readyfront!=NULL&&readyrear!=NULL) {

                    if(checkPCBname(pcb) == 1) {

                        if(pcb->Priority < Toppriority) {
                            Z502_REG9 = ERR_SUCCESS;
                            pcb->next = readyfront;
                            readyfront = pcb;
                            pcb->pid = Pid;
                            pcb->next=NULL;
                            Z502MakeContext( &next_context, (void *)SystemCallData->Argument[1], USER_MODE );
                            pcb->context = next_context;
                            *SystemCallData->Argument[3] = Pid;
                            Pid++;
                        }
                        else {
                            while(head->next!=NULL) {
                                if(pcb->Priority < head->Priority)
                                    break;
                                else
                                    head = head->next;
                            }

                            if(head->next!=NULL) {
                                while(head1->next!=head)
                                {
                                    head1=head1->next;
                                }
                                Z502_REG9 = ERR_SUCCESS;
                                head1->next = pcb;
                                pcb->next=head;
                                pcb->pid = Pid;
                                Z502MakeContext( &next_context, (void *)SystemCallData->Argument[1], USER_MODE );
                                pcb->context = next_context;
                                *SystemCallData->Argument[3] = Pid;
                                Pid++;
                            }
                            else {
                                if(pcb->Priority < head->Priority) {
                                    while(head1->next!=head)
                                    {
                                        head1=head1->next;
                                    }
                                    Z502_REG9 = ERR_SUCCESS;
                                    head1->next=pcb;
                                    pcb->next=head;
                                    pcb->pid = Pid;
                                    Z502MakeContext( &next_context, (void *)SystemCallData->Argument[1], USER_MODE );
                                    pcb->context = next_context;
                                    *SystemCallData->Argument[3] = Pid;
                                    Pid++;
                                }
                                else {
                                    Z502_REG9 = ERR_SUCCESS;
                                    head->next = pcb;
                                    readyrear = pcb;
                                    pcb->next=NULL;
                                    pcb->pid = Pid;
                                    Z502MakeContext( &next_context, (void *)SystemCallData->Argument[1], USER_MODE );
                                    pcb->context = next_context;
                                    *SystemCallData->Argument[3] = Pid;
                                    Pid++;
                                }
                            }

                        }
                    }
                    else free(pcb);
                }
            } else free(pcb);
        }
        else {
            Z502_REG9++;
            free(pcb);
        }
        break;

    case SYSNUM_SUSPEND_PROCESS:
        ID = (int)SystemCallData->Argument[0];
        head = suspendfront;
        while(head!=NULL) {
            if(head->pid == ID) {
                n = 1;
                break;
            }
            else
                head = head->next;
        }

        if(n!=1) {
            head = readyfront;
            while(head!=NULL) {
                if(head->pid == ID) {
                    Z502_REG9 = ERR_SUCCESS;
                    suspend_process_ready(head);
                    k = 1;
                    break;
                }
                else
                    head = head->next;
            }

            if(k == 0) {
                head = timerfront;
                while(head!=NULL) {
                    if(head->pid == ID) {
                        Z502_REG9 = ERR_SUCCESS;
                        suspend_process_timer(head);
                        m = 1;
                        break;
                    }
                    else
                        head=head->next;
                }
                if(m == 0&&k == 0) {
                    printf("illegal PID\n");
                }
            }
        }
        if(n == 1) {
            printf("can not suspend suspended process\n");
        }
        break;

    case SYSNUM_RESUME_PROCESS:
        ID = (int)SystemCallData->Argument[0];
        head = suspendfront;
        while(head!=NULL) {
            if(head->pid == ID) {
                k=1;
                break;
            }
            else
                head=head->next;
        }
        if(k==1)
            resume_process(head);
        else
            printf("error\n");
        break;
    case SYSNUM_CHANGE_PRIORITY:
        ID = (int)SystemCallData->Argument[0];
        PR = (int)SystemCallData->Argument[1];
        if(ID == -1) {
            Running->Priority = PR;
            Z502_REG9 = ERR_SUCCESS;
        }
        else {
            if(PR < 100) {
                if(checkReady(ID) == 1) {
                    head = readyfront;
                    while(head->pid != ID)
                        head=head->next;
                    change_priority_ready(head,PR);
                    Z502_REG9 = ERR_SUCCESS;
                }
                else if(checkTimer(ID) == 1) {
                    head = timerfront;
                    while(head->pid != ID)
                        head=head->next;
                    change_priority_timer(head,PR);
                    Z502_REG9 = ERR_SUCCESS;
                }
                else if(checkSuspend(ID) == 1) {
                    head = suspendfront;
                    while(head->pid != ID)
                        head = head->next;
                    change_priority_suspend(head,PR);
                    Z502_REG9 = ERR_SUCCESS;
                }
                else {
                    printf("ID ERROR!\n");
                }
            }
            else {
                printf("illegal Priority");
            }
        }
        break;
    case SYSNUM_SEND_MESSAGE:
        sid = Running->pid;
        tid = (int)SystemCallData->Argument[0];
        tmpmsg =(char *)SystemCallData->Argument[1];
        mlen = (int)SystemCallData->Argument[2];
        if(maxbuffer < 8) {
            if(tid < 100) {
                if(mlen < 100)
                {
                    if(tid>0)
                    {   send_message(sid,tid,mlen,tmpmsg);
                        maxbuffer++;
                    }
                    else if(tid == -1) {
                        send_message_to_all(sid,mlen,tmpmsg);
                        maxbuffer++;
                    }
                }
                else {
                    printf("illegal length!\n");
                }
            } else
                printf("illegal id!\n");
        }
        else
        {   printf("no space!\n");
            Z502_REG9++;
        }
        break;
    case  SYSNUM_RECEIVE_MESSAGE:
        sid = (int)SystemCallData->Argument[0];
        mlen = (int)SystemCallData->Argument[2];

        if(sid < 100) {
            if(mlen < 100) {
                if(sid == -1) {

                    receive_message_fromall();
                    if(msgnum>0) {
                        actual_length = strlen(checkmsg->msg_buffer);
                        if(mlen >actual_length) {
                            msg_out_queue(checkmsg);
                            *SystemCallData->Argument[3] = actual_length;
                            *SystemCallData->Argument[4] = checkmsg->source_pid;
                            strcpy((char *)SystemCallData->Argument[1] ,checkmsg->msg_buffer);
                            Z502_REG9 = ERR_SUCCESS;
                        }
                        else {
                            printf("small buffer!\n");
                        }
                    }
                }
                else {
                    receive_message_fromone(sid);
                    if(msgnum>0) {
                        actual_length = strlen(checkmsg->msg_buffer);
                        if(mlen >actual_length) {
                            msg_out_queue(checkmsg);
                            *SystemCallData->Argument[3] = actual_length;
                            *SystemCallData->Argument[4] = checkmsg->source_pid;
                            strcpy((char *)SystemCallData->Argument[1], checkmsg->msg_buffer);
                            Z502_REG9 = ERR_SUCCESS;
                        }
                        else {
                            printf("small buffer!\n");
                        }
                    }
                }
            }
            else
                printf("illegal length!\n");
        }
        else
            printf("illegal id!\n");
        break;
    case  SYSNUM_DISK_READ:
        disk_read(SystemCallData->Argument[0],SystemCallData->Argument[1],SystemCallData->Argument[2]);

        break;
    case SYSNUM_DISK_WRITE:
        disk_write(SystemCallData->Argument[0],SystemCallData->Argument[1],SystemCallData->Argument[2]);
        break;
    default:
        printf("call_type %d cannot be recognized\n",call_type);
        break;
    }

    do_print--;
}