/* deserializes a single file from the binary. */ static size_t deserialize_file(unsigned char* buffer, char* basedir, size_t offset) { unsigned char* orig_buffer = buffer; size_t len; char* relpath = NULL; BUFFER_READ_STR2(relpath, len); assert(len > 0); char* content = NULL; BUFFER_READ_STR2(content, len); assert(len > 0); char *p = basedir + offset; strcpy(p, relpath); free(relpath); char *fullpath = basedir; if (pocl_exists(fullpath)) goto RET; char* dir = strdup(basedir); char* dirpath = dirname(dir); if (!pocl_exists(dirpath)) pocl_mkdir_p(dirpath); free(dir); pocl_write_file(fullpath, content, len, 0, 0); RET: free(content); return (buffer - orig_buffer); }
static int make_kernel_cachedir_path(char* kernel_cachedir_path, cl_program program, unsigned device_i, cl_kernel kernel, unsigned spmd, size_t local_x, size_t local_y, size_t local_z) { assert(kernel->name); char tempstring[POCL_FILENAME_LENGTH]; int bytes_written; if (spmd) { bytes_written = snprintf(tempstring, POCL_FILENAME_LENGTH, "/%s/SPMD", kernel->name); } else { bytes_written = snprintf(tempstring, POCL_FILENAME_LENGTH, "/%s/%zu-%zu-%zu", kernel->name, local_x, local_y, local_z); } assert(bytes_written > 0 && bytes_written < POCL_FILENAME_LENGTH); program_device_dir(kernel_cachedir_path, program, device_i, tempstring); return pocl_mkdir_p(kernel_cachedir_path); }
void pocl_cache_init_topdir() { if (cache_topdir_initialized) return; const char *tmp_path = pocl_get_string_option("POCL_CACHE_DIR", NULL); int needed; if (tmp_path && (pocl_exists(tmp_path))) { needed = snprintf(cache_topdir, POCL_FILENAME_LENGTH, "%s", tmp_path); } else { #ifdef POCL_ANDROID char* process_name = pocl_get_process_name(); needed = snprintf(cache_topdir, POCL_FILENAME_LENGTH, "/data/data/%s/cache/", process_name); free(process_name); if (!pocl_exists(cache_topdir)) needed = snprintf(cache_topdir, POCL_FILENAME_LENGTH, "/sdcard/pocl/kcache"); #elif defined(_MSC_VER) || defined(__MINGW32__) tmp_path = getenv("LOCALAPPDATA"); if (!tmp_path) tmp_path = getenv("TEMP"); assert(tmp_path); needed = snprintf(cache_topdir, POCL_FILENAME_LENGTH, "%s\\pocl", tmp_path); #else // "If $XDG_CACHE_HOME is either not set or empty, a default equal to // $HOME/.cache should be used." // http://standards.freedesktop.org/basedir-spec/latest/ tmp_path = getenv("XDG_CACHE_HOME"); if (tmp_path && tmp_path[0] != '\0') { needed = snprintf(cache_topdir, POCL_FILENAME_LENGTH, "%s/pocl/kcache", tmp_path); } else if ((tmp_path = getenv("HOME")) != NULL) { needed = snprintf(cache_topdir, POCL_FILENAME_LENGTH, "%s/.cache/pocl/kcache", tmp_path); } else { needed = snprintf(cache_topdir, POCL_FILENAME_LENGTH, "/tmp/pocl/kcache"); } #endif } if (needed >= POCL_FILENAME_LENGTH) { POCL_ABORT("pocl: cache path longer than maximum filename length"); } assert(strlen(cache_topdir) > 0); if (pocl_mkdir_p(cache_topdir)) POCL_ABORT("Could not create topdir for cache"); cache_topdir_initialized = 1; }
int pocl_cache_create_program_cachedir(cl_program program, unsigned device_i, const char* preprocessed_source, size_t source_len, char* program_bc_path, void** cache_lock) { const char *hash_source = NULL; uint8_t old_build_hash[SHA1_DIGEST_SIZE] = {0}; size_t hs_len = 0; assert(cache_topdir_initialized); if (program->source && preprocessed_source==NULL) { hash_source = program->source; hs_len = strlen(program->source); } else { hash_source = preprocessed_source; hs_len = source_len; } if (program->build_hash[device_i]) memcpy(old_build_hash, program->build_hash[device_i], SHA1_DIGEST_SIZE); build_program_compute_hash(program, device_i, hash_source, hs_len); /* if the old hash is nonzero and different, we must free the built binaries before returning, so that they get loaded from the new location */ if (old_build_hash[0] && memcmp(old_build_hash, program->build_hash[device_i], SHA1_DIGEST_SIZE)) { if (program->binaries[device_i]) { POCL_MEM_FREE(program->binaries[device_i]); program->binary_sizes[device_i] = 0; } pocl_free_llvm_irs(program, device_i); } program_device_dir(program_bc_path, program, device_i, ""); if (pocl_mkdir_p(program_bc_path)) return 1; pocl_cache_program_bc_path(program_bc_path, program, device_i); *cache_lock = pocl_cache_acquire_writer_lock_i(program, device_i); return 0; }
int pocl_mkdir_p (const char* path) { int error; int errno_tmp; error = mkdir (path, S_IRWXU); if (error && errno == ENOENT) { // creates all needed directories recursively char *previous_path; int previous_path_length = strrchr (path, '/') - path; previous_path = malloc (previous_path_length + 1); strncpy (previous_path, path, previous_path_length); previous_path[previous_path_length] = '\0'; pocl_mkdir_p ((const char*) previous_path); free (previous_path); error = mkdir (path, S_IRWXU); } else if (error && errno == EEXIST) error = 0; return error; }
int pocl_cache_write_descriptor(cl_program program, unsigned device_i, const char* kernel_name, const char* content, size_t size) { char devdir[POCL_FILENAME_LENGTH]; program_device_dir(devdir, program, device_i, ""); char descriptor[POCL_FILENAME_LENGTH]; int bytes_written = snprintf(descriptor, POCL_FILENAME_LENGTH, "%s/%s", devdir, kernel_name); assert(bytes_written > 0 && bytes_written < POCL_FILENAME_LENGTH); if (pocl_mkdir_p(descriptor)) return 1; bytes_written = snprintf(descriptor, POCL_FILENAME_LENGTH, "%s/%s/descriptor.so.kernel_obj.c", devdir, kernel_name); assert(bytes_written > 0 && bytes_written < POCL_FILENAME_LENGTH); return pocl_write_file(descriptor, content, size, 0, 1); }