int k_mut_ceil_enter (struct k_t *sem, int timeout) { int retval; DI (); // if ceiling_prio < 0 then its a normal wait call if (sem->ceiling_prio < 0) { retval = ki_wait (sem, timeout); // could call k_wait but just extra fct call EI (); return retval; } if (pRun->prio < sem->ceiling_prio) { // I have higher priority than ceiling :-( EI (); return CEILINGFAIL; } // now we play imm ceiling protocol sem->saved_prio = pRun->prio; // do im ceiling pRun->prio = sem->ceiling_prio; // dont need to reinsert in AQ bq ceil prio is higher or equal to mine and Im already in front of AQ prio_enQ (pAQ, deQ (pRun)); // resinsert me in AQ acc to nwe(old) priority retval = ki_wait (sem, timeout); // coming back interrupt is still disabled ! // chk if we did get semaphore if (retval < 0) { // NOPE we did not pRun->prio = sem->saved_prio; // reset to my old priority prio_enQ (pAQ, deQ (pRun)); // reinsert me in AQ acc to nwe(old) priority ki_task_shift (); // bq maybe started task has higher prio than me } EI (); return retval; // 0(has waited),1(straight through) : ok, -1: timeout }
ISR (TIMER2_OVF_vect, ISR_NAKED) { // no local vars ! I think PUSHREGS (); TCNT2 = tcnt2; // Reload the timer if (!k_running) // obvious goto exitt; fakecnt--; if (0 < fakecnt) // how often shall we run KeRNeL timer code ? goto exitt; fakecnt = fakecnt_preset; // now it's time for doing RT stuff // It looks maybe crazy to go through all semaphores and tasks // but // you may have 3-4 tasks and 3-6 semaphores in your code // so... // and - it's a good idea not to init krnl with more items (tasks/Sem/msg descriptors than needed) pE = sem_pool; // Semaphore timer - check timers on semaphores - they may be cyclic for (tmr_indx = 0; tmr_indx < nr_sem; tmr_indx++) { if (0 < pE->cnt2) { // timer on semaphore ? pE->cnt2--; // yep decrement it if (pE->cnt2 <= 0) { // timeout ? pE->cnt2 = pE->cnt3; // preset again - if cnt3 == 0 and >= 0 the rep timer ki_signal (pE); //issue a signal to the semaphore } } pE++; } pE = task_pool; // Chk timers on tasks - they may be one shoot waiting for (tmr_indx = 0; tmr_indx < nr_task; tmr_indx++) { if (0 < pE->cnt2) { // timer active on task ? pE->cnt2--; // yep so let us do one down count if (pE->cnt2 <= 0) { // timeout ? ( == 0 ) pE->cnt2 = -1; // indicate timeout inis semQ prio_enQ (pAQ, deQ (pE)); // to AQ } } pE++; } prio_enQ (pAQ, deQ (pRun)); // round robbin K_CHG_STAK (); exitt: POPREGS (); RETI (); }
int main () { Q *q = createQ(10); enQ(q, 0x0, 10); enQ(q, 0x0, 20); deQ(q); deQ(q); enQ(q, 0x0, 30); enQ(q, 0x0, 40); enQ(q, 0x0, 50); struct qNode *n = deQ(q); if (n != NULL) printf("Dequeued item is %d", n->key); return 0; }
int k_wait (struct k_t *sem, int timeout) { // copy of ki_wait just with EI()'s before leaving DI (); if (0 < sem->cnt1) { // lucky that we do not need to wait ? sem->cnt1--; // Salute to Dijkstra EI (); return (0); } if (timeout == -1) { // no luck, dont want to wait so bye EI (); return (-2); } // from here we have to wait pRun->cnt2 = timeout; // if 0 then wait forever if (timeout) pRun->cnt3 = (int) sem; // nasty keep ref to semaphore, // so we can be removed if timeout occurs sem->cnt1--; // Salute to Dijkstra enQ (sem, deQ (pRun)); ki_task_shift (); // call enables interrupt on return EI (); return (char) (pRun->cnt2); // 0: ok, -1: timeout }
int ki_wait (struct k_t *sem, int timeout) { // used by msg system DI (); if (0 < sem->cnt1) { // lucky that we do not need to wait ? sem->cnt1--; // Salute to Dijkstra return (0); } if (timeout == -1) { // no luck, dont want to wait so bye bye return (-2); } // from here we want to wait pRun->cnt2 = timeout; // if 0 then wait forever if (timeout) pRun->cnt3 = (int) sem; // nasty keep ref to semaphor // so we can be removed if timeout occurs sem->cnt1--; // Salute to Dijkstra enQ (sem, deQ (pRun)); ki_task_shift (); // call enables NOT interrupt on return return ((char) (pRun->cnt2)); // 0: ok, -1: timeout }
int k_set_prio (char prio) { int i; if (!k_running) { return (-2); } DI (); if ((prio <= 0) || (DMY_PRIO <= prio)) // not legal value my friend { EI (); return (-1); } i = pRun->prio; pRun->prio = prio; prio_enQ (pAQ, deQ (pRun)); ki_task_shift (); EI (); return (i); }
int ki_signal (struct k_t *sem) { DI (); // just in case if (sem->cnt1 < sem->maxv) { sem->cnt1++; // Salute to Dijkstra if (sem->cnt1 <= 0) { sem->next->cnt2 = 0; // return code == ok prio_enQ (pAQ, deQ (sem->next)); return (0); // task was waiting } return (1); // just delivered a signal - no task was waiting } if (SEM_MAX_VALUE > sem->clip) { sem->clip++; } // here we are on bad clip failure no signal takes place // signal is lost !!! #ifdef KRNLBUG k_sem_clip (sem->nr, sem->clip); #endif return (-1); }
int ki_wait (struct k_t *sem, int timeout) { DI (); if (0 < sem->cnt1) { sem->cnt1--; // Salute to Dijkstra k_sem_unclip (sem->nr); return (1); // ok: 1 bq we are not suspended } if (timeout < 0) // no luck, dont want to wait so bye bye { return (-2); } // from here we want to wait pRun->cnt2 = timeout; // 0 == wait forever if (timeout) { // so we can be removed if timeout occurs pRun->cnt3 = (int) sem; // nasty keep ref to semaphore in task stomach } sem->cnt1--; // Salute to Dijkstra k_sem_unclip (sem->nr); enQ (sem, deQ (pRun)); ki_task_shift (); // back again - have semaphore received signal or timeout ? pRun->cnt3 = 0; // reset ref to timer semaphore return ((char) (pRun->cnt2)); // 0: ok , -1: timeout }
int main() { int r, i; /* 32 entries */ queInit(&Q, 32); srand(time(NULL)); printf("Rand #: \n"); for(i=0; i<25; i++) { r = rand()%32; enQ(&Q, r); printf("%d st: %d en: %d\n", r, (Q)->start, (Q)->end); } printf("\nQue after inserts: \n"); walk(&Q); for(i=0; i<5; i++) deQ(&Q); printf("\nQue after DeQ: \n"); walk(&Q); printf("st: %d en: %d\n\n", (Q)->start, (Q)->end); return 0; }
void dispatch() /* dispatch determines which process is to run next and transfers control to that process. */ { PCBptr oldrun = running; if ((running->state == DISPATCH) && (running->pin != 1)) enQ(running, &Ready); /* get next process */ running = deQ(&Ready); if (running == 0) running = &(PTable[0]); /* wait process */ /* set CPU timer */ SPT_(26); /* save old stack ptr and load new one */ if (running->state == NEW) { running->state = DISPATCH; CSWITCH1(&oldrun->top, running->regs); } else CSWITCH(&oldrun->top, &running->top); } /* end dispatch */
// ********************************************************************** // system kill task // int sysKillTask(int taskId) { Semaphore* sem = semaphoreList; Semaphore** semLink = &semaphoreList; // assert that you are not pulling the rug out from under yourself! assert("sysKillTask Error" && tcb[taskId].name && superMode); printf("\nKill Task %s", tcb[taskId].name); // signal task terminated semSignal(taskSems[taskId]); // look for any semaphores created by this task while(sem = *semLink) { if(sem->taskNum == taskId) { // semaphore found, delete from list, release memory deleteSemaphore(semLink); } else { // move to next semaphore semLink = (Semaphore**)&sem->semLink; } } if (tcb[taskId].state == S_BLOCKED) { deQ(&tcb[taskId].event->blockedQ, taskId); } else { deQ(&readyQ, taskId); } // ?? delete task from system queues for (int i = 0; i < tcb[taskId].argc; i++) { free(tcb[taskId].argv[i]); } free(tcb[taskId].argv); /////////////////////////////////////////// tcb[taskId].name = 0; // release tcb slot return 0; } // end sysKillTask
void k_round_robbin (void) { // reinsert running task in activeQ if round robbin is selected DI (); prio_enQ (pAQ, deQ (pRun)); ki_task_shift (); EI (); }
int k_prio_wait (struct k_t *sem, int timeout, char prio) { int retval; return -666; // no rdy for use // copy of ki_wait just with EI()'s before leaving DI (); if (0 < sem->cnt1) { // lucky that we do not need to wait ? sem->cnt1--; // Salute to Dijkstra // set prio pRun->prio = prio; // no need bq we are alrdy in front prio_enQ (pAQ, deQ (pRun)); EI (); return (0); } if (timeout == -1) { // no luck, dont want to wait so bye EI (); return (-2); } // from here we have to wait pRun->cnt2 = timeout; // if 0 then wait forever if (timeout) { pRun->cnt3 = (int) sem; // nasty keep ref to semaphore, } // so we can be removed if timeout occurs sem->cnt1--; // Salute to Dijkstra enQ (sem, deQ (pRun)); ki_task_shift (); // call enables interrupt on return pRun->cnt3 = 0; // reset ref to timer semaphore retval = pRun->cnt2; if (retval == 0) { // set prio pRun->prio = prio; // no need prio_enQ (pAQ, deQ (pRun)); } EI (); return retval; // 0: ok, -1: timeout }
void LGATTServerClass::handleEvents() { APP_LOG("LGATTServer::handleEvents -S"); gatts_q_node *node = frQ(); boolean ret = false; while (node) { APP_LOG("LGATTServer::handleEvents event[%d]", node->evt); LGATTService *service = (LGATTService*)node->service; node->data->_srv = service; switch (node->evt) { case GATTS_EVENT_ON_CONNETION: { LGATTConnection &connection = *(LGATTConnection*)node->data; ret = service->onConnection(connection.addr, connection.connected); }break; case GATTS_EVENT_ON_CHAR_ADDED: { ret = service->onCharacteristicAdded(*(LGATTAttributeData*)node->data); }break; case GATTS_EVENT_ON_DESC_ADDED: { ret = service->onDescriptorAdded(*(LGATTAttributeData*)node->data); }break; case GATTS_EVENT_ON_READ: { ret = service->onRead(*(LGATTReadRequest*)node->data); }break; case GATTS_EVENT_ON_WRITE: { ret = service->onWrite(*(LGATTWriteRequest*)node->data); }break; default: break; } delete node; deQ(); node = frQ(); } APP_LOG("LGATTServer::handleEvents -E"); }
int ki_signal (struct k_t *sem) { if (sem->maxv <= sem->cnt1){ if (32000 > sem->clip) sem->clip++; return (-1); } sem->cnt1++; // Salute to Dijkstra if (sem->cnt1 <= 0) { sem->next->cnt2 = 0; // return code == ok prio_enQ (pAQ, deQ (sem->next)); } return (0); }
char k_mutex_leave (struct k_t *sem) { volatile char res; DI (); pRun->prio = (char) (pRun->maxv); // back to org prio prio_enQ (pAQ, deQ (pRun)); // chg pos in AQ acc to prio res = ki_signal (sem); if (res == 0) ki_task_shift (); EI (); return (res); }
int k_prio_signal (struct k_t *sem, char prio) { int res; DI (); res = ki_signal (sem); // set prio pRun->prio = prio; prio_enQ (pAQ, deQ (pRun)); ki_task_shift (); EI (); return (res); }
static void exitTask(int taskId) { assert("exitTaskError" && tcb[taskId].name); // 1. find task in system queue // 2. if blocked, unblock (handle semaphore) // 3. set state to exit // ?? add code here if (tcb[taskId].state == S_BLOCKED) { Semaphore* s = tcb[taskId].event; enQ(rq, deQ(s->q, taskId), tcb[taskId].priority); tcb[curTask].event = 0; s->state++; } tcb[taskId].state = S_EXIT; // EXIT task state return; } // end exitTask
int k_mut_ceil_leave (struct k_t *sem) { int res; DI (); if (sem->ceiling_prio < 0) { // just std signal return k_signal (sem); } res = ki_signal (sem); // 1: ok no task to AQ, 0: ok task to AQ // coming back interrupt is still disabled ! pRun->prio = sem->saved_prio; // reset to my old priority prio_enQ (pAQ, deQ (pRun)); // resinsert me in AQ acc to nwe(old) priority ki_task_shift (); // bq maybe started task has higher prio than me EI (); return (res); }
int k_set_prio (char prio) { if (!k_running) return (-1); DI (); if ((prio <= 0) || (DMY_PRIO <= prio)) { // not legal value my friend EI (); return (-2); } pRun->prio = prio; prio_enQ (pAQ, deQ (pRun)); ki_task_shift (); EI (); return (0); }
void* scan_nodes(void* threadid) { int i, j, k; long tid; unsigned int min_nbr_height; Edge nbr_edge, min_height_edge; long d; long local_e; long local_c; int max_flow; int isInQ; int height_before_lift; int node_push_times = 0, node_lift_times = 0; int op_times = 0; tid = (long)threadid; Node* cur_node; ThreadEnv* thisThread; thisThread = threadEnv + tid; #if 0 if (tid == 0) global_relabel(tid); #endif pthread_barrier_wait(&start_barrier); while (!flow_done()) { cur_node = thisThread->Q[0]; while (cur_node != NoNode) { #ifdef GR if (op_times > gr_threshold) { op_times = 0; if (pthread_mutex_trylock(&gr_mutex) == 0) { global_relabel(tid); pthread_mutex_unlock(&gr_mutex); } } #endif while (cur_node->excess > 0) { #ifdef DEBUG fprintf(stderr, "%d h=%d, e=%ld\n", cur_node - g_node, cur_node->height, cur_node->excess); fflush(stderr); #endif min_nbr_height = UINT_MAX; for (nbr_edge = cur_node->adj_list; nbr_edge < (cur_node + 1)->adj_list; nbr_edge++) { if (nbr_edge->capacity > 0 && (nbr_edge->endpoint)->height < min_nbr_height) { min_nbr_height = (nbr_edge->endpoint)->height; min_height_edge = nbr_edge; } } #ifdef DEBUG fprintf(stderr, "work on %d\n", cur_node - g_node); fflush(stderr); #endif if (cur_node->height > min_nbr_height) { local_e = cur_node->excess; local_c = min_height_edge->capacity; d = MIN(local_e, local_c); if (min_height_edge->endpoint->wave == cur_node->wave && cur_node->height > min_height_edge->endpoint->height) { node_push_times++; op_times++; atomic_add(d, &(min_height_edge->mateedge->capacity)); atomic_sub(d, &(min_height_edge->capacity)); atomic_add(d, &((min_height_edge->endpoint)->excess)); atomic_sub(d, &(cur_node->excess)); #if defined(PUSH) || defined(DEBUG) fprintf(stderr, "[%ld] %ld(%ld) -> %ld -> %ld(%ld) \n", tid, cur_node - g_node, cur_node->excess, d, min_height_edge->endpoint - g_node, (min_height_edge->endpoint)->excess); fflush(stderr); #endif // add min_nbr to local queue isInQ = cmpxchg(&(min_height_edge->endpoint->inQ), 0, tid + 1); if (isInQ == 0) enQ(thisThread, min_height_edge->endpoint); } } else { // if we cannot push to any nodes, then we must be able to lift node_lift_times++; op_times++; pthread_mutex_lock(&(node_mutex[cur_node - g_node])); if (cur_node->height < min_nbr_height + 1) cur_node->height = min_nbr_height + 1; pthread_mutex_unlock(&(node_mutex[cur_node - g_node])); #if defined(LIFT) || defined(DEBUG) fprintf(stderr, "%ld ^ %d, ref %ld(%d)\n", cur_node - g_node, cur_node->height, min_height_edge->endpoint - g_node, min_height_edge->endpoint->height); fflush(stderr); #endif } } // while( g_node[i].excess > 0 ) set0(&(cur_node->inQ)); if (cur_node->excess > 0) { isInQ = cmpxchg(&(cur_node->inQ), 0, tid + 1); if (isInQ == 0) { reenQ(thisThread, cur_node); } else { deQ(thisThread); } } else { deQ(thisThread); } #ifdef HELP if (thisThread->request < MAX_THRD) send_work(tid); #endif cur_node = thisThread->Q[thisThread->head]; } // while (i != -1) #ifdef HELP // Q is empty, find something to do; request_work(tid); #else break; #endif } // while(!flow_done()) atomic_add(node_push_times, &(totalPushes)); atomic_add(node_lift_times, &(totalLifts)); } // scan_node
int main(void) { PriorityQueue* q = newPriorityQueue(); assert("PriorityQueue creation error" && q->head == NULL); enQ(q, 10, 100); assert("enQ error" && q->head != NULL); assert("enQ error" && q->head->data == 10); assert("enQ error" && q->head->priority == 100); enQ(q, 11, 102); enQ(q, 8, 105); enQ(q, 2, 103); enQ(q, 90, 101); print(q); printf("\n"); // Pop int data, priority; data = pop(q); assert("Pop error" && data == 8); data = pop(q); assert("Pop error" && data == 2); data = pop(q); assert("Pop error" && data == 11); data = pop(q); assert("Pop error" && data == 90); data = pop(q); assert("Pop error" && data == 10); data = pop(q); assert("Pop error" && data == -1); print(q); printf("\n"); // Test deQ enQ(q, 10, 100); enQ(q, 11, 102); enQ(q, 8, 105); enQ(q, 2, 103); enQ(q, 90, 101); enQ(q, 20, 98); print(q); printf("\n"); deQ(q, 2); assert("DeQ error" && q->head != NULL); data = pop(q); assert("Pop error after deQ" && data == 8); data = pop(q); assert("Pop error after deQ" && data == 11); deQ(q, 90); assert("DeQ error" && q->head != NULL); data = pop(q); assert("Pop error after deQ" && data == 10); data = pop(q); assert("Pop error after deQ" && data == 20); data = pop(q); assert("Pop error after deQ" && data == -1); assert("Pop error after deQ" && q->head == NULL); deQ(q, 90); assert("DeQ error" && q->head == NULL); print(q); printf("\n"); enQ(q, 10, 100); enQ(q, 11, 102); enQ(q, 8, 105); enQ(q, 2, 103); enQ(q, 90, 101); enQ(q, 20, 98); deQ(q, 90); assert("DeQ error" && q->head != NULL); data = pop(q); assert("Pop error" && data == 8); data = pop(q); assert("Pop error" && data == 2); data = pop(q); assert("Pop error" && data == 11); data = pop(q); assert("Pop error" && data == 10); data = pop(q); assert("Pop error" && data == 20); data = pop(q); assert("Pop error" && data == -1); print(q); printf("\n"); enQ(q, 20, 98); assert("enQ error" && q->head != NULL); data = pop(q); assert("Pop error" && data == 20); assert("pop error" && q->head == NULL); enQ(q, 20, 98); assert("enQ error" && q->head != NULL); data = pop(q); assert("Pop error" && data == 20); assert("pop error" && q->head == NULL); enQ(q, 20, 98); assert("enQ error" && q->head != NULL); data = pop(q); assert("Pop error" && data == 20); assert("pop error" && q->head == NULL); print(q); printf("\n"); // Pop and reQ enQ(q, 0, 98); enQ(q, 1, 100); enQ(q, 2, 100); enQ(q, 3, 100); enQ(q, 4, 100); print(q); printf("\n"); data = pop(q); assert("Pop error" && data == 1); enQ(q, 1, 100); data = pop(q); assert("Pop error" && data == 2); enQ(q, 2, 100); data = pop(q); assert("Pop error" && data == 3); enQ(q, 3, 100); data = pop(q); assert("Pop error" && data == 4); enQ(q, 4, 100); data = pop(q); assert("Pop error" && data == 1); enQ(q, 1, 100); data = pop(q); assert("Pop error" && data == 2); enQ(q, 2, 100); data = pop(q); assert("Pop error" && data == 3); enQ(q, 3, 100); print(q); printf("\n"); deletePriorityQueue(q); q = 0; return 0; }
int main(int argc, char *argv[]) { bool rFlag = false; // Flag to tell if -r is specified int height = 3; // HEIGHT of the Rubik's square int width = 3; // WIDTH of the Rubik's square int maxlength; // MAXLENGTH of a series of moves char *initial = NULL; // The INITIAL string char *goal = NULL; // The GOAL string /* INPUT ERROR CHECKING */ // Check for correct number of args if (argc < 4 || argc > 7) { DIE("RubikSq: RubikSq [-r] [HEIGHT WIDTH] MAXLENGTH INITIAL GOAL"); } if (argc == 5 || argc == 7) { // Check to make sure the first arg is "-r" if (strcmp(argv[1], "-r") != 0) { DIE("RubikSq: Invalid [-r] Flag"); } rFlag = true; } if (argc == 6 || argc == 7) { char *check = argv[argc-5]; // Used to check for non-numeric chars in the args for (int i = 0; i < strlen(check); i++) { if (!isdigit(check[i])) { DIE("RubikSq: Invalid HEIGHT"); } } char *end = NULL; // End pointer for strtol height = strtol(argv[argc-5], &end, 10); if (*end != '\0') { DIE("RubikSq: Invalid HEIGHT"); } char *check2 = argv[argc-4]; // Used to check for non-numeric chars in the args for (int i = 0; i < strlen(check2); i++) { if (!isdigit(check2[i])) { DIE("RubikSq: Invalid WIDTH"); } } char *end2 = NULL; // End pointer for strtol width = strtol(argv[argc-4], &end2, 10); if (*end2 != '\0') { DIE("RubikSq: Invalid WIDTH"); } } char *check3 = argv[argc-3]; // Used to check for non-numeric chars in the args for (int i = 0; i < strlen(check3); i++) { if (!isdigit(check3[i])) { DIE("RubikSq: Invalid MAXLENGTH"); } } char *end3 = NULL; // End pointer for strtol maxlength = strtol(argv[argc-3], &end3, 10); if (*end3 != '\0') { DIE("RubikSq: Invalid MAXLENGTH"); } // Check for non-alpha chars in the args initial = argv[argc-2]; for (int i = 0; i < strlen(initial); i++) { if (!isalpha(initial[i])) { DIE("RubikSq: Invalid INITIAL"); } } // Check for non-alpha chars in the args goal = argv[argc-1]; for (int i = 0; i < strlen(goal); i++) { if (!isalpha(goal[i])) { DIE("RubikSq: Invalid GOAL"); } } if (maxlength < 0) { DIE("RubikSq: MAXLENGTH < 0"); } if (height < 2 || height > 5 || width < 2 || width > 5) { DIE("RubikSq: HEIGHT/WIDTH must be between 2 and 5, inclusive"); } if (strlen(initial) != strlen(goal)){ DIE("RubikSq: Length of INITIAL does not equal length of GOAL"); } if ((height*width) != strlen(initial)) { DIE("RubikSq: HEIGHT*WIDTH does not match length of INITIAL/GOAL"); } // If GOAL and INITIAL are the same, print and exit if (strcmp(initial, goal) == 0) { printf("%s\n", initial); exit(0); } // Make an alphabetized copy of INITIAL char *initialSort = malloc(strlen(initial)+1); // An alphabetized version of INITIAL strcpy(initialSort, initial); sortAlphabetical(initialSort); // Make an alphabetized copy of GOAL char *goalSort = malloc(strlen(goal)+1); // An alphabetized version of GOAL strcpy(goalSort, goal); sortAlphabetical(goalSort); if (strcmp(initialSort, goalSort) != 0) { DIE("RubikSq: INITIAL and GOAL do not contain the same letters"); } // Make sure all letters are between A and L, inclusive if (initialSort[0] < 'A' || initialSort[strlen(initialSort)-1] > 'L' || goalSort[0] < 'A' || goalSort[strlen(goalSort)-1] > 'L') { DIE("RubikSq: INITIAL/GOAL contain invalid letters"); } /* ALGORITHM */ Trie dict; // The dictionary trie for storing past positions createT(&dict); addT(&dict, goal, NULL, 0, 0); Queue moves; // The queue of positions to analyze createQ(&moves); enQ(&moves, goal); // Main loop while (!isEmptyQ(&moves)) { char *pos = NULL; // The current position P deQ(&moves, &pos); int len = getLengthT(&dict, pos, 0); // The length of P in the dictionary if (len < maxlength) { int total; // The total number of possible moves // If -r is specified, there are more possible moves if (rFlag) { total = (width-1)*height + (height-1)*width; } else { total = width + height; } char *primes[total]; // The array of possible positions P' char *copy; // Used to find all P' to put in the array // If the -r flag is specified, we can move right or down multiple times if (rFlag) { for (int i = 1; i <= height; i++) { copy = pos; for (int j = 1; j < width; j++){ copy = moveRight(i, width, copy); primes[(i-1)*(width-1)+j-1] = copy; } } for (int i = 1; i <= width; i++) { copy = pos; for (int j = 1; j < height; j++){ copy = moveDown(i, width, height, copy); primes[height*(width-1)+(i-1)*(height-1)+j-1] = copy; } } } // Otherwise, we can only make one move else { for (int i = 1; i <= height; i++) { primes[i-1] = moveRight(i, width, pos); } for (int i = 1; i <= width; i++) { primes[i+height-1] = moveDown(i, width, height, pos); } } // P' checking for loop for (int i = 0; i < total; i++) { // If P' is INITIAL, print the moves and exit if (strcmp(primes[i], initial) == 0) { printf("%s\n", primes[i]); printf("%s\n", pos); while (getFromT(&dict, pos, 0) != NULL) { pos = getFromT(&dict, pos, 0); printf("%s\n", pos); } // Free the sorted INITIAL and GOAL free(initialSort); free(goalSort); exit(0); } // Else if P' is not in the dictionary, add it to the dict and queue else if (!isMemberT(&dict, primes[i], 0)) { addT(&dict, primes[i], pos, len+1, 0); enQ(&moves, primes[i]); } // Else free the storage else { free(primes[i]); } } } } // Free the sorted INITIAL and GOAL free(initialSort); free(goalSort); return 0; }
void main() { void *npswloc; /* new psw location address */ unsigned int psw[2]; /* psw */ int x; /* loop index */ int wpin, rpin; /* pin for the wait and root states */ PCB dummypcb; /* dummy PCB for running to be set to */ /* initialize new psw locations */ /* program interrupt */ psw[0] = 0x000A0000; psw[1] = 0x00000BAD; npswloc = (void *)progint; memcpy(npswloc, psw, 16); /* I/O interrupt */ psw[0] = 0x00080000; psw[1] = (int)IOHNDLR; npswloc = (void *)ioint; memcpy(npswloc, psw, 16); /* External interrupt */ psw[1] = (int)EXTHNDLR; npswloc = (void *)extint; memcpy(npswloc, psw, 16); /* SVC interrupt */ psw[1] = (int)SVCHNDLR; npswloc = (void *)svcint; memcpy(npswloc, psw, 16); /* initialize memory */ initmem_(); /* initialize Ready Process Q */ QInit(&Ready); /* initialize table to all empty slots */ for (x=0; x<PTSIZE; x++) PTable[x].state = UNUSED; /* create WAIT process */ psw[0] = 0x030A0000; psw[1] = 0x0000AAAA; wpin = create_("WAIT ", psw, NULL, 0, NULL); deQ(&Ready); /* create terminator process */ psw[0] = 0x3080000; psw[1] = (int)terminator; tpin = create_("TERMINAT", psw, 0, 0, NULL); /* create PTSEM and MEMWAIT */ PTSEM = getsem_(PTSIZE, &(PTable[0])); MEMWAIT = getsem_(0, &PTable[0]); /* create 1st user (ROOT) process */ psw[0] = 0x03080000; psw[1] = (int)root; rpin = create_("ROOT ", psw, 0, 0, NULL); /* initialize running to dummy PCB */ running = &dummypcb; running->state = BLOCKED; /* dispatch to give control to ROOT */ dispatch(); } /* end main */
static void idle(struct net_device *dev) { unsigned long flags; int state; /* FIXME This is initialized to shut the warning up, but I need to * think this through again. */ struct xmitQel *q = NULL; int oops; int i; int base = dev->base_addr; spin_lock_irqsave(&txqueue_lock, flags); if(QInIdle) { spin_unlock_irqrestore(&txqueue_lock, flags); return; } QInIdle = 1; spin_unlock_irqrestore(&txqueue_lock, flags); /* this tri-states the IRQ line */ (void) inb_p(base+6); oops = 100; loop: if (0>oops--) { printk("idle: looped too many times\n"); goto done; } state = inb_p(base+6); if (state != inb_p(base+6)) goto loop; switch(state) { case 0xfc: /* incoming command */ if (debug & DEBUG_LOWER) printk("idle: fc\n"); handlefc(dev); break; case 0xfd: /* incoming data */ if(debug & DEBUG_LOWER) printk("idle: fd\n"); handlefd(dev); break; case 0xf9: /* result ready */ if (debug & DEBUG_LOWER) printk("idle: f9\n"); if(!mboxinuse[0]) { mboxinuse[0] = 1; qels[0].cbuf = rescbuf; qels[0].cbuflen = 2; qels[0].dbuf = resdbuf; qels[0].dbuflen = 2; qels[0].QWrite = 0; qels[0].mailbox = 0; enQ(&qels[0]); } inb_p(dev->base_addr+1); inb_p(dev->base_addr+0); if( wait_timeout(dev,0xf9) ) printk("timed out idle f9\n"); break; case 0xf8: /* ?? */ if (xmQhd) { inb_p(dev->base_addr+1); inb_p(dev->base_addr+0); if(wait_timeout(dev,0xf8) ) printk("timed out idle f8\n"); } else { goto done; } break; case 0xfa: /* waiting for command */ if(debug & DEBUG_LOWER) printk("idle: fa\n"); if (xmQhd) { q=deQ(); memcpy(ltdmacbuf,q->cbuf,q->cbuflen); ltdmacbuf[1] = q->mailbox; if (debug>1) { int n; printk("ltpc: sent command "); n = q->cbuflen; if (n>100) n=100; for(i=0;i<n;i++) printk("%02x ",ltdmacbuf[i]); printk("\n"); } handlecommand(dev); if(0xfa==inb_p(base+6)) { /* we timed out, so return */ goto done; } } else { /* we don't seem to have a command */ if (!mboxinuse[0]) { mboxinuse[0] = 1; qels[0].cbuf = rescbuf; qels[0].cbuflen = 2; qels[0].dbuf = resdbuf; qels[0].dbuflen = 2; qels[0].QWrite = 0; qels[0].mailbox = 0; enQ(&qels[0]); } else { printk("trouble: response command already queued\n"); goto done; } } break; case 0Xfb: /* data transfer ready */ if(debug & DEBUG_LOWER) printk("idle: fb\n"); if(q->QWrite) { memcpy(ltdmabuf,q->dbuf,q->dbuflen); handlewrite(dev); } else { handleread(dev); /* non-zero mailbox numbers are for commmands, 0 is for GETRESULT requests */ if(q->mailbox) { memcpy(q->dbuf,ltdmabuf,q->dbuflen); } else { /* this was a result */ mailbox[ 0x0f & ltdmabuf[0] ] = ltdmabuf[1]; mboxinuse[0]=0; } } break; } goto loop; done: QInIdle=0; /* now set the interrupts back as appropriate */ /* the first read takes it out of tri-state (but still high) */ /* the second resets it */ /* note that after this point, any read of base+6 will trigger an interrupt */ if (dev->irq) { inb_p(base+7); inb_p(base+7); } return; }
ISR (KRNLTMRVECTOR, ISR_NAKED) // naked so we have to supply with prolog and epilog (push pop stack of regs) { PUSHREGS (); // no local vars ! I think // JDN NASTY FOR TIMING ANALYSIS ONLY // PORTB |=0x10; wdt_reset (); #if (KRNLTMR == 0) // we have overtaken the millis timer so we do it by hand timer0_millis += MILLIS_INC; timer0_fractt += FRACT_INC; if (timer0_fractt >= FRACT_MAX) { timer0_fractt -= FRACT_MAX; timer0_millis += 1; } timer0_overflow_count++; #else TCNTx = tcntValue; // Reload the timer #endif if (!k_running) { goto exitt; } if (1 < k_tick_size) { fakecnt--; if (fakecnt <= 0) { fakecnt = k_tick_size; } else { goto exitt; // no service } } k_millis_counter += k_tick_size; // my own millis counter // the following may look crazy: to go through all semaphores and tasks // but you may have 3-4 tasks and 3-6 semaphores in your code // so - seems to be efficient :-) // so - it's a good idea not to init krnl with more items // (tasks/Sem/msg descriptors than needed) pE = sem_pool; // Semaphore timer - check timers on semaphores for (tmr_indx = 0; tmr_indx < nr_sem; tmr_indx++) { if (0 < pE->cnt2) // timer on semaphore ? { pE->cnt2--; // yep decrement it if (pE->cnt2 <= 0) // timeout ? { pE->cnt2 = pE->cnt3; // preset again - if cnt3 == 0 and >= 0 the rep timer ki_signal (pE); //issue a signal to the semaphore } } pE++; } pE = task_pool; // Chk timers on tasks - they may be one shoot waiting for (tmr_indx = 0; tmr_indx < nr_task; tmr_indx++) { if (0 < pE->cnt2) // timer active on task ? { pE->cnt2--; // yep so let us do one down count if (pE->cnt2 <= 0) // timeout ? ( == 0 ) { ((struct k_t *) (pE->cnt3))->cnt1++; // leaving sem so adjust semcount on sem prio_enQ (pAQ, deQ (pE)); // and rip task of semQ and insert in activeQ pE->cnt2 = -1; // indicate timeout in this semQ } } pE++; } prio_enQ (pAQ, deQ (pRun)); K_CHG_STAK (); exitt: //JDN NASTY FOR MEA ONLY onn UNO pin8 //PORTB &=0xef; POPREGS (); RETI (); }
ISR (KRNLTMRVECTOR, ISR_NAKED) { // no local vars ! I think PUSHREGS (); TCNTx = tcntValue; // Reload the timer if (!k_running) { // obvious goto exitt; } fakecnt--; // for very slow k_start values //bq timer cant run so slow (8 bit timers at least) if (0 < fakecnt) { // how often shall we run KeRNeL timer code ? goto exitt; } fakecnt = fakecnt_preset; // now it's time for doing RT stuff k_millis_counter += k_tick_size; // my own millis counter // the following may look crazy: to go through all semaphores and tasks // but you may have 3-4 tasks and 3-6 semaphores in your code // so - seesm to be efficient :-) // so - it's a good idea not to init krnl with more items // (tasks/Sem/msg descriptors than needed) pE = sem_pool; // Semaphore timer - check timers on semaphores - they may be cyclic for (tmr_indx = 0; tmr_indx < nr_sem; tmr_indx++) { if (0 < pE->cnt2) { // timer on semaphore ? pE->cnt2--; // yep decrement it if (pE->cnt2 <= 0) { // timeout ? pE->cnt2 = pE->cnt3; // preset again - if cnt3 == 0 and >= 0 the rep timer ki_signal (pE); //issue a signal to the semaphore } } pE++; } pE = task_pool; // Chk timers on tasks - they may be one shoot waiting for (tmr_indx = 0; tmr_indx < nr_task; tmr_indx++) { if (0 < pE->cnt2) { // timer active on task ? pE->cnt2--; // yep so let us do one down count if (pE->cnt2 <= 0) { // timeout ? ( == 0 ) ki_signal ((struct k_t *) (pE->cnt3)); pE->cnt2 = -1; // indicate timeout in this semQ } } pE++; } if (krnl_preempt_flag) { prio_enQ (pAQ, deQ (pRun)); // round robbin K_CHG_STAK (); } exitt: POPREGS (); RETI (); }
int main() { /* test */ int i,j,k,l,m,n; int exit = 1; int dir = 0; graph* gr=NULL; myQueue * q = NULL; while(exit) { printf("\nTEST MENU\n"); printf("*********\n"); printf("1.Create and print a graph\n"); printf("2.DFS\n"); printf("5.Exit\n"); scanf("%d",&m); switch(m) { case 1: printf("Enter no of nodes\n"); scanf("%d",&k); printf("Enter 0:UnDirected 1:Directed\n"); scanf("%d",&dir); gr=(graph*)createGraph(k); // addVertices(gr,0,1,dir,1); addVertices(gr,0,4,dir,4); addVertices(gr,1,2,dir,2); addVertices(gr,1,3,dir,3); addVertices(gr,1,4,dir,4); addVertices(gr,2,3,dir,3); addVertices(gr,3,4,dir,4); printGraph(gr); break; case 2: graph_DFS(gr,0); break; case 3: q = createQ(10); enQ(q,1); enQ(q,3); enQ(q,5); deQ(q); enQ(q,7); enQ(q,9); enQ(q,11); deQ(q); deQ(q); deQ(q); break; case 5: exit = 0; break; } } return 0; }