/* * Identify the attribute in <attr_name>. * * Check if * 1) the attribute has been defined already * 2) the value count is correct * 3) the assign op is appropriate * * Invoke appropriate parser. * * This function will return FAILED only if its in the default section * and an attribute cannot be ID'd. Otherwise, it returns OK. */ static status_e identify_attribute( entry_e entry_type, struct service_config *scp, const char *attr_name, enum assign_op op, pset_h attr_values ) { const struct attribute *ap ; const char *func = "identify_attribute" ; if ( entry_type == SERVICE_ENTRY ) ap = attr_lookup( service_attributes, attr_name ) ; else ap = attr_lookup( default_attributes, attr_name ) ; if ( ap == NULL ) return OK; /* We simply ignore keywords not on the list */ if ( ! MODIFIABLE( ap ) ) { if ( SC_SPECIFIED( scp, ap->a_id ) ) { parsemsg( LOG_WARNING, func, "Service %s: attribute already set: %s", SC_NAME(scp), attr_name ) ; return OK; } if ( op != SET_EQ ) { parsemsg( LOG_WARNING, func, "Service %s: operator '%s' cannot be used for attribute '%s'", SC_NAME(scp), ( op == PLUS_EQ ) ? "+=" : "-=", attr_name ) ; return OK; } } else /* modifiable attribute */ { /* * For the defaults entry, '=' and '+=' have the same meaning */ if ( entry_type == DEFAULTS_ENTRY && op == SET_EQ ) op = PLUS_EQ ; } if ( FIXED_VALUES( ap ) && (unsigned)ap->a_nvalues != pset_count( attr_values ) ) { parsemsg( LOG_WARNING, func, "attribute %s expects %d values and %d values were specified", attr_name, ap->a_nvalues, pset_count( attr_values ) ) ; return OK; } if ( (*ap->a_parser)( attr_values, scp, op ) == OK ) { /* This is the normal path. */ SC_SPECIFY( scp, ap->a_id ) ; } else if ( entry_type == SERVICE_ENTRY ) { parsemsg( LOG_ERR, func, "Error parsing attribute %s - DISABLING SERVICE", attr_name ) ; SC_DISABLE( scp ); } /* * We are in the default section and an error was detected. At * this point, we should terminate since whatever attribute * was trying to be specified cannot be propagated. */ else if ( !debug.on ) return FAILED; return OK; }
void sys_Dispatch(struct pt_regs * regs, LONG adjust) { struct ExecBase * SysBase = (struct ExecBase *)*(ULONG *)0x04; /* Hmm, interrupts are nesting, not a good idea... */ // if(user_mode(regs)) { // return; // } #if 0 D(bug("In %s!!!\n",__FUNCTION__)); D(bug("lr_svc=%x, r0=%x, r1=%x, r2=%x, r9=%x, r12=%x, sp=%x, lr=%x, cpsr=%x\n", regs->lr_svc, regs->r0, regs->r1, regs->r2, regs->r9, regs->r12, regs->sp, regs->lr, regs->cpsr)); #endif /* Check if a task switch is necessary */ /* 1. There has to be another task in the ready-list */ /* 2. The first task in the ready list hast to have the same or higher priority than the currently active task */ if( SysBase->TaskReady.lh_Head->ln_Succ != NULL /* ((BYTE)SysBase->ThisTask->tc_Node.ln_Pri <= (BYTE)((struct Task *)SysBase->TaskReady.lh_Head)->tc_Node.ln_Pri ) */ ) { /* Check if task switch is possible */ if( SysBase->TDNestCnt < 0 ) { if( SysBase->ThisTask->tc_State == TS_RUN ) { SysBase->ThisTask->tc_State = TS_READY; Reschedule(SysBase->ThisTask); SysBase->AttnResched |= 0x8000; } else if( SysBase->ThisTask->tc_State == TS_REMOVED ) SysBase->AttnResched |= 0x8000; } else SysBase->AttnResched |= 0x80; } /* Has an interrupt told us to dispatch when leaving */ if (SysBase->AttnResched & 0x8000) { SysBase->AttnResched &= ~0x8000; /* Save registers for this task (if there is one...) */ if (SysBase->ThisTask && SysBase->ThisTask->tc_State != TS_REMOVED) { regs->lr_svc -= adjust; // adjust is 0 or -4 SaveRegs(SysBase->ThisTask, regs); } /* Tell exec that we have actually switched tasks... */ Dispatch (); //D(bug("DISPATCHER: New task: %s\n",SysBase->ThisTask->tc_Node.ln_Name)); /* Get the registers of the old task */ RestoreRegs(SysBase->ThisTask, regs); regs->lr_svc += adjust; // adjust is 0 or -4 /* Make sure that the state of the interrupts is what the task expects. */ if (SysBase->IDNestCnt < 0) SC_ENABLE(regs); else SC_DISABLE(regs); #if 0 D(bug("after: lr_svc=%x, r0=%x, r1=%x, r2=%x, r9=%x, r12=%x, sp=%x, lr=%x, cpsr=%x (adjust=%d)\n", regs->lr_svc, regs->r0, regs->r1, regs->r2, regs->r9, regs->r12, regs->sp, regs->lr, regs->cpsr, adjust)); #endif /* Ok, the next step is to either drop back to the new task, or give it its Exception() if it wants one... */ if (SysBase->ThisTask->tc_Flags & TF_EXCEPT) { Disable(); Exception(); Enable(); } } /* Leave the interrupt. */ }
void sys_Dispatch(struct pt_regs * regs) { struct ExecBase * SysBase = (struct ExecBase *)*(ULONG *)0x04; /* Hmm, interrupts are nesting, not a good idea... */ if(!user_mode(regs)) { return; } /* Check if a task switch is necessary */ /* 1. There has to be another task in the ready-list */ /* 2. The first task in the ready list hast to have the same or higher priority than the currently active task */ if( SysBase->TaskReady.lh_Head->ln_Succ != NULL /* && ((BYTE)SysBase->ThisTask->tc_Node.ln_Pri <= (BYTE)((struct Task *)SysBase->TaskReady.lh_Head)->tc_Node.ln_Pri )*/ ) { /* Check if task switch is possible */ if( SysBase->TDNestCnt < 0 ) { if( SysBase->ThisTask->tc_State == TS_RUN ) { SysBase->ThisTask->tc_State = TS_READY; Reschedule(SysBase->ThisTask); SysBase->AttnResched |= 0x8000; } else if( SysBase->ThisTask->tc_State == TS_REMOVED ) SysBase->AttnResched |= 0x8000; } else SysBase->AttnResched |= 0x80; } /* Has an interrupt told us to dispatch when leaving */ if (SysBase->AttnResched & 0x8000) { SysBase->AttnResched &= ~0x8000; /* Save registers for this task (if there is one...) */ if (SysBase->ThisTask && SysBase->ThisTask->tc_State != TS_REMOVED) SaveRegs(SysBase->ThisTask, regs); /* Tell exec that we have actually switched tasks... */ Dispatch (); /* Get the registers of the old task */ RestoreRegs(SysBase->ThisTask, regs); /* Make sure that the state of the interrupts is what the task expects. */ if (SysBase->IDNestCnt < 0) SC_ENABLE(regs); else SC_DISABLE(regs); /* Ok, the next step is to either drop back to the new task, or give it its Exception() if it wants one... */ if (SysBase->ThisTask->tc_Flags & TF_EXCEPT) { Disable(); Exception(); Enable(); } } /* Leave the interrupt. */ }