void test_move_card_from_stack_empty_stack_to_non_stack_empty_stack() { struct stack *origin, *destination, *new_origin, *new_destination, *origin_duplicate, *destination_duplicate; struct card *card; card_malloc(&card); card_init(card); card_set(card, ACE, SPADES, EXPOSED, 0, 0); stack_malloc(&origin); stack_malloc(&destination); stack_init(origin); stack_init(destination); new_origin = origin; new_destination = destination; stack_push(&new_destination, card); origin_duplicate = stack_dup(origin); destination_duplicate = stack_dup(destination); move_card(&new_origin, &new_destination); assert(origin == new_origin); assert(stacks_equal(origin, origin_duplicate)); assert(destination == new_destination); assert(stacks_equal(destination, destination_duplicate)); stack_free(origin); stack_free(destination); }
void stack_over() { if (num_stack_items() < 2) { eprintf("stack underflow error."); return; } char *topval = stack_pop(); stack_dup(); stack_push(topval); stack_swap(); }
void test_move_card_from_stack_empty_stack_to_stack_empty_stack() { struct stack *origin, *destination, *new_origin, *new_destination, *origin_duplicate, *destination_duplicate; stack_malloc(&origin); stack_malloc(&destination); stack_init(origin); stack_init(destination); new_origin = origin; new_destination = destination; origin_duplicate = stack_dup(origin); destination_duplicate = stack_dup(destination); move_card(&new_origin, &new_destination); assert(origin == new_origin); assert(stacks_equal(origin, origin_duplicate)); assert(destination == new_destination); assert(stacks_equal(destination, destination_duplicate)); stack_free(origin); stack_free(destination); }
struct stack flow_table_get( flow_table_t *ft, struct flow_keys match, routing_table_t* routing_table, u32 dst_ip) { struct stack no_stack; struct stack new_stk; struct stack old_stk; unsigned long flags = 0; match_stk_t *curr = NULL; match_stk_t *prev = NULL; int index = 0; no_stack.num_tags = -1; index = flow_keys_hash(match) % ft->size; curr = rcu_dereference_bh(ft->table[index]); while(curr != NULL && !flow_key_equal(match, curr->match)) { pr_debug("FT: active non-matching flow\n"); prev = curr; curr = rcu_dereference_bh(curr->next); } // flow_table returns "no_stack" on miss if(curr == NULL || !flow_key_equal(match, curr->match)) { pr_debug("FT: no matching flow\n"); return no_stack; } // found a matching stack - check idle timeout before returning if(flow_idle_time(curr->last_used) > IDLE_TIMEOUT){ pr_debug("FT: matched flow - timeout.. num_flows %d -> %d\n", atomic_read(&ft->num_flows), atomic_read(&ft->num_flows) - 1); // if idle timed-out, remove flow entry and return no_stack new_stk = stack_dup(get_random_stack_for_dst(dst_ip, routing_table)); old_stk = curr->stk; ft_lock(flags); curr->stk = new_stk; ft_unlock(flags); stack_free(old_stk); } pr_debug("FT: matched flow - updating last_used\n"); // update the last_used value for successful match curr->last_used = jiffies; return curr->stk; }
int main(){ stack_init(); printf("%d\n", stack_count()); stack_push(5); stack_push(2); stack_push(10); printf("%d\n", stack_count()); stack_dup(); stack_add(); printf("%d\n", stack_count()); int x; puts(""); while(!stack_empty()){ x = stack_pop(); printf("%d\n", x); } return 0; }
static __inline void dup(void) { stack_dup(&bmachine.stack); }
void flow_table_set( flow_table_t *ft, struct flow_keys match, struct stack orig_stk ) { unsigned long flags = 0; int index = 0; match_stk_t *new_match_stk = NULL; match_stk_t *curr = NULL; match_stk_t *prev = NULL; match_stk_t *tmp = NULL; match_stk_t *to_free = NULL; // keep separate copies of stack in routing and flow tables struct stack stk = stack_dup(orig_stk); new_match_stk = flow_table_new_match_stk(match, stk); if(new_match_stk == NULL){ stack_free(stk); return; } index = flow_keys_hash(match) % ft->size; pr_debug("FT: setting flow entry %d ... num_flows: %d -> %d\n", index, atomic_read(&ft->num_flows), atomic_read(&ft->num_flows)+1); ft_lock(flags); curr = rcu_dereference_bh(ft->table[index]); while(curr != NULL && !flow_key_equal(match, curr->match)) { // --- if(flow_idle_time(curr->last_used) > IDLE_TIMEOUT && 0){ // if idle timed-out, remove flow entry pr_debug("FT: non-matching flow timeout remove it %d -> %d flows\n", atomic_read(&ft->num_flows), atomic_read(&ft->num_flows)-1); if(prev == NULL) { // at the beginning of bucket tmp = curr->next; rcu_assign_pointer(ft->table[index], tmp); curr->next = to_free; to_free = curr; curr = rcu_dereference_bh(ft->table[index]); } else { // otherwise prev->next = curr->next; curr->next = to_free; to_free = curr; curr = rcu_dereference_bh(prev->next); } atomic_dec(&ft->num_flows); } else { // Else advance to next entry in bucket pr_debug("FT: active non-matching flow\n"); prev = curr; curr = rcu_dereference_bh(curr->next); } } if(curr != NULL && flow_key_equal(match, curr->match)) { curr->stk = stk; free_match_stk_entry(new_match_stk); } else { tmp = rcu_dereference_bh(ft->table[index]); if(curr == tmp) { pr_debug("FT: creating new bucket entry at %d\n", index); new_match_stk->next = curr; rcu_assign_pointer(ft->table[index], new_match_stk); } else if (curr == NULL) { pr_debug("FT: appending bucket entry at %d\n", index); rcu_assign_pointer(prev->next, new_match_stk); } else { pr_debug("FT: inserting bucket entry at %d\n", index); new_match_stk->next = curr; rcu_assign_pointer(prev->next, new_match_stk); } atomic_inc(&ft->num_flows); } ft_unlock(flags); }
void program_loop() { char *line = NULL; size_t line_size = 0; int start_from = 0; char *token = NULL; while(true) { printf("%d > ", num_stack_items()); line_size = getline(&line, &line_size, stdin); if (line_size == -1) break; while (true) { token = get_next_token(line, line_size, &start_from); if (token == NULL) { break; } else if (strcmp(token, ".s") == 0) { stack_show(); continue; } else if (strcmp(token, ".") == 0) { stack_dot(); continue; } else if (strcmp(token, ".dropall") == 0) { stack_dropall(); continue; } else if (strcmp(token, "+") == 0) { stack_plus(); continue; } else if (strcmp(token, "-") == 0) { stack_minus(); continue; } else if (strcmp(token, ".swap") == 0) { stack_swap(); continue; } else if (strcmp(token, ".dup") == 0) { stack_dup(); continue; } else if (strcmp(token, ".over") == 0) { stack_over(); continue; } else if (strcmp(token, ".drop") == 0) { stack_pop(); continue; } else if (strcmp(token, ".rot") == 0) { stack_rot(); continue; } else if (strcmp(token, ".-rot") == 0) { stack_rot(); stack_rot(); continue; } else if (strcmp(token, "!") == 0) { set_variable(); continue; } else if (strcmp(token, "$") == 0) { get_variable(); continue; } else if (token[0] == '$' && token[1] == '$') { eprintf("error: variable name can't begin with $.\n"); continue; } else if (token[0] == '$' && token[1] == '.') { /* Put literals in for stack operations. */ /* shift everything after $ over one */ for (int i = 0; i < BUFSIZE-1; ++i) { token[i] = token[i+1]; } stack_push(token); continue; } else if (token[0] == '$') { /* shift everything after $ over one */ for (int i = 0; i < BUFSIZE-1; ++i) { token[i] = token[i+1]; } stack_push(token); get_variable(); continue; } else if (strcmp(token, ";") == 0) { stack_execute(); continue; } else if (strcmp(token, ".cd") == 0) { stack_cd(); continue; } else if (token[0] == '.' && strlen(token) > 1) { /* shift everything after . over one */ for (int i = 0; i < BUFSIZE-1; ++i) { token[i] = token[i+1]; } stack_push(token); stack_execute(); continue; } stack_push(token); } start_from = 0; } }