/** * MAIN */ int main(int argc, char *argv[]) { if (argc == 1) { help(); return -1; } // Handle command line arguments while (argc > 1) { // Parsing '-' options if (argv[1][0] == '-') { // Single option switch (argv[1][1]) { case 'c': // Move at command if (argc > 2) { ++argv; --argc; } else { help(); return -1; } // Check for a valid command if (strcmp(argv[1], "") == 0 || argv[1][0] == '-') { help(); return -1; } // Store command command = malloc(sizeof(char) * strlen(argv[1]) + 1); strcpy(command, argv[1]); break; case 'l': // Enable syslog be_syslog = 1; break; case 'v': // Be verbose be_verbose = 1; break; case 'V': // Print version and exit printf("%s - Version: %s\n", program_name, program_version); return 0; case 'n': be_easter = 1; break; case 'h': default: help(); return -1; } } else { // Directory to watch??? // A command is specified??? if (argc != 2 || command == NULL) { help(); return -1; } // Check if the path isn't empty if (strcmp(argv[1],"") == 0) { help(); return -1; } // Check if the path has the final slash if (argv[1][strlen(argv[1])-1] != '/') { path = (char*) malloc(sizeof(char) * (strlen(argv[1]) + 2)); strcpy(path, argv[1]); strcat(path, "/"); // Check if it is a directory DIR *dir = opendir(path); if (dir == NULL) { help(); return -1; } closedir(dir); } else { path = (char*) malloc(sizeof(char) * strlen(argv[1])); strcpy(path, argv[1]); } // Check if the path is absolute or not. if( path[0] != '/' ) { char *real_path = resolve_real_path(path); free(path); path = real_path; } } // Next argument --argc; ++argv; } if (path == NULL) { help(); return -1; } // File descriptor inotify fd = inotify_init(); // List of all watch directories list_wd = list_init(); // List of all symbolic links list_link = list_init(); // Watch the path watch(path, 0); // Start monitoring return monitor(); }
static void default_init(void) { list_init(&free_list); nr_free = 0; }
static void RR_init(struct run_queue *rq) { list_init(&(rq->run_list)); rq->proc_num = 0; }
//添加节点 int student_add(struct listnode *list,student *stu) { list_init(&stu->_list); list_add_tail(list,&stu->_list); }
int main (int argc, char **argv) { List nflist; int summary = FALSE; int error_occurred = FALSE; struct stats *total_stats = stats_alloc (); int processed = 0; int opt; int option_index = 0; extern char *optarg; extern int optind, opterr, optopt; struct option long_options[] = { {"debug",0,0,'D'}, {"summary",0,0,'s'}, {"help",0,0,'h'}, {"version",0,0,0}, {0,0,0,0} }; #ifdef __GLIBC__ program_name = program_invocation_short_name; #else program_name = base_name (argv[0]); #endif /* Initialize i18n. */ #ifdef HAVE_SETLOCALE setlocale (LC_ALL, ""); #endif #if ENABLE_NLS bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); #endif setup (); while ((opt = getopt_long (argc, argv, "sh", long_options, &option_index)) != -1) { switch (opt) { case 0: { printf_version_string (N_("nfstats")); teardown (); if (fclose (stdout) == EOF) error (EXIT_FAILURE, errno, _("error writing output")); exit (EXIT_SUCCESS); } case 'D': debug = TRUE; break; case 's': summary = TRUE; break; case 'h': printf (_("Usage: %s [OPTION]... NOTESFILE...\n" "Display usage statistics for NOTESFILE(s), including a total.\n\n"), program_name); printf (_(" -s, --summary Print only the total for all listed notesfiles\n" " --debug Display debugging messages\n\n" " -h, --help Display this help and exit\n" " --version Display version information and exit\n\n")); printf (_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT); teardown (); if (fclose (stdout) == EOF) error (EXIT_FAILURE, errno, _("error writing output")); exit (EXIT_SUCCESS); case '?': fprintf (stderr, _("Try '%s --help' for more information.\n"), program_name); teardown (); exit (EXIT_FAILURE); } } if (optind == argc) { fprintf (stderr, _("%s: too few arguments\n"), program_name); fprintf (stderr, _("Try '%s --help' for more information.\n"), program_name); teardown (); exit (EXIT_FAILURE); } list_init (&nflist, (void * (*) (void)) nfref_alloc, (void (*) (void *)) nfref_free, NULL); while (optind < argc) parse_nf (argv[optind++], &nflist); { ListNode *node = list_head (&nflist); struct stats *stats = stats_alloc (); while (node != NULL && !error_occurred) { newts_nfref *ref = (newts_nfref *) list_data (node); int result = get_stats (ref, stats); if (result != NEWTS_NO_ERROR) { fprintf (stderr, _("%s: error getting stats for '%s'\n"), program_name, nfref_pretty_name (ref)); error_occurred = TRUE; break; } if (!summary) { if (processed) printf ("\n"); printf (_("Usage statistics for %s\n"), nfref_pretty_name (ref)); printf (_(" NOTES RESPS TOTALS\n")); printf (_("Local Reads: %7u %7u %7u\n"), stats->notes_read, stats->resps_read, (stats->notes_read + stats->resps_read)); printf (_("Local Writes: %7u %7u %7u\n"), (stats->notes_written - stats->notes_received), (stats->resps_written - stats->resps_received), (stats->notes_written + stats->resps_written - stats->notes_received - stats->resps_received)); printf (_("Entries into Notesfile: %u\n"), stats->entries); printf (_("Total Time in Notesfile: %.2f minutes\n"), ((float) stats->total_time / 60.0)); if (stats->entries) printf (_("Average Time/Entry: %.2f minutes\n"), (((float) stats->total_time / 60.0) / (float) stats->entries)); } stats_accumulate (stats, total_stats); processed++; node = list_next (node); } stats_free (stats); } if (processed && (summary || processed != 1) && !error_occurred) { if (!summary) printf ("\n"); printf (_("Total for all requested notesfiles\n")); printf (_(" NOTES RESPS TOTALS\n")); printf (_("Local Reads: %7u %7u %7u\n"), total_stats->notes_read, total_stats->resps_read, (total_stats->notes_read + total_stats->resps_read)); printf (_("Local Writes: %7u %7u %7u\n"), (total_stats->notes_written - total_stats->notes_received), (total_stats->resps_written - total_stats->resps_received), (total_stats->notes_written + total_stats->resps_written - total_stats->notes_received - total_stats->resps_received)); printf (_("Entries into Notesfiles: %u\n"), total_stats->entries); printf (_("Total Time in Notesfiles: %.2f minutes\n"), ((float) total_stats->total_time / 60.0)); if (total_stats->entries) printf (_("Average Time/Entry: %.2f minutes\n"), (((float) total_stats->total_time / 60.0) / (float) total_stats->entries)); } stats_free (total_stats); list_destroy (&nflist); teardown (); if (fclose (stdout) == EOF) error (EXIT_FAILURE, errno, _("error writing output")); exit (error_occurred ? EXIT_FAILURE : EXIT_SUCCESS); }
/** * @brief Creates threads to handle messages received from Clients. * * @param[in] pdwClientID Connection ID used to reference the Client. * * @return Error code. * @retval SCARD_S_SUCCESS Success. * @retval SCARD_F_INTERNAL_ERROR Exceded the maximum number of simultaneous Application Contexts. * @retval SCARD_E_NO_MEMORY Error creating the Context Thread. */ LONG CreateContextThread(uint32_t *pdwClientID) { int rv; int lrv; int listSize; SCONTEXT * newContext = NULL; LONG retval = SCARD_E_NO_MEMORY; (void)pthread_mutex_lock(&contextsList_lock); listSize = list_size(&contextsList); if (listSize >= contextMaxThreadCounter) { Log2(PCSC_LOG_CRITICAL, "Too many context running: %d", listSize); goto out; } /* Create the context for this thread. */ newContext = malloc(sizeof(*newContext)); if (NULL == newContext) { Log1(PCSC_LOG_CRITICAL, "Could not allocate new context"); goto out; } memset(newContext, 0, sizeof(*newContext)); newContext->dwClientID = *pdwClientID; /* Initialise the list of card contexts */ lrv = list_init(&newContext->cardsList); if (lrv < 0) { Log2(PCSC_LOG_CRITICAL, "list_init failed with return value: %d", lrv); goto out; } /* request to store copies, and provide the metric function */ list_attributes_copy(&newContext->cardsList, list_meter_int32_t, 1); /* Adding a comparator * The stored type is SCARDHANDLE (long) but has only 32 bits * usefull even on a 64-bit CPU since the API between pcscd and * libpcscliter uses "int32_t hCard;" */ lrv = list_attributes_comparator(&newContext->cardsList, list_comparator_int32_t); if (lrv != 0) { Log2(PCSC_LOG_CRITICAL, "list_attributes_comparator failed with return value: %d", lrv); list_destroy(&newContext->cardsList); goto out; } (void)pthread_mutex_init(&newContext->cardsList_lock, NULL); lrv = list_append(&contextsList, newContext); if (lrv < 0) { Log2(PCSC_LOG_CRITICAL, "list_append failed with return value: %d", lrv); list_destroy(&newContext->cardsList); goto out; } rv = ThreadCreate(&newContext->pthThread, THREAD_ATTR_DETACHED, (PCSCLITE_THREAD_FUNCTION( )) ContextThread, (LPVOID) newContext); if (rv) { int lrv2; Log2(PCSC_LOG_CRITICAL, "ThreadCreate failed: %s", strerror(rv)); lrv2 = list_delete(&contextsList, newContext); if (lrv2 < 0) Log2(PCSC_LOG_CRITICAL, "list_delete failed with error %d", lrv2); list_destroy(&newContext->cardsList); goto out; } /* disable any suicide alarm */ if (AutoExit) alarm(0); retval = SCARD_S_SUCCESS; out: (void)pthread_mutex_unlock(&contextsList_lock); if (retval != SCARD_S_SUCCESS) { if (newContext) free(newContext); (void)close(*pdwClientID); } return retval; }
/* ************************************************************************************************************************ * Create a queue * * Description: This function is called to create a queue. * * Arguments :p_q is the address of queue size object want to be initialized * ----- * name_ptr is the queue object name * ----- * msg_start is the start address of msg buffer. * ------ * number is the number of msgs of the queue. * Returns * RAW_SUCCESS: raw os return success * Note(s) * * ************************************************************************************************************************ */ RAW_OS_ERROR raw_queue_size_create(RAW_QUEUE_SIZE *p_q, RAW_U8 *p_name, RAW_MSG_SIZE *msg_start, MSG_SIZE_TYPE number) { RAW_MSG_SIZE *p_msg1; RAW_MSG_SIZE *p_msg2; #if (RAW_QUEUE_SIZE_FUNCTION_CHECK > 0) if (p_q == 0) { return RAW_NULL_OBJECT; } if (msg_start == 0) { return RAW_NULL_POINTER; } if (number == 0) { return RAW_ZERO_NUMBER; } #endif list_init(&p_q->common_block_obj.block_list); p_q->common_block_obj.name = p_name; p_q->common_block_obj.block_way = RAW_BLOCKED_WAY_PRIO; p_q->queue_current_msg = 0; p_q->peak_numbers = 0; p_q->queue_size_full_callback = 0; p_q->queue_msg_size = number; p_q->free_msg = msg_start; /*init the free msg list*/ p_msg1 = msg_start; p_msg2 = msg_start; p_msg2++; while (--number) { p_msg1->next = p_msg2; p_msg1->msg_ptr = 0; p_msg1->msg_size = 0; p_msg1++; p_msg2++; } /*init the last free msg*/ p_msg1->next = 0; p_msg1->msg_ptr = 0; p_msg1->msg_size = 0; p_q->common_block_obj.object_type = RAW_QUEUE_SIZE_OBJ_TYPE; TRACE_QUEUE_SIZE_CREATE(raw_task_active, p_q); return RAW_SUCCESS; }
/** * @brief Destroys a list * * @param list List to be destroyed */ void list_destroy(List *list) { free(list->data); list_init(list); }
int main(int argc, char **args) { //list1 x^10 s_list *list1 = (s_list *) malloc(sizeof(s_list)); list_init(list1); list_insert_value(list1, 0, 10, 1); //list2 2x^6 s_list *list2 = (s_list *) malloc(sizeof(s_list)); list_init(list2); list_insert_value(list2, 0, 6, 2); //list1 (x^10 + 2x^6) list_append(list1, list2); //list3 (x^10 + 2x^6)y^3 s_list *list3 = (s_list *) malloc(sizeof(s_list)); list_init(list3); list_insert_value(list3, 1, 3, (int) list1); //list4 3x^5 s_list *list4 = (s_list *) malloc(sizeof(s_list)); list_init(list4); list_insert_value(list4, 0, 5, 3); //list5 (3x^5)y^2 s_list *list5 = (s_list *) malloc(sizeof(s_list)); list_init(list5); list_insert_value(list5, 1, 2, (int) list4); //list3 ((x^10 + 2x^6)y^3 + (3x^5)y^2) list_append(list3, list5); //list6 ((x^10 + 2x^6)y^3 + (3x^5)y^2)z^2 s_list *list6 = (s_list *) malloc(sizeof(s_list)); list_init(list6); list_insert_value(list6, 1, 2, (int) list3); //list7 x^4 s_list *list7 = (s_list *) malloc(sizeof(s_list)); list_init(list7); list_insert_value(list7, 0, 4, 1); //list8 6x^3 s_list *list8 = (s_list *) malloc(sizeof(s_list)); list_init(list8); list_insert_value(list8, 0, 3, 6); //list8 (x^4 + 6x^3) list_append(list7, list8); //list9 (x^4 + 6x^3)y^4 s_list *list9 = (s_list *) malloc(sizeof(s_list)); list_init(list9); list_insert_value(list9, 1, 4, (int) list7); //list10 2y s_list *list10 = (s_list *) malloc(sizeof(s_list)); list_init(list10); list_insert_value(list10, 0, 1, 2); //list9 ((x^4 + 6x^3)y^4 + 2y) list_append(list9, list10); //list11 ((x^4 + 6x^3)y^4 + 2y)z s_list *list11 = (s_list *) malloc(sizeof(s_list)); list_init(list11); list_insert_value(list11, 1, 1, (int) list9); //list6 ((x^10 + 2x^6)y^3 + (3x^5)y^2)z^2 + ((x^4 + 6x^3)y^4 + 2y)z list_append(list6, list11); //list12 15 s_list *list12 = (s_list *) malloc(sizeof(s_list)); list_init(list12); list_insert_value(list12, 0, 0, 15); //list6 ((x^10 + 2x^6)y^3 + (3x^5)y^2)z^2 + ((x^4 + 6x^3)y^4 + 2y)z + 15 list_append(list6, list12); //显示多项式 list_display(list6, 'z'); printf("\n"); //求广义表list6深度 int depth = 0; list_depth(list6, &depth); printf("depth = %d \n", depth); s_list *list13 = (s_list *) malloc(sizeof(s_list)); list_copy(list13, list6); //显示多项式 list_display(list13, 'z'); printf("\n"); //求广义表list13深度 depth = 0; list_depth(list13, &depth); printf("depth = %d \n", depth); //销毁广义表,释放内存 list_destory(list6); //销毁广义表,释放内存 list_destory(list13); return 0; }
static void default_init(void) { list_init(&free_list); nr_free = 0; // 空闲的页的数目为0,是吧! }
void l_scan (SOURCE_FILE * sf) { int r = 1,in_sub = FALSE; int block_stack[STACK_SIZE],block_size = 0; list_init(&list_sub); list_init(&list_var); list_init(&list_array); while(r) { r = l_get_line(sf); pline = line; l_get_token (); // skip empty line if (token_type==TT_LINE_END) continue; // check command if (IS_KEYWORD(token_type)) { if (token_type==KEY_SUB) { USER_SUB * sub; if(in_sub) { merror_msg("sub procedure can not be nested"); } in_sub = TRUE; match_type(TT_ID); sub = (USER_SUB*)calloc(sizeof(USER_SUB),1); sub->name = s_strdup(token); sub->pos = sf->pos; list_push(&list_sub,sub); match_type(TT_LINE_END); push_block(B_SUB); continue; } else if (token_type==KEY_END) { if (block_size<=0 || block_top==B_REPEAT) merror_illegal_token(); match_type(TT_LINE_END); if(pop_block==B_SUB) { in_sub = FALSE; } continue; } else if(token_type==KEY_VAR) { while(1) { match_type(TT_ID); l_get_token(); if (token_type==TT_END) break; else if (token_type==TT_COM) continue; else merror_illegal_token(); } } if (!in_sub) merror_illegal_token(); if(token_type==KEY_IF) { match_exp(pline); match_type(TT_LINE_END); push_block(B_IF); } else if (token_type==KEY_ELSEIF) { if (block_size<=0 || block_top!=B_IF) merror_illegal_token(); match_exp(pline); match_type(TT_LINE_END); } else if (token_type==KEY_ELSE) { if (block_size<=0 || !(block_top==B_IF || block_top==B_CASE)) merror_illegal_token(); match_type(TT_LINE_END); } else if (token_type==KEY_WHILE) { match_exp(pline); match_type(TT_LINE_END); push_block(B_WHILE); } else if (token_type==KEY_FOR) { // 'for' ID '=' EXP 'to' EXP match_type(TT_ID); match_type(OPR_EQ); match_exp(pline); match_str("to"); match_exp(pline); l_get_token(); if (token_type!=TT_LINE_END) { if (!str_eq(token,"step")) merror_expect("step"); match_exp(pline); match_type(TT_LINE_END); } push_block(B_FOR); } else if (token_type==KEY_CASE) { match_type(TT_ID); match_type(TT_LINE_END); push_block(B_CASE); } else if (token_type==KEY_REPEAT) { match_type(TT_LINE_END); push_block(B_REPEAT); } else if (token_type==KEY_UNTIL) { if (block_size<=0 || block_top!=B_REPEAT) merror_illegal_token(); match_exp(pline); match_type(TT_LINE_END); pop_block; } else if (token_type==KEY_WHEN) { if (block_size<=0 || block_top!=B_CASE) merror_illegal_token(); match_exp(pline); match_type(TT_LINE_END); } else if (token_type==KEY_GOSUB) { match_type(TT_ID); match_type(TT_LINE_END); } else if (token_type==KEY_EXIT) { match_type(TT_LINE_END); } else if (token_type==KEY_BREAK) { match_type(TT_LINE_END); } else if (token_type==KEY_RETURN) { match_type(TT_LINE_END); } else if (token_type==KEY_DIM) { while(1) { match_type (TT_ID); match_type (TT_LBK); match_exp (pline); match_type (TT_RBK); l_get_token(); if (token_type==TT_COM) continue; else if (token_type==TT_LINE_END) break; else merror_illegal_token(); } } } else if (token_type==TT_ID) { if (!in_sub) merror_illegal_token(); if (str_eq(token,"print")) { while(1) { l_get_token(); if(token_type!=TT_STRING) { l_put_back(); match_exp(pline); } l_get_token(); if(token_type==TT_LINE_END) break; else if (token_type==TT_COM) continue; else merror_expect(","); } } else if (str_eq(token,"input")) { while(1) { match_type(TT_ID); l_get_token(); if(token_type==TT_LINE_END) break; else if (token_type==TT_COM) continue; else merror_expect(","); } } else { // match: [var][=][exp] l_get_token(); if (token_type==OPR_EQ) { match_exp(pline); match_type(TT_LINE_END); } else { if (token_type!=TT_LBK)merror_expect("("); match_exp(pline); match_type(TT_RBK); match_type(OPR_EQ); match_exp(pline); match_type(TT_LINE_END); } } } else merror_illegal_token (); } if (block_size>0) merror_msg("incompleted '%s' block!",BLOCK_NAME[block_top]); }
// LAB2: below code is used to check the first fit allocation algorithm (your EXERCISE 1) // NOTICE: You SHOULD NOT CHANGE basic_check, default_check functions! static void default_check(void) { // 好吧,我们现在来看一下默认的测试吧! int count = 0, total = 0; list_entry_t *le = &free_list; // free_list应该是一个文件头吧! while ((le = list_next(le)) != &free_list) { // 开始遍历 struct Page *p = le2page(le, page_link); assert(PageProperty(p)); count ++, total += p->property; // counter表示一个有多少个page,total表示一共有多少个空闲页 } assert(total == nr_free_pages()); basic_check(); struct Page *p0 = alloc_pages(5), *p1, *p2; // 分配5个页面给p0 assert(p0 != NULL); assert(!PageProperty(p0)); list_entry_t free_list_store = free_list; list_init(&free_list); assert(list_empty(&free_list)); assert(alloc_page() == NULL); // 然后分配一个页面应该为空,确实应该为空 unsigned int nr_free_store = nr_free; // 空闲的页面的数目 nr_free = 0; // 然后将他们全部变为0 free_pages(p0 + 2, 3); // 这个玩意能free吗? assert(alloc_pages(4) == NULL); // 因为nr_free=3 assert(PageProperty(p0 + 2) && p0[2].property == 3); assert((p1 = alloc_pages(3)) != NULL); // 给p1分配3块,现在nr_free=0 assert(alloc_page() == NULL); assert(p0 + 2 == p1); p2 = p0 + 1; free_page(p0); // 好吧,释放一个页面, nr_free=1 free_pages(p1, 3); // 现在nr_free = 4 assert(PageProperty(p0) && p0->property == 1); assert(PageProperty(p1) && p1->property == 3); /** p0 p2 p1 end * | | | | | | * ------------------------------- * | N N N N | * | | * ------------------------------- */ assert((p0 = alloc_page()) == p2 - 1); // 这里出错了。我倒是要看一看啦!这里应该不会出错啊,参照上面的图,重新分配的话,会分配p0,恰好是p2-1 free_page(p0); assert((p0 = alloc_pages(2)) == p2 + 1); // 这里是测试first fit的 /** start p2 p0 end * | | | | | | * ------------------------------- * | N N | * | | * ------------------------------- */ free_pages(p0, 2); free_page(p2); /** start p2 p0 end * | | | | | | * ------------------------------- * | N N N N N | * | | * ------------------------------- */ assert((p0 = alloc_pages(5)) != NULL); assert(alloc_page() == NULL); assert(nr_free == 0); nr_free = nr_free_store; // 恢复原来的样子 free_list = free_list_store; free_pages(p0, 5); le = &free_list; while ((le = list_next(le)) != &free_list) { // 又要开始遍历了,这里主要是测试经过这么折腾之后,没有出现页丢失的情况 struct Page *p = le2page(le, page_link); count --, total -= p->property; } assert(count == 0); assert(total == 0); }
struct obj_cache *cache_init( void ) { struct obj_cache *cache = (struct obj_cache *) myalloc( sizeof(struct obj_cache) ); cache->list = list_init(); cache->hash = hash_init( CACHE_SIZE ); return cache; }
void watch(char *path, bool is_link) { // Add initial path to the watch list LIST_NODE *node = get_from_path(path); if (node == NULL) node = add_to_watch_list(path); // Searchs and increments the reference counter // of the link in list_link if (is_link) add_to_link_list(node); // Temporary list to perform breath-first-search LIST *list = list_init(); list_push(list, (void *) path); // Traverse directory DIR *dir_stream; struct dirent *dir; while (list->first != NULL) { // Directory to watch char *p = (char*) list_pop(list); // Traverse directory dir_stream = opendir(p); while (dir = readdir(dir_stream)) { if (dir->d_type == DT_DIR && strcmp(dir->d_name, ".") == 1 && strcmp(dir->d_name, "..") == 1) { char *path_to_watch = (char*) malloc(sizeof(char) * (strlen(p) + strlen(dir->d_name) + 2)); strcpy(path_to_watch, p); strcat(path_to_watch, dir->d_name); strcat(path_to_watch, "/"); // Add to the watch list if (get_from_path(path_to_watch) == NULL) add_to_watch_list(path_to_watch); // Continue directory traversing list_push(list, (void*) path_to_watch); } // Resolve symbolic link else if (dir->d_type == DT_LNK) { char *path_to_watch = (char*) malloc(sizeof(char) * (strlen(p) + strlen(dir->d_name) + 1)); strcpy(path_to_watch, p); strcat(path_to_watch, dir->d_name); char *real_path = resolve_real_path(path_to_watch); // Test for: // 1. is a real path // 2. is a directory if (real_path != NULL && opendir(real_path) != NULL) { // Add to the watch list if it's not present LIST_NODE *node = get_from_path(real_path); if (node == NULL) node = add_to_watch_list(real_path); // Searchs and increments the reference counter // of the link in list_link add_to_link_list(node); // Continue directory traversing list_push(list, (void*) real_path); } } } closedir(dir_stream); } // Free memory list_free(list); }
void heap_pool_init(heap_pool_t *heap) { memset(heap, 0, sizeof(*heap)); list_init(&heap->custom_blocks); }
/* * ctxt_switch_dump_diff() * dump differences between old and new events */ void ctxt_switch_dump_diff(json_object *j_tests, const double duration) { link_t *l; list_t sorted; #ifndef JSON_OUTPUT (void)j_tests; #endif printf("Context Switches:\n"); list_init(&sorted); for (l = ctxt_switch_info_finish.head; l; l = l->next) { ctxt_switch_info_t *new_info, *info = (ctxt_switch_info_t *)l->data; if (!info->valid) continue; if ((new_info = calloc(1, sizeof(*info))) == NULL) { health_check_out_of_memory("allocating context switch information"); goto out; } new_info->proc = info->proc; ctxt_switch_delta(info, &ctxt_switch_info_start, &new_info->total, &new_info->voluntary, &new_info->involuntary); if (list_add_ordered(&sorted, new_info, ctx_switch_cmp) == NULL) { free(new_info); goto out; } } if (sorted.head) { if (opt_flags & OPT_BRIEF) { double rate = 0.0; for (l = sorted.head; l; l = l->next) { ctxt_switch_info_t *info = (ctxt_switch_info_t *)l->data; rate += (double)info->total; } rate /= duration; printf(" %.2f context switches/sec (%s)\n\n", rate, ctxt_switch_loading(rate)); } else { int count = 0; double total_total = 0.0, total_voluntary = 0.0, total_involuntary = 0.0; const int pid_size = pid_max_digits(); printf(" %*s Process Voluntary Involuntary Total\n", pid_size, "PID"); printf(" %*s Ctxt Sw/Sec Ctxt Sw/Sec Ctxt Sw/Sec\n", pid_size, " "); for (l = sorted.head; l; l = l->next) { ctxt_switch_info_t *info = (ctxt_switch_info_t *)l->data; printf(" %*d %-20.20s %12.2f %12.2f %12.2f (%s)\n", pid_size, info->proc->pid, info->proc->cmdline, (double)info->voluntary / duration, (double)info->involuntary / duration, (double)info->total / duration, ctxt_switch_loading((double)info->total / duration)); total_voluntary += (double)info->voluntary; total_involuntary += (double)info->involuntary; total_total += (double)info->total; count++; } if (count > 1) printf(" %-27.27s%12.2f %12.2f %12.2f\n", "Total", total_voluntary / duration, total_involuntary / duration, total_total / duration); printf("\n"); } } else { printf(" No context switches detected.\n\n"); } #ifdef JSON_OUTPUT if (j_tests) { json_object *j_ctxt_switch_test, *j_ctxt_switches, *j_ctxt_switch; uint64_t total = 0; double total_rate; if ((j_ctxt_switch_test = j_obj_new_obj()) == NULL) goto out; j_obj_obj_add(j_tests, "context-switches", j_ctxt_switch_test); if ((j_ctxt_switches = j_obj_new_array()) == NULL) goto out; j_obj_obj_add(j_ctxt_switch_test, "context-switches-per-process", j_ctxt_switches); for (l = sorted.head; l; l = l->next) { ctxt_switch_info_t *info = (ctxt_switch_info_t *)l->data; total += (double)info->total; if ((j_ctxt_switch = j_obj_new_obj()) == NULL) goto out; j_obj_new_int32_add(j_ctxt_switch, "pid", info->proc->pid); j_obj_new_int32_add(j_ctxt_switch, "ppid", info->proc->ppid); j_obj_new_int32_add(j_ctxt_switch, "is-thread", info->proc->is_thread); j_obj_new_string_add(j_ctxt_switch, "name", info->proc->cmdline); j_obj_new_int64_add(j_ctxt_switch, "voluntary-context-switches", info->voluntary); j_obj_new_double_add(j_ctxt_switch, "voluntary-context-switch-rate", (double)info->voluntary / duration); j_obj_new_int64_add(j_ctxt_switch, "involuntary-context-switches", (double)info->involuntary / duration); j_obj_new_double_add(j_ctxt_switch, "involuntary-context-switch-rate", (double)info->involuntary / duration); j_obj_new_int64_add(j_ctxt_switch, "total-context-switches", info->total); j_obj_new_double_add(j_ctxt_switch, "total-context-switch-rate", (double)info->total / duration); j_obj_new_string_add(j_ctxt_switch, "load-hint", ctxt_switch_loading((double)info->total / duration)); j_obj_array_add(j_ctxt_switches, j_ctxt_switch); } total_rate = (double)total / duration; if ((j_ctxt_switch = j_obj_new_obj()) == NULL) goto out; j_obj_obj_add(j_ctxt_switch_test, "context-switches-total", j_ctxt_switch); j_obj_new_int64_add(j_ctxt_switch, "context-switch-total", total); j_obj_new_double_add(j_ctxt_switch, "context-switch-total-rate", total_rate); j_obj_new_string_add(j_ctxt_switch, "load-hint-total", ctxt_switch_loading(total_rate)); } #endif out: list_free(&sorted, free); }
int main (int argc, char *argv[]) { size_t max_batches = 20; size_t batch_size = 2000; list_t *read_list = (list_t*) malloc (sizeof(list_t)); list_init("batches", 1, max_batches, read_list); int ret_code; double start, stop, total; char *filename = (char*) malloc ((strlen(argv[1])+1) * sizeof(char)); strncat(filename, argv[1], strlen(argv[1])); gff_file_t* file; init_log_custom(LOG_LEVEL_DEBUG, 1, NULL, "w"); #pragma omp parallel sections private(start, stop, total) lastprivate(file) { #pragma omp section { LOG_DEBUG_F("Thread %d reads the GFF file\n", omp_get_thread_num()); // Reading start = omp_get_wtime(); file = gff_open(filename); ret_code = gff_read_batches(read_list, batch_size, file); stop = omp_get_wtime(); total = (stop - start); if (ret_code) { LOG_FATAL_F("[%dR] Error code = %d\n", omp_get_thread_num(), ret_code); } LOG_INFO_F("[%dR] Time elapsed = %f s\n", omp_get_thread_num(), total); LOG_INFO_F("[%dR] Time elapsed = %e ms\n", omp_get_thread_num(), total*1000); // Writing to a new file if (argc == 3) { start = omp_get_wtime(); ret_code = gff_write(file, argv[2]); stop = omp_get_wtime(); total = (stop - start); if (ret_code) { LOG_ERROR_F("[%dW] Error code = %d\n", omp_get_thread_num(), ret_code); } LOG_INFO_F("[%dW] Time elapsed = %f s\n", omp_get_thread_num(), total); LOG_INFO_F("[%dW] Time elapsed = %e ms\n", omp_get_thread_num(), total*1000); } list_decr_writers(read_list); gff_close(file, 0); } #pragma omp section { printf("1st log debug\n"); LOG_DEBUG_F("OMP num threads = %d\n", omp_get_num_threads()); LOG_DEBUG_F("Thread %d prints info\n", omp_get_thread_num()); printf("after 1st log debug\n"); start = omp_get_wtime(); int i = 0; list_item_t* item = NULL; FILE *out = fopen("result.gff", "w"); while ( (item = list_remove_item(read_list)) != NULL ) { if (i % 200 == 0) { int debug = 1; LOG_DEBUG_F("Batch %d reached by thread %d - %zu/%zu records \n", i, omp_get_thread_num(), ((gff_batch_t*) item->data_p)->length, ((gff_batch_t*) item->data_p)->max_length); } // gff_write_to_file(file, out); // gff_batch_print(stdout, item->data_p); write_gff_batch(item->data_p, out); gff_batch_free(item->data_p); list_item_free(item); i++; } fclose(out); stop = omp_get_wtime(); total = (stop - start); LOG_INFO_F("[%d] Time elapsed = %f s\n", omp_get_thread_num(), total); LOG_INFO_F("[%d] Time elapsed = %e ms\n", omp_get_thread_num(), total*1000); } } free(read_list); return 0; }
/* * ctxt_switch_init() * initialize lists */ void ctxt_switch_init(void) { list_init(&ctxt_switch_info_start); list_init(&ctxt_switch_info_finish); }
Region::Region(void) { // Initialize the window list rect_list = (LinkedList *)__kmalloc(sizeof(LinkedList)); list_init(rect_list, __kfree); }
//----初始化窗口数据结构--------------------------------------------------------- //描述: 该函数为内部调用. //参数:pwin:窗口数据结构指针. // proc:窗口过程回调函数指针. // Text:窗口文字内容指针. // Style:窗口风格. // x,y,w,h:窗口位置和大小. // hParent:父窗口句柄. // WinId: 窗口Id. //返回:无. //------------------------------------------------------------------------------ static void _InitWindow(WINDOW *pwin,WNDPROC *proc,const char *Text,u32 Style, int x,int y,int w,int h,HWND hParent,u32 WinId) { RECT rc; _SetRect(&rc,x,y,w,h); pwin->Parent =hParent; pwin->Child =NULL; pwin->Prev =NULL; pwin->Next =NULL; pwin->PrivateData =NULL; pwin->UserData =NULL; pwin->WndProc =proc; //pwin->Text =Text; strncpy(pwin->Text,Text,250); itoa((u32)pwin,pwin->Name,16); pwin->Style =Style; pwin->WinId =WinId&0x0000FFFF; list_init(&pwin->list_timer); list_init(&pwin->node_msg_close); list_init(&pwin->node_msg_ncpaint); list_init(&pwin->node_msg_paint); if(hParent != NULL) { _ClientToScreen(hParent,(POINT*)&rc,2); } _CopyRect(&pwin->WinRect,&rc); if(Style&WS_BORDER) { pwin->BorderSize =DEF_BORDER_SIZE; _InflateRectEx(&rc, -DEF_BORDER_SIZE, -DEF_BORDER_SIZE, -DEF_BORDER_SIZE, -DEF_BORDER_SIZE); } else { pwin->BorderSize =0; } if(Style&WS_DLGFRAME) { pwin->DlgFrameSize =DEF_DLGFRAME_SIZE; _InflateRectEx(&rc, -DEF_DLGFRAME_SIZE, -DEF_DLGFRAME_SIZE, -DEF_DLGFRAME_SIZE, -DEF_DLGFRAME_SIZE); } else { pwin->DlgFrameSize =0; } if(Style&WS_CAPTION) { pwin->CaptionSize =DEF_CAPTION_SIZE; _InflateRectEx(&rc,0,-DEF_CAPTION_SIZE,0,0); } else { pwin->CaptionSize =0; } _CopyRect(&pwin->CliRect,&rc); }
// do_fork - parent process for a new child process // 1. call alloc_proc to allocate a proc_struct // 2. call setup_kstack to allocate a kernel stack for child process // 3. call copy_mm to dup OR share mm according clone_flag // 4. call wakup_proc to make the new child process RUNNABLE int do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) { int ret = -E_NO_FREE_PROC; struct proc_struct *proc; if (nr_process >= MAX_PROCESS) { goto fork_out; } ret = -E_NO_MEM; if ((proc = alloc_proc()) == NULL) { goto fork_out; } proc->parent = current; list_init(&(proc->thread_group)); assert(current->wait_state == 0); assert(current->time_slice >= 0); proc->time_slice = current->time_slice / 2; current->time_slice -= proc->time_slice; if (setup_kstack(proc) != 0) { goto bad_fork_cleanup_proc; } if (copy_sem(clone_flags, proc) != 0) { goto bad_fork_cleanup_kstack; } if (copy_fs(clone_flags, proc) != 0) { goto bad_fork_cleanup_sem; } if (copy_signal(clone_flags, proc) != 0) { goto bad_fork_cleanup_fs; } if (copy_sighand(clone_flags, proc) != 0) { goto bad_fork_cleanup_signal; } if (copy_mm(clone_flags, proc) != 0) { goto bad_fork_cleanup_sighand; } if (copy_thread(clone_flags, proc, stack, tf) != 0) { goto bad_fork_cleanup_sighand; } proc->tls_pointer = current->tls_pointer; bool intr_flag; local_intr_save(intr_flag); { proc->pid = get_pid(); proc->tid = proc->pid; hash_proc(proc); set_links(proc); if (clone_flags & CLONE_THREAD) { list_add_before(&(current->thread_group), &(proc->thread_group)); proc->gid = current->gid; } else { proc->gid = proc->pid; } } local_intr_restore(intr_flag); wakeup_proc(proc); ret = proc->pid; fork_out: return ret; bad_fork_cleanup_sighand: put_sighand(proc); bad_fork_cleanup_signal: put_signal(proc); bad_fork_cleanup_fs: put_fs(proc); bad_fork_cleanup_sem: put_sem_queue(proc); bad_fork_cleanup_kstack: put_kstack(proc); bad_fork_cleanup_proc: kfree(proc); goto fork_out; }
void init_room(struct list* l) { list_init(l); }
/*! Initializes the inode module. */ void inode_init(void) { list_init(&open_inodes); }
/** * Initialize the queue * Input: Queue* q - pointer to the queue * Output: int - 1 for OK; 0 for ERROR **/ int queue_init(Queue* q) { /* Use the list function */ if(q==NULL); return 0; return list_init(&q->l); }
// LAB2: below code is used to check the first fit allocation algorithm (your EXERCISE 1) // NOTICE: You SHOULD NOT CHANGE basic_check, default_check functions! static void default_check(void) { int count = 0, total = 0; list_entry_t *le = &free_list; while ((le = list_next(le)) != &free_list) { struct Page *p = le2page(le, page_link); assert(PageProperty(p)); count ++, total += p->property; } assert(total == nr_free_pages()); basic_check(); struct Page *p0 = alloc_pages(5), *p1, *p2; assert(p0 != NULL); assert(!PageProperty(p0)); list_entry_t free_list_store = free_list; list_init(&free_list); assert(list_empty(&free_list)); assert(alloc_page() == NULL); unsigned int nr_free_store = nr_free; nr_free = 0; free_pages(p0 + 2, 3); assert(alloc_pages(4) == NULL); assert(PageProperty(p0 + 2) && p0[2].property == 3); assert((p1 = alloc_pages(3)) != NULL); assert(alloc_page() == NULL); assert(p0 + 2 == p1); p2 = p0 + 1; free_page(p0); free_pages(p1, 3); assert(PageProperty(p0) && p0->property == 1); assert(PageProperty(p1) && p1->property == 3); assert((p0 = alloc_page()) == p2 - 1); free_page(p0); assert((p0 = alloc_pages(2)) == p2 + 1); free_pages(p0, 2); free_page(p2); assert((p0 = alloc_pages(5)) != NULL); assert(alloc_page() == NULL); assert(nr_free == 0); nr_free = nr_free_store; free_list = free_list_store; free_pages(p0, 5); le = &free_list; while ((le = list_next(le)) != &free_list) { struct Page *p = le2page(le, page_link); count --, total -= p->property; } assert(count == 0); assert(total == 0); }
int su_peer_create_bind(su_peer_t *psar, int port, const SA *destaddr, socklen_t destlen) { psar->fd = socket(destaddr->sa_family, SOCK_DGRAM, 0); if (psar->fd < 0) { err_ret("peer %x create failed, socket error", psar); return -1; } if (port > 0 && port <= 65535) { void *paddr; SA4 s4; SA6 s6; switch (destaddr->sa_family) { case PF_INET: memcpy(&s4, destaddr, destlen); /* for sin_family and more... */ s4.sin_port = htons(port); inet_pton(PF_INET, "0.0.0.0", &s4.sin_addr.s_addr); paddr = &s4; break; case PF_INET6: memcpy(&s6, destaddr, destlen); /* for sin6_family and more... */ s6.sin6_port = htons(port); inet_pton(PF_INET6, "::", &s6.sin6_addr.__in6_u); paddr = &s6; break; default: close(psar->fd); psar->fd = -1; errno = EINVAL; return -1; } int reuse = 1; if (setsockopt(psar->fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)) < 0) { close(psar->fd); psar->fd = -1; return -1; } if (bind(psar->fd, paddr, destlen) < 0) { close(psar->fd); psar->fd = -1; return -1; } } if (setfd_nonblock(psar->fd) < 0) { close(psar->fd); psar->fd = -1; return -1; } memset(&psar->destaddr, 0, sizeof(SAUN)); memcpy(&psar->destaddr, destaddr, destlen); psar->destlen = destlen; psar->seq = 0; psar->rttinit = 0; psar->retry = RTT_MAXNREXMT; psar->ackwaitnum = 0; list_init(&psar->ackrecvls); list_init(&psar->synrecvls); list_init(&psar->lsackcache); rbt_init(&psar->rbackcache, cache_getkey, search_cache_cmp); psar->nowsynframe = 0; pthread_mutex_init(&psar->mutex, 0); pthread_mutex_init(&psar->lock, 0); pthread_cond_init(&psar->ackcond, 0); pthread_cond_init(&psar->syncond, 0); pthread_mutex_init(&psar->cachelock, 0); if (su_peer_thread_install(psar) < 0) { pthread_mutex_destroy(&psar->mutex); pthread_mutex_destroy(&psar->lock); pthread_cond_destroy(&psar->ackcond); pthread_cond_destroy(&psar->syncond); pthread_mutex_destroy(&psar->cachelock); close(psar->fd); psar->fd = -1; return -1; } pthread_mutex_lock(&emutex); if (sugem == 0) { sugem = Em_open(100, -1, 0, 0, 0); Em_run(sugem, 1); struct timeval now; gettimeofday(&now, 0); srand(now.tv_sec % 1000 + now.tv_usec); } psar->sid = rand() % 65535; pthread_mutex_unlock(&emutex); memset(&psar->fe, 0, sizeof(fe_t)); fe_init(&psar->fe, sugem, psar->fd); fe_set(&psar->fe, EPOLLIN, handle_su_peer_recv); fe_set(&psar->fe, EPOLLET, 0); Fe_em_add(&psar->fe); return psar->fd; }
stack_t* stack_init(int (*compare)(void*, void*), void (*print)(void*, FILE*), void* (*clone)(void*), void (*destroy)(void*)) { return (stack_t*)list_init(compare, print, clone, destroy); }
int mm_unmap_keep_pages(struct mm_struct *mm, uintptr_t addr, size_t len) { uintptr_t start = ROUNDDOWN(addr, PGSIZE), end = ROUNDUP(addr + len, PGSIZE); if (!USER_ACCESS(start, end)) { return -E_INVAL; } assert(mm != NULL); struct vma_struct *vma; if ((vma = find_vma(mm, start)) == NULL || end <= vma->vm_start) { return 0; } if (vma->vm_start < start && end < vma->vm_end) { struct vma_struct *nvma; if ((nvma = vma_create(vma->vm_start, start, vma->vm_flags)) == NULL) { return -E_NO_MEM; } vma_copymapfile(nvma, vma); vma_resize(vma, end, vma->vm_end); insert_vma_struct(mm, nvma); return 0; } list_entry_t free_list, *le; list_init(&free_list); while (vma->vm_start < end) { le = list_next(&(vma->list_link)); remove_vma_struct(mm, vma); list_add(&free_list, &(vma->list_link)); if (le == &(mm->mmap_list)) { break; } vma = le2vma(le, list_link); } le = list_next(&free_list); while (le != &free_list) { vma = le2vma(le, list_link); le = list_next(le); uintptr_t un_start, un_end; if (vma->vm_start < start) { un_start = start, un_end = vma->vm_end; vma_resize(vma, vma->vm_start, un_start); insert_vma_struct(mm, vma); } else { un_start = vma->vm_start, un_end = vma->vm_end; if (end < un_end) { un_end = end; vma_resize(vma, un_end, vma->vm_end); insert_vma_struct(mm, vma); } else { vma_unmapfile(vma); vma_destroy(vma); } } //unmap_range(mm->pgdir, un_start, un_end); } return 0; }
int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) { sc_context_t *ctx; struct _sc_ctx_options opts; int r; if (ctx_out == NULL || parm == NULL) return SC_ERROR_INVALID_ARGUMENTS; ctx = calloc(1, sizeof(sc_context_t)); if (ctx == NULL) return SC_ERROR_OUT_OF_MEMORY; memset(&opts, 0, sizeof(opts)); /* set the application name if set in the parameter options */ if (parm->app_name != NULL) ctx->app_name = strdup(parm->app_name); else ctx->app_name = strdup("default"); if (ctx->app_name == NULL) { sc_release_context(ctx); return SC_ERROR_OUT_OF_MEMORY; } set_defaults(ctx, &opts); list_init(&ctx->readers); list_attributes_seeker(&ctx->readers, reader_list_seeker); /* set thread context and create mutex object (if specified) */ if (parm->thread_ctx != NULL) ctx->thread_ctx = parm->thread_ctx; r = sc_mutex_create(ctx, &ctx->mutex); if (r != SC_SUCCESS) { sc_release_context(ctx); return r; } process_config_file(ctx, &opts); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "==================================="); /* first thing in the log */ sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "opensc version: %s", sc_get_version()); #ifdef HAVE_LTDL_H /* initialize ltdl, if available. See scdl.c for more information */ if (lt_dlinit() != 0) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "lt_dlinit() failed"); sc_release_context(ctx); return SC_ERROR_INTERNAL; } #endif #ifdef ENABLE_PCSC ctx->reader_driver = sc_get_pcsc_driver(); /* XXX: remove cardmod pseudoreader driver */ #ifdef ENABLE_MINIDRIVER if(strcmp(ctx->app_name, "cardmod") == 0) { ctx->reader_driver = sc_get_cardmod_driver(); } #endif #elif defined(ENABLE_CTAPI) ctx->reader_driver = sc_get_ctapi_driver(); #elif defined(ENABLE_OPENCT) ctx->reader_driver = sc_get_openct_driver(); #endif load_reader_driver_options(ctx); ctx->reader_driver->ops->init(ctx); load_card_drivers(ctx, &opts); load_card_atrs(ctx); if (opts.forced_card_driver) { /* FIXME: check return value? */ sc_set_card_driver(ctx, opts.forced_card_driver); free(opts.forced_card_driver); } del_drvs(&opts); sc_ctx_detect_readers(ctx); *ctx_out = ctx; return SC_SUCCESS; }
int main(int argc, char* argv[]){ if(argc > 3) { printf("You may only enter a filename and an option.\necho sort tail tail-remove\nExiting...\n"); exit(-1); } else if (argc < 3) { printf("You must enter both a filename and an option.\necho sort tail tail-remove\nExiting...\n"); exit(-1); } // Open the supplied input file read only FILE *input_file = fopen(argv[1], "r"); if(input_file == NULL) { perror("Please enter a different filename"); exit(-1); } // Echo the file if(strcmp(argv[2], "echo") == 0) { char echo_buf[41]; while(read_line(input_file, echo_buf, 41)) { printf("%s\n", echo_buf); memset(echo_buf, '\0', 41); } } // Put the file in a list and visit-print the list else if(strcmp(argv[2], "tail") == 0) { list_t list; list_init(&list, list_item_compare_string, string_data_delete); char *tail_buf = malloc(41*sizeof(char)); if(tail_buf == NULL) { perror("malloc failed to create new buffer."); exit(-1); } while(read_line(input_file, tail_buf, 41)) { list_insert_tail(&list, tail_buf); tail_buf = malloc(41*sizeof(char)); if(tail_buf == NULL) { perror("malloc failed to create new buffer."); exit(-1); } } // Free the last buffer created when we looped last free(tail_buf); list_visit_items(&list, print_data_string); cleanup_list(&list); } // Insert the file into a sorted list ** Does not seem to sort correctly** else if(strcmp(argv[2], "sort") == 0) { list_t list; list_init(&list, list_item_compare_string, string_data_delete); char *sort_buf = malloc(41*sizeof(char)); if(sort_buf == NULL) { perror("malloc failed to create new buffer."); exit(-1); } while(read_line(input_file, sort_buf, 41)) { list_insert_sorted(&list, sort_buf); sort_buf = malloc(41*sizeof(char)); if(sort_buf == NULL) { perror("malloc failed to create new buffer."); exit(-1); } } // Free last buffer created as it is unused free(sort_buf); list_visit_items(&list, print_data_string); cleanup_list(&list); } // Insert the file into a list in order and then remove 3 head nodes until it is empty else if(strcmp(argv[2], "tail-remove") == 0) { printf("Running tail-remove\n"); list_t list; list_init(&list, list_item_compare_string, string_data_delete); char *rem_buf = malloc(41*sizeof(char)); if(rem_buf == NULL) { perror("malloc failed to create new buffer."); exit(-1); } while(read_line(input_file, rem_buf, 41)) { list_insert_tail(&list, rem_buf); rem_buf = malloc(41*sizeof(char)); } // Free last buffer created free(rem_buf); unsigned int three_sets = (list.length)/3; unsigned int i; list_visit_items(&list, print_data_string); for(i = 0; i < three_sets; i++) { list_remove_head(&list); list_remove_head(&list); list_remove_head(&list); printf("----------------------------------------\n"); list_visit_items(&list, print_data_string); } cleanup_list(&list); printf("----------------------------------------\n"); list_visit_items(&list, print_data_string); } fclose(input_file); return 0; };