void smap_increment(smap *map, char *key, int amt) { int already_contains = 1; int val = smap_get_extended(map, key, &already_contains); if (already_contains) { smap_put(map, key, val + amt); } else { smap_put(map, key, amt); } }
void *insert_map(void *argv) { struct timeval tvafter,tvpre; struct timezone tz; struct SMAP* map = ((struct thread_args *)argv)->map; struct file *fptr = ((struct thread_args *)argv)->fptr; int i, j, s,z; void *ret; int rc; struct PAIR pair; gettimeofday (&tvpre , &tz); for (i = LOOP_TIMES; i < LOOP_TIMES*2; i++) { if (i%2) SMAP_SET_NUM_PAIR(&pair, i, buf[i], 8); else SMAP_SET_STR_PAIR(&pair, buf[i], 7, buf[i], 8); rc = smap_put(map, &pair, 1); } gettimeofday (&tvafter , &tz); printf("put: %dms\n", (tvafter.tv_sec-tvpre.tv_sec)*1000+(tvafter.tv_usec-tvpre.tv_usec)/1000); stop_thr(fptr); }
void initialize_keyword_to_enum_mapping() { /* Note that enums is an *array*, not a pointer, so this * sizeof business is reasonable. */ size_t num_keywords = sizeof(enums) / sizeof(int); for (size_t i = 0; i < num_keywords; i += 1) { smap_put(keyword_str_to_enum, keywords[i], enums[i]); } }
void expand(smap *map) { bucket* old_buckets = map->buckets; size_t old_num_buckets = map->num_buckets; map->buckets = safe_calloc(map->num_buckets * 2 * sizeof(bucket)); map->num_buckets *= 2; map->num_pairs = 0; for (size_t i = 0; i < old_num_buckets; i += 1) { bucket *cur_bucket = old_buckets + i; for (size_t j = 0; j < cur_bucket->num_pairs; j += 1) { smap_put(map, cur_bucket->pairs[j].key, cur_bucket->pairs[j].val); } if (cur_bucket->pairs) { free(cur_bucket->pairs); } } free(old_buckets); }
void smap_put(smap *map, char *key, int value) { if (!map) { return; } size_t hash = hash_string(key) % map->num_buckets; bucket buck = map->buckets[hash]; for (size_t i = 0; i < buck.num_pairs; i += 1) { if (!strcmp(key, buck.pairs[i].key)) { buck.pairs[i].val = value; return; } } if ((map->num_pairs + 1) < map->num_buckets * LOAD_FACTOR) { bucket_insert(map->buckets + hash, key, value); map->num_pairs += 1; } else { expand(map); smap_put(map, key, value); } }
AST *build_ast (lexer *lex) { /* TODO: Implement me. */ /* Hint: switch statements are pretty cool, and they work * brilliantly with enums. */ if (lex) { AST *ast = safe_malloc(sizeof(AST)); token_type ast_type; char *ast_val; read_token(lex); if (peek_type(lex) == token_CLOSE_PAREN) { num_paren--; if (num_paren < 0) { fatal_error("Extra close parenthesis"); } else { return NULL; } } else if (peek_type(lex) == token_END) { if (num_paren != 0) { fatal_error("Uneven number of parenthesis"); } else { return NULL; } } else if (peek_type(lex) == token_OPEN_PAREN) { AST *struct_num; // for when we get a node_STRUCT num_paren++; read_token(lex); ast_type = peek_type(lex); ast_val = peek_value(lex); if (ast_type == token_CLOSE_PAREN) { fatal_error("Empty pair of parenthesis"); } else if (ast_type == token_NAME) { //any variable name that comes after ( will be a function call ast->type = node_CALL; } else if (ast_type == token_KEYWORD) { // if it's a keyword, use smap if (!strcmp(ast_val,"None")) { ast->type = node_INT; ast_val = "0"; } else { ast->type = lookup_keyword_enum(ast_val); if (ast->type == node_STRUCT) { struct_num = safe_malloc(sizeof(AST)); struct_num->type = node_STRING; struct_num->children = NULL; struct_num->last_child = NULL; struct_num->val = safe_malloc(8*sizeof(char)); sprintf(struct_num->val,"struct%d",num_structs); num_structs++; } } } else if (ast_type == token_INT || ast_type == token_STRING) { fatal_error("INT/STRING lone in parenthesis"); } else if (ast_type == token_OPEN_PAREN) { fatal_error("Two consecutive open parenthesis"); } else if (ast_type == token_END) { fatal_error("Abrupt end after open parenthesis"); } ast->val = safe_malloc((strlen(ast_val) + 1) * sizeof(char)); strcpy(ast->val, ast_val); ast->children = safe_malloc(sizeof(AST_lst)); AST_lst *children = ast->children; // somewhere here fit the struct_num child in!! if (ast->type == node_STRUCT) { ast->last_child = children; children->val = struct_num; children->next = safe_malloc(sizeof(AST_lst)); children = children->next; } AST *temp = build_ast(lex); if (temp == NULL && ast->type != node_STRUCT) { ast->children = NULL; ast->last_child = NULL; } else { while (temp != NULL) { ast->last_child = children; children->val = temp; children->next = safe_malloc(sizeof(AST_lst)); children = children->next; temp = build_ast(lex); } (ast->last_child)->next = NULL; } free(children);// free next of last child for which we malloced space earlier, thinking there existed a next. if (ast->type == node_FUNCTION) { ((ast->children)->val)->type = node_VAR; smap_put(num_args,((ast->children)->val)->val,AST_lst_len(((ast->children)->val)->children)); } } else { ast_type = peek_type(lex); ast_val = peek_value(lex); if (ast_type == token_NAME) { ast->type = node_VAR; } else if (ast_type == token_KEYWORD) { if (!strcmp(ast_val,"None")) { ast->type = node_INT; ast_val = "0"; } else { ast->type = lookup_keyword_enum(ast_val); } } ast->val = safe_malloc((strlen(ast_val) + 1) * sizeof(char)); strcpy(ast->val, ast_val); ast->children = NULL; ast->last_child = NULL; } switch (ast_type) { case token_INT: ast->type = node_INT; break; case token_STRING: ast->type = node_STRING; break; } return ast; } return NULL; }
void initialize_calls_to_num_args_mapping() { size_t num_calls = sizeof(nargs) / sizeof(int); for (size_t i = 0; i < num_calls; i++) { smap_put(num_args,keywords[i],nargs[i]); } }
void gather_decls(AST *ast, char *env, int is_top_level, int can_declare_function) { /* TODO: Implement me. */ /* Hint: switch statements are pretty cool, and they work * brilliantly with enums. */ if (ast) { smap_increment(stack_sizes,env,0); AST_lst *children = ast->children; switch (ast->type) { case node_STRING: smap_put(strings,ast->val, num_strings);//(intptr_t) ast->val); num_strings++; // don't need to check children because shouldn't have children break; case node_VAR: if (!is_top_level) { // if we're not in the top level stack if (smap_get(stack_decls,ast->val) == -1) { // check the stack declarations first if (smap_get(decls,ast->val) == -1) { // otherwise check the global declarations fatal_error("Variable called is not defined"); // if not in either stack or global declarations -> ERROR } } } else { // otherwise directly check global declarations if (smap_get(decls,ast->val) == -1) { fatal_error("Variable called is not defined"); } } break; case node_CALL: if (smap_get(func_decls,ast->val) == -1) { fatal_error("Function called is not defined"); } break; case node_FUNCTION: if (!can_declare_function) { fatal_error("Tried to declare function when not at top level"); } AST *first_child = children->val; if (smap_get(func_decls,first_child->val) != -1) { fatal_error("Tried to declare function that already exists"); } else { smap_put(func_decls,first_child->val,smap_get(stack_sizes,env)); // still not sure about value either, maybe just set to 1 } smap_put(stack_sizes,first_child->val,0); // initialized stack_size for this function is_top_level = 0; smap_del(stack_decls); // clean out whatever was in stack_decls from a previous function declaration stack_decls = smap_new(); AST_lst *grandchildren = first_child->children; while (grandchildren) { smap_put(stack_decls,(grandchildren->val)->val,smap_get(stack_sizes,first_child->val)); // again, not sure aboue value yet smap_increment(stack_sizes,first_child->val,1); // increment only by one cause I'm just gonna count the number of words grandchildren = grandchildren->next; } children = children->next; break; case node_ASSIGN: if (!strcmp(env,"if") || !strcmp(env,"for") || !strcmp(env,"while")) { // can be assigned to but just can't be declared if (!is_top_level) { if (smap_get(stack_decls,(children->val)->val) == -1 && smap_get(decls,(children->val)->val) == -1) { fatal_error("Tried to declare variable in IF/FOR/WHILE"); } } else { if (smap_get(decls,(children->val)->val) == -1) { fatal_error("Tried to declare variable in IF/FOR/WHILE"); } } } if (!is_top_level) { // if we're not in the top level stack if (smap_get(stack_decls,(children->val)->val) == -1 && smap_get(decls,(children->val)->val) == -1) { // if it's not in either stack or global declarations smap_put(stack_decls,(children->val)->val,smap_get(stack_sizes,env)); // put it in the stack_declarations, still unsure about value smap_increment(stack_sizes,env,1); // increment the stack size } } else { // else we're just in the global stack frame if (smap_get(decls,(children->val)->val) == -1) { // if not there if (size_of_decls_arr == 0) { decls_arr = safe_malloc(sizeof(char *)); } else { decls_arr = safe_realloc(decls_arr,(size_of_decls_arr + 1) * sizeof(char *)); } decls_arr[size_of_decls_arr] = (children->val)->val; size_of_decls_arr++; smap_increment(stack_sizes,env,1); // increment stack size of env = "" global frame...should equal size_of_decls_arr; } smap_put(decls,(children->val)->val, smap_get(stack_sizes,env)); // still not sure about value } break; } can_declare_function = 0; while (children) { if (ast->type == node_IF || ast->type == node_WHILE || ast->type == node_FOR) { gather_decls(children->val,ast->val,is_top_level, can_declare_function); } else if (ast->type == node_FUNCTION) { gather_decls(children->val,((ast->children)->val)->val,is_top_level, can_declare_function); } else { gather_decls(children->val,env,is_top_level, can_declare_function); } children = children->next; } } }
int main() { struct SMAP* map; int i, rc, ret; pthread_t ntid; struct thread_args *thr_arg; struct PAIR pair; for (i = 0; i < LOOP_TIMES *2; i++) { sprintf(buf[i], "%07d", i); } map = smap_init(LOOP_TIMES*2, DEFAULT_LOAD_FACTOR, 128, LOOP_TIMES/100, 1); if (map == NULL) printf("smap_init failed! \n"); for (i = 0; i < LOOP_TIMES; i++) { if (i%2) SMAP_SET_NUM_PAIR(&pair, i, buf[i], 8); else SMAP_SET_STR_PAIR(&pair, buf[i], 7, buf[i], 8); rc = smap_put(map, &pair, 1); if (rc < 0){ printf("put: i: %d, error: %d\n", i, rc); exit(1); } } nconn = 0; for (i = 0; i < MAXTHEADS; i++) { file[i].f_flags = 0; } for (i = 0; i < MAXTHEADS; i++) { if ((thr_arg = (struct thread_args *)malloc(sizeof(struct thread_args))) == NULL) { perror("malloc"); exit(1); } thr_arg->fptr = &file[i]; thr_arg->map = map; file[i].f_flags = F_CONNECTING; ret = pthread_create(&ntid, NULL, getmap, (void *)thr_arg); if (ret != 0) { perror("pthread_create"); exit(1); } nconn++; file[i].f_tid = ntid; } if ((thr_arg = (struct thread_args *)malloc(sizeof(struct thread_args))) == NULL) { perror("malloc"); exit(1); } thr_arg->fptr = &file[i]; thr_arg->map = map; file[i].f_flags = F_CONNECTING; ret = pthread_create(&ntid, NULL, insert_map, (void *)thr_arg); nconn++; i++; if ((thr_arg = (struct thread_args *)malloc(sizeof(struct thread_args))) == NULL) { perror("malloc"); exit(1); } thr_arg->fptr = &file[i]; thr_arg->map = map; file[i].f_flags = F_CONNECTING; ret = pthread_create(&ntid, NULL, del_map, (void *)thr_arg); nconn++; while (nconn != 0) { pthread_mutex_lock(&ndone_mutex); while(ndone == 0) pthread_cond_wait(&ndone_cond, &ndone_mutex); for (i = 0; i < MAXTHEADS+2; i++) { if (file[i].f_flags & F_DONE) { pthread_join(file[i].f_tid, NULL); //file[i].f_tid = 0; file[i].f_flags = 0; /* clears F_DONE */ ndone--; nconn--; } } pthread_mutex_unlock(&ndone_mutex); } return 0; }