diff --git a/Makefile b/Makefile index 2b7ff74..66be544 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ include config.mk # flags and incs PKGS = $(GITLIB) -CFLAGS = -DVERSION=\"$(VERSION)\" -Wall -pedantic -O3 $(GIT) $(GITHASH) $(ERR) $(EXPLAIN) +CFLAGS = -DVERSION=\"$(VERSION)\" -Wall -pedantic -O3 $(GIT) $(GITHASH) $(ERR) $(PERF) $(EXPLAIN) LIBS = `$(PKG_CONFIG) --libs --cflags $(PKGS)` all: XD diff --git a/XD.c b/XD.c index 82925e9..de8d694 100644 --- a/XD.c +++ b/XD.c @@ -3,6 +3,7 @@ #include #include #include +#include #ifdef ERR #include @@ -31,6 +32,7 @@ char *find_git_repo(void) { + PS(); char path[PATH_MAX] = ".", fstr[PATH_MAX], *rpath, *res; struct stat s; FILE *f; @@ -40,6 +42,7 @@ char rpath = realpath(path, NULL); if (!rpath) { L("realpath: %s", strerror(errno)); + PE(); return NULL; } for (i = c = 0; i < strlen(rpath); i++) { @@ -56,22 +59,26 @@ char /* if there seems to be a git directory return the directory it was found in */ if (stat(path, &s) == 0) { if (S_ISDIR(s.st_mode)) { + PE(); return realpath(path, NULL); } else if (S_ISREG(s.st_mode)) { /* we do some special magic here to check if we're in a submodule */ f = fopen(path, "r"); if (!f) { L("fopen: %s", strerror(errno)); + PE(); return NULL; } res = fgets(fstr, PATH_MAX, f); fclose(f); if (!res) { L("fgets: %s", strerror(errno)); + PE(); return NULL; } if (strncmp(fstr, "gitdir: ", strlen("gitdir: ")) == 0) { fstr[strlen(fstr) - 1] = '\0'; + PE(); return realpath(fstr + strlen("gitdir: "), NULL); } } @@ -82,6 +89,7 @@ char memset(&path[strlen(path) - 2], 0, 2); } + PE(); return NULL; } @@ -93,11 +101,13 @@ char git_repository *init_git(void) { + PS(); char *buf; git_repository *repo; /* check for a repo before loading libgit2 */ if ((buf = find_git_repo()) == NULL) { + PE(); return NULL; } @@ -113,17 +123,20 @@ git_repository /* initialize the git library and repository */ if (git_libgit2_init() < 0) { L("Failed to initalize libgit2, proceeding without git functionality enabled."); + PE(); return NULL; } if (git_repository_open(&repo, buf) < 0) { L("Failed to open git repo: %s", git_error_last()->message); free(buf); + PE(); return NULL; } /* get rid of object containing git repo path and return the repo */ free(buf); + PE(); return repo; } @@ -136,20 +149,24 @@ git_repository int has_stashes(git_repository *repo) { + PS(); git_reference *stash = NULL; int e; e = git_reference_lookup(&stash, repo, "refs/stash"); if (e == GIT_ENOTFOUND) { + PE(); return 0; } else if (e < 0) { L("Error looking up stash reference: %s", git_error_last()->message); + PE(); return 0; } else { e = 1; } git_reference_free(stash); + PE(); return e; } @@ -162,6 +179,7 @@ has_stashes(git_repository *repo) int has_untracked(git_repository *repo) { + PS(); git_status_options opts = GIT_STATUS_OPTIONS_INIT; git_status_list *list = NULL; repohash *storedhash; @@ -173,6 +191,7 @@ has_untracked(git_repository *repo) && storedhash->hash == newhash) { r = storedhash->changes; free(storedhash); + PE(); return r; } #endif @@ -187,6 +206,7 @@ has_untracked(git_repository *repo) if (git_status_list_new(&list, repo, &opts) < 0) { L("Error checking for untracked changes: %s", git_error_last()->message); + PE(); return 0; } @@ -197,6 +217,7 @@ has_untracked(git_repository *repo) #endif git_status_list_free(list); + PE(); return r; } @@ -209,6 +230,7 @@ has_untracked(git_repository *repo) int has_staged(git_repository *repo) { + PS(); git_status_entry entry; git_status_list *list = NULL; git_status_options opts = GIT_STATUS_OPTIONS_INIT; @@ -219,6 +241,7 @@ has_staged(git_repository *repo) if (git_status_list_new(&list, repo, &opts) < 0) { L("Error checking for staged changes: %s", git_error_last()->message); + PE(); return 0; } @@ -237,6 +260,7 @@ has_staged(git_repository *repo) } git_status_list_free(list); + PE(); return r; } #endif @@ -244,17 +268,20 @@ has_staged(git_repository *repo) inline unsigned numcat(unsigned x, unsigned y) { + PS(); unsigned pow = 10; while(y >= pow) { pow *= 10; } + PE(); return (x * pow) + y; } int str_to_int(char *str) { + PS(); int res = -1; char *c; @@ -266,17 +293,20 @@ str_to_int(char *str) } } + PE(); return res; } int main(int argc, char *argv[]) { + PS(); int code = -1; /* print version information */ if (argc > 1 && strcmp(argv[1], "-v") == 0) { printf("XD [number] %s\n", VERSION); + PE(); return 0; #ifdef EXPLAIN } else if (argc > 1 && strcmp(argv[1], "-e") == 0) { @@ -328,6 +358,7 @@ main(int argc, char *argv[]) code = str_to_int(argv[argc - 1]); if (code < 0) { L("Return code, %d, not valid", code); + PE(); exit(1); } } @@ -361,5 +392,6 @@ main(int argc, char *argv[]) P("|"); /* no code info */ } + PE(); return code; } diff --git a/config.mk b/config.mk index 1bd082d..aaff33a 100644 --- a/config.mk +++ b/config.mk @@ -18,6 +18,10 @@ ERR = # uncomment to enable errors # ERR = -DERR +PERF = +# uncomment to enable performance logging +# PERF = -DPERF + EXPLAIN = # comment to disable explinations EXPLAIN = -DEXPLAIN @@ -36,6 +40,11 @@ ifeq ($(ERR),) else VERSION := $(VERSION)"\\nerrors enabled" endif +ifeq ($(PERF),) + VERSION := $(VERSION)"\\nperformance logging disabled" +else + VERSION := $(VERSION)"\\nperformance logging enabled" +endif ifeq ($(EXPLAIN),) VERSION := $(VERSION)"\\nexplinations disabled" else diff --git a/hash.c b/hash.c index 55a16f6..de2289b 100644 --- a/hash.c +++ b/hash.c @@ -15,41 +15,49 @@ static uint64_t murmur64(uint64_t k) { + PS(); k ^= k >> 33; k *= 0xff51afd7ed558ccdLLU; k ^= k >> 33; k *= 0xc4ceb9fe1a85ec53LLU; k ^= k >> 33; + PE(); return k; } uint64_t generate_hash(git_repository *repo) { + PS(); struct stat dir, index; char path[PATH_MAX] = { 0 }; const char *gitpath = git_repository_path(repo); if (strlen(gitpath) + strlen("/..") > PATH_MAX - 1) { L("strlen: %s", strerror(errno)); + PE(); return -1; } strcat(path, gitpath); if (stat(path, &index) < 0) { + PE(); return -1; } strcat(path, "/.."); if (stat(path, &dir) < 0) { + PE(); return -1; } + PE(); return murmur64(dir.st_mtim.tv_nsec ^ index.st_mtim.tv_nsec); } repohash *read_hash(git_repository *repo) { + PS(); FILE *f; uint64_t data; uint8_t changes; @@ -59,6 +67,7 @@ repohash const char *gitpath = git_repository_path(repo); if (strlen(gitpath) + strlen(XD_HASH_PATH) > PATH_MAX - 1) { L("strlen: %s", strerror(errno)); + PE(); return NULL; } strcat(path, gitpath); @@ -67,39 +76,46 @@ repohash f = fopen(path, "r"); if (!f) { L("fopen: %s", strerror(errno)); + PE(); return NULL; } if (fread(&data, sizeof(uint64_t), 1, f) != 1) { L("fread: %s", strerror(errno)); + PE(); return NULL; } if (fseek(f, sizeof(uint64_t), SEEK_SET) < 0) { L("fseek: %s", strerror(errno)); + PE(); return NULL; } if (fread(&changes, sizeof(uint8_t), 1, f) != 1) { L("fread: %s", strerror(errno)); + PE(); return NULL; } fclose(f); hash->hash = data; hash->changes = changes; + PE(); return hash; } int write_hash(git_repository *repo, repohash hash) { + PS(); FILE *f; char path[PATH_MAX] = { 0 }; const char *gitpath = git_repository_path(repo); if (strlen(gitpath) + strlen(XD_HASH_PATH) > PATH_MAX - 1) { L("strlen: %s", strerror(errno)); + PE(); return 1; } strcat(path, gitpath); @@ -108,25 +124,30 @@ write_hash(git_repository *repo, repohash hash) f = fopen(path, "wb"); if (!f) { L("fopen: %s", strerror(errno)); + PE(); return 1; } if (fwrite(&hash.hash, sizeof(uint64_t), 1, f) != 1) { L("fwrite: %s", strerror(errno)); + PE(); return 1; } if (fseek(f, sizeof(uint64_t), SEEK_SET) < 0) { L("fseek: %s", strerror(errno)); + PE(); return 1; } if (fwrite(&hash.changes, sizeof(uint8_t), 1, f) != 1) { L("fwrite: %s", strerror(errno)); + PE(); return 1; } fclose(f); + PE(); return 0; } #endif diff --git a/helpers.h b/helpers.h index 81666ab..b106667 100644 --- a/helpers.h +++ b/helpers.h @@ -18,3 +18,11 @@ extern int explain; #else #define E(...) #endif + +#ifdef PERF +#define PS() long __start = clock() +#define PE() l("%s: %fs", __func__, ((double) (clock() - __start)) / CLOCKS_PER_SEC) +#else +#define PS() +#define PE() +#endif