void parallelOperation(double **a, double **b, double **c, int size, int operation) { int i; struct work_struct *jobs[CPUCORES]; aa = a; bb = b; cc = c; matrixSize = size; for (i = 0; i < CPUCORES; i++) { jobs[i] = malloc(sizeof(struct work_struct)); if (jobs[i] == NULL) { perror(NULL); exit(1); } jobs[i]->id = i; } job_init(); switch(operation){ case MULTIPLY:{ // printf("Multiply[%d]: ", size); for (i = 1; i < CPUCORES; i++) job_create(mm, jobs[i], 0); mm(jobs[0]); }break; case VECTOR:{ // printf("Vector[%d]: ", size); for (i = 1; i < CPUCORES; i++) job_create(mv, jobs[i], 0); mv(jobs[0]); }break; case ADD:{ // printf("Add[%d]: ", size); for (i = 1; i < CPUCORES; i++) job_create(add, jobs[i], 0); add(jobs[0]); }break; case SCALE:{ // printf("Scale[%d]: ", size); for (i = 1; i < CPUCORES; i++) job_create(scale, jobs[i], 0); scale(jobs[0]); }break; } for (i = 1; i < CPUCORES; i++) job_join(jobs[i]); // printf("\n"); }
static void *_create_container_thread(void *args) { stepd_step_rec_t *job = (stepd_step_rec_t *)args; job->cont_id = (uint64_t)job_create(0, job->uid, 0); /* Signal the container_create we are done */ slurm_mutex_lock(¬ify_mutex); /* We need to signal failure or not */ pthread_cond_signal(¬ify); /* Don't unlock the notify_mutex here, wait, it is not needed * and can cause deadlock if done. */ if (job->cont_id == (jid_t)-1) error("Failed to create job container: %m"); else /* Wait around for something else to be added and then exit when that takes place. */ pthread_cond_wait(¬ify, ¬ify_mutex); slurm_mutex_unlock(¬ify_mutex); return NULL; }
/* Create job with only params that affect queue order. */ struct job *job_create_test (flux_jobid_t id, int priority) { struct job *j; if (!(j = job_create ())) BAIL_OUT ("job_create failed"); j->id = id; j->priority = priority; return j; }
int vm_send(vm_ptr vm, ENTERM data) { job_ptr job = job_create(); if(job == NULL) goto error; job->type = job_response; job->args = enif_make_copy(job->env, data); if(!queue_send(vm->jobs, job)) goto error; return 1; error: if(job != NULL) job_destroy(job); return 0; }
void vm_destroy(ErlNifEnv* env, void* obj) { vm_ptr vm = (vm_ptr) obj; job_ptr job = job_create(); void* resp; assert(job != NULL && "Failed to create job."); job->type = job_close; queue_push(vm->jobs, job); queue_send(vm->jobs, job); enif_thread_join(vm->tid, &resp); queue_destroy(vm->jobs); enif_thread_opts_destroy(vm->opts); }
/* Create queue of size jobs * id: [0:size-1] */ struct queue *make_test_queue (int size) { struct queue *q; flux_jobid_t id; q = queue_create (); if (!q) BAIL_OUT ("could not create queue"); for (id = 0; id < size; id++) { struct job *j; if (!(j = job_create (id, 0, 0, 0, 0))) BAIL_OUT ("job_create failed"); if (queue_insert (q, j) < 0) BAIL_OUT ("queue_insert failed"); } return q; }
void masterconn_create(masterconn *eptr,const uint8_t *data,uint32_t length) { uint64_t chunkid; uint32_t version; uint8_t *ptr; void *packet; if (length!=8+4) { syslog(LOG_NOTICE,"MATOCS_CREATE - wrong size (%"PRIu32"/12)",length); eptr->mode = KILL; return; } chunkid = get64bit(&data); version = get32bit(&data); packet = masterconn_create_detached_packet(eptr,CSTOMA_CREATE,8+1); ptr = masterconn_get_packet_data(packet); put64bit(&ptr,chunkid); job_create(masterconn_jobfinished,packet,chunkid,version); }
int vm_add_call(vm_ptr vm, ENTERM ref, ENPID pid, ENTERM name, ENTERM args) { job_ptr job = job_create(); if(job == NULL) goto error; job->type = job_call; job->ref = enif_make_copy(job->env, ref); job->pid = pid; job->name = enif_make_copy(job->env, name); job->args = enif_make_copy(job->env, args); if(!queue_push(vm->jobs, job)) goto error; return 1; error: if(job != NULL) job_destroy(job); return 0; }
int vm_add_eval(vm_ptr vm, ENTERM ref, ENPID pid, ENBINARY bin) { job_ptr job = job_create(); job->type = job_eval; job->ref = enif_make_copy(job->env, ref); job->pid = pid; if(!enif_alloc_binary(bin.size, &(job->script))) goto error; memcpy(job->script.data, bin.data, bin.size); if(!queue_push(vm->jobs, job)) goto error; return 1; error: if(job != NULL) job_destroy(job); return 0; }
ushort lcs(const struct sequence *s1, const struct sequence *s2) { ushort alen = s1->len; ushort blen = s2->len; job_init(); struct work_struct a_work = { .id = 0, .a = s1->str, .alen = alen, .b = s2->str, .blen = blen, .ret = NULL }; struct work_struct b_work = { .id = 1, .a = s1->str, .alen = alen, .b = s2->str, .blen = blen, .ret = NULL }; job_create(memo_lcs_front, &a_work, 0); memo_lcs_back(&b_work); job_join(&a_work); ushort *forward = a_work.ret; ushort *backward = b_work.ret; ushort i = 0; ushort ibest = 0; for (i = 1; i < blen + 1; i++) { if (forward[i] + backward[i - 1] > ibest) ibest = forward[i] + backward[i - 1]; } return ibest; }
//读取Master的packet,创建chunk //调用:masterconn_gotpacket() void masterconn_create(masterconn *eptr,const uint8_t *data,uint32_t length) { uint64_t chunkid; uint32_t version; uint8_t *ptr; #ifdef BGJOBS void *packet; #else /* BGJOBS */ uint8_t status; #endif /* BGJOBS */ if (length!=8+4) { syslog(LOG_NOTICE,"MATOCS_CREATE - wrong size (%"PRIu32"/12)",length); eptr->mode = KILL; return; } chunkid = get64bit(&data); version = get32bit(&data); #ifdef BGJOBS packet = masterconn_create_detached_packet(CSTOMA_CREATE,8+1); //封装连接packet,用于创建后台作业 if (packet==NULL) { eptr->mode=KILL; return; } ptr = masterconn_get_packet_data(packet); put64bit(&ptr,chunkid); job_create(eptr->jpool,masterconn_jobfinished,packet,chunkid,version); //建立后台作业 #else /* BGJOBS */ status = hdd_create(chunkid,version); ptr = masterconn_create_attached_packet(eptr,CSTOMA_CREATE,8+1); if (ptr==NULL) { eptr->mode=KILL; return; } put64bit(&ptr,chunkid); put8bit(&ptr,status); #endif /* BGJOBS */ }
void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options, Error **errp) { BlockdevCreateJob *s; const char *fmt = BlockdevDriver_str(options->driver); BlockDriver *drv = bdrv_find_format(fmt); /* If the driver is in the schema, we know that it exists. But it may not * be whitelisted. */ assert(drv); if (bdrv_uses_whitelist() && !bdrv_is_whitelisted(drv, false)) { error_setg(errp, "Driver is not whitelisted"); return; } /* Error out if the driver doesn't support .bdrv_co_create */ if (!drv->bdrv_co_create) { error_setg(errp, "Driver does not support blockdev-create"); return; } /* Create the block job */ /* TODO Running in the main context. Block drivers need to error out or add * locking when they use a BDS in a different AioContext. */ s = job_create(job_id, &blockdev_create_job_driver, NULL, qemu_get_aio_context(), JOB_DEFAULT | JOB_MANUAL_DISMISS, NULL, NULL, errp); if (!s) { return; } s->drv = drv, s->opts = QAPI_CLONE(BlockdevCreateOptions, options), job_start(&s->common); }
/****************************************************************************** * checks for migratability or actually does the migration ******************************************************************************/ int MigrateVirtualSystem( const CMPIBroker *broker, /* in - CMPI Broker that does most of the work */ const CMPIContext *context, /* in - CMPI context for the caller */ const CMPIArgs *argsin, /* in - All the arguments for the method */ const CMPIArgs *argsout, /* out - All the output arguments for the method */ xen_utils_session *session, /* in - Session for making xen calls */ bool host_ip, /* in - The host parameter is an IP address */ bool migrate_check_only, /* in -Check if migration is possible only, dont actually migrate */ CMPIStatus *status) /* out - Report CMPI status of method */ { char *hostid = NULL, *vm_uuid = NULL; CMPIData argdata; xen_vm vm = NULL; xen_host_set *host_set = NULL; CMPIInstance *msd = NULL; xen_host host = NULL; int rc = Xen_VirtualSystemMigrationService_MigrateVirtualSystemToSystem_Invalid_Parameter; CMPIrc statusrc = CMPI_RC_ERR_INVALID_PARAMETER; char *error_msg = "ERROR: Unknown error"; xen_string_string_map *other_config=NULL; /* For now only Live migrations are supported */ if(_GetArgument(broker, argsin, "MigrationSettingData", CMPI_chars, &argdata, status)) { /* Argument passed in as a MOF string, parse it */ msd = xen_utils_parse_embedded_instance(broker, CMGetCharPtr(argdata.value.string)); if (msd == NULL) { // parser returns zero for success, non-zero for error error_msg = "ERROR: Couldnt parse the 'MigrationSettingData' parameter"; goto Exit; } } else /* Argument could have been passed in as an intance */ if(_GetArgument(broker, argsin, "MigrationSettingData", CMPI_instance, &argdata, status)) msd = argdata.value.inst; if(msd != NULL) { CMPIData data = CMGetProperty(msd, "MigrationType", status); if(data.value.uint16 != Xen_VirtualSystemMigrationSettingData_MigrationType_Live) { error_msg = "ERROR: 'MigrationSettingData' contains an invalid MigrationType (Live expected)"; goto Exit; } } /* Host to migrate to */ if(!host_ip) { /* required parameters */ if(!_GetArgument(broker, argsin, "DestinationSystem", CMPI_ref, &argdata, status)){ error_msg = "ERROR: 'DestionationSystem' parameter is missing"; goto Exit; } else { /* This is the CIM reference to an existing Host object */ CMPIData key; key = CMGetKey(argdata.value.ref, "Name", status); if(status->rc != CMPI_RC_OK || CMIsNullValue(key)) { error_msg = "ERROR: 'DestinationSystem' is missing the required 'Name' key"; goto Exit; } hostid = CMGetCharPtr(key.value.string); if(!xen_host_get_by_uuid(session->xen, &host, hostid)) goto Exit; } } else { if(!_GetArgument(broker, argsin, "DestinationHost", CMPI_string, &argdata, status)) { error_msg = "ERROR: 'DestinationHost' parameter is missing"; goto Exit; } else { /* Determing Xen host based on IP address,. Cannot use inet_pton() and so on since DNS may not have been configured properly */ hostid = CMGetCharPtr(argdata.value.string); _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("Trying to migrate to DestinationHost : %s", hostid)); if(!xen_host_get_all(session->xen, &host_set)) goto Exit; int i=0; for (i=0; i<host_set->size; i++) { xen_host_record *host_rec = NULL; if(!xen_host_get_record(session->xen, &host_rec, host_set->contents[i])) goto Exit; /* DestinationHost could be an IP address or the hostname */ if((host_rec->address && (strcmp(hostid, host_rec->address) == 0)) || (host_rec->hostname && (strcmp(hostid, host_rec->hostname) == 0)) || (host_rec->name_label && (strcmp(hostid, host_rec->name_label) == 0))) { xen_host_record_free(host_rec); host = host_set->contents[i]; host_set->contents[i] = NULL; /* dont free this one */ break; } xen_host_record_free(host_rec); } } } /* VM to migrate - required parameter */ if(!_GetArgument(broker, argsin, "ComputerSystem", CMPI_ref, &argdata, status)) { if(!_GetArgument(broker, argsin, "ComputerSystem", CMPI_string, &argdata, status)) { error_msg = "ERROR: Missing the required 'ComputerSystem' parameter"; goto Exit; } else vm_uuid = CMGetCharPtr(argdata.value.string); } else { argdata = CMGetKey(argdata.value.ref, "Name", status); if(status->rc != CMPI_RC_OK || CMIsNullValue(argdata)) { error_msg = "ERROR: ComputerSystem is missing the required 'Name' key"; goto Exit; } vm_uuid = CMGetCharPtr(argdata.value.string); } status->rc = CMPI_RC_ERR_FAILED; rc = Xen_VirtualSystemMigrationService_MigrateVirtualSystemToSystem_Failed; if(xen_vm_get_by_uuid(session->xen, &vm, vm_uuid)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Migrating %s to %s", vm_uuid, hostid)); if(migrate_check_only) { /* Check to see if migration is possible */ statusrc = CMPI_RC_OK; rc = Xen_VirtualSystemMigrationService_MigrateVirtualSystemToSystem_Completed_with_No_Error; bool migratable = xen_vm_assert_can_boot_here(session->xen, vm, host); if(migratable == false || !session->xen->ok) { migratable = false; // Workaround for kvp migration if(session->xen->error_description_count==1) { if(xen_vm_get_other_config(session->xen, &other_config, vm)) { if(xen_utils_get_from_string_string_map(other_config, "kvp_enabled")) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("Overwriting migratable to mark kvp vm as migratable, although its network")); migratable=true; RESET_XEN_ERROR(session->xen); } free(other_config); } else { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Could not get other config.")); } } if(migratable == false && session->xen->error_description) { /* This is not part of the MOF (and is not documented), but nice to have */ char *xen_error = xen_utils_get_xen_error(session->xen); CMAddArg(argsout, "Reason", (CMPIValue *)xen_error, CMPI_chars); free(xen_error); } } CMAddArg(argsout, "IsMigratable", (CMPIValue *)&migratable, CMPI_boolean); } else { /* Do the actual migration, this could take a few minutes */ CMPIObjectPath* job_instance_op = NULL; migrate_job_context *job_context = calloc(1, sizeof(migrate_job_context)); if(!job_context) { error_msg = "ERROR: Couldn't allocate memory for the migrate job."; goto Exit; } job_context->vm = vm; job_context->host = host; if(!job_create(broker, context, session, MIGRATE_VM_TASK_NAME, vm_uuid, migrate_task, job_context, &job_instance_op, status)) { error_msg = "ERROR: Couldn't prepare the Migrate job. Job wasnt started."; goto Exit; } statusrc = CMPI_RC_OK; rc = Xen_VirtualSystemMigrationService_MigrateVirtualSystemToHost_Method_Parameters_Checked___Job_Started; CMAddArg(argsout, "Job", (CMPIValue *)&job_instance_op, CMPI_ref); vm = NULL; /* freed by async thread */ host = NULL; /* freed by async thread */ } } Exit: if(host) xen_host_free(host); if(vm) xen_vm_free(vm); if(host_set) xen_host_set_free(host_set); xen_utils_set_status(broker, status, statusrc, error_msg, session->xen); return rc; }
int main(void) { struct DSQueue *job_queue, *results_queue; pthread_t *producers, *consumers; struct job *prod_jobs, *cons_jobs; int i; int *result, result_sum; if (SEQUENTIAL) { sequential(); exit(0); } /* If there is a bad value from sysconf, just assume 1. */ cpus = (int) sysconf(_SC_NPROCESSORS_ONLN); cpus = cpus == 0 ? 1 : cpus; /* Compute the number of producer/consumer threads to start. */ num_producers = num_producers == 0 ? cpus : num_producers; num_consumers = num_consumers == 0 ? cpus : num_consumers; /* Initialize thread safe queues. `job_queue` has a capacity equivalent * to the buffer size set by the user. `results_queue` always has a capacity * equivalent to the number of consumer threads so that every consumer * can send a value to `results_queue` without blocking. */ job_queue = ds_queue_create(BUFFER); results_queue = ds_queue_create(num_consumers); assert(producers = malloc(num_producers * sizeof(*producers))); assert(consumers = malloc(num_consumers * sizeof(*consumers))); assert(prod_jobs = malloc(num_producers * sizeof(*prod_jobs))); assert(cons_jobs = malloc(num_consumers * sizeof(*cons_jobs))); /* Create `num_producers` jobs and threads. * Similarly for `num_consumers`. */ for (i = 0; i < num_producers; i++) { prod_jobs[i] = job_create(i, job_queue, results_queue); pthread_create(&(producers[i]), NULL, producer, (void*) &(prod_jobs[i])); } for (i = 0; i < num_consumers; i++) { cons_jobs[i] = job_create(i, job_queue, results_queue); pthread_create(&(consumers[i]), NULL, consumer, (void*) &(cons_jobs[i])); } /* Wait for all of the producers to finish producing. */ for (i = 0; i < num_producers; i++) assert(0 == pthread_join(producers[i], NULL)); /* Now that the producers are done, no more values will be sent to * `job_queue`, and therefore, it should be closed. (Values can still * be read from a closed queue.) */ ds_queue_close(job_queue); /* Free the producer jobs. */ for (i = 0; i < num_producers; i++) free(prod_jobs[i].id); free(prod_jobs); /* Now wait for the consumers to finish consuming. */ for (i = 0; i < num_consumers; i++) assert(0 == pthread_join(consumers[i], NULL)); /* Now that the consumers are done, no more values will be sent to * `results_queue`, and therefore, it should be closed. */ ds_queue_close(results_queue); /* Free the consumer jobs. */ for (i = 0; i < num_consumers; i++) free(cons_jobs[i].id); free(cons_jobs); /* Read all values in `results_queue`, and sum them up to get the total * number of consumed items. */ result_sum = 0; while (NULL != (result = (int*) ds_queue_pop(results_queue))) { result_sum += *result; free(result); } /* Print out the total number of produced and consumed items. * In this example, these numbers should always be equal. * N.B. Watch out for integer division! */ printf("Total produced: %d\n", (JOBS / num_producers) * num_producers); printf("Total consumed: %d\n", result_sum); free(consumers); free(producers); ds_queue_free(job_queue); ds_queue_free(results_queue); return 0; }
/*------------------------------------------------------------------------- handle_transform Get data from upstream vconn. Parse it. Include file if include tags found. Copy data to downstream vconn. Wake up upstream to get more data. Input: contp continuation for the current transaction Output : Return Value: 0 if failure 1 if success -------------------------------------------------------------------------*/ static int handle_transform(TSCont contp) { TSVConn output_conn; TSVIO input_vio; ContData *data; TSIOBufferReader input_reader; int toread, avail, psi, toconsume, towrite; /* Get the output (downstream) vconnection where we'll write data to. */ output_conn = TSTransformOutputVConnGet(contp); /* Get upstream vio */ input_vio = TSVConnWriteVIOGet(contp); data = TSContDataGet(contp); TSAssert(data->magic == MAGIC_ALIVE); if (!data->output_buffer) { data->output_buffer = TSIOBufferCreate(); data->output_reader = TSIOBufferReaderAlloc(data->output_buffer); /* INT64_MAX because we don't know yet how much bytes we'll produce */ data->output_vio = TSVConnWrite(output_conn, contp, data->output_reader, INT64_MAX); } /* If the input VIO's buffer is NULL, the transformation is over */ if (!TSVIOBufferGet(input_vio)) { TSDebug(DBG_TAG, "input_vio NULL, terminating transformation"); TSVIONBytesSet(data->output_vio, data->transform_bytes); TSVIOReenable(data->output_vio); return 1; } /* Determine how much data we have left to read. */ toread = TSVIONTodoGet(input_vio); if (toread > 0) { input_reader = TSVIOReaderGet(input_vio); avail = TSIOBufferReaderAvail(input_reader); /* There are some data available for reading. Let's parse it */ if (avail > 0) { /* No need to parse data if there are too few bytes left to contain an include command... */ if (toread > (PSI_START_TAG_LEN + PSI_END_TAG_LEN)) { psi = parse_data(contp, input_reader, avail, &toconsume, &towrite); } else { towrite = avail; toconsume = avail; psi = 0; } if (towrite > 0) { /* Update the total size of the doc so far */ data->transform_bytes += towrite; /* Copy the data from the read buffer to the output buffer. */ /* TODO: Should we check the return value of TSIOBufferCopy() ? */ TSIOBufferCopy(TSVIOBufferGet(data->output_vio), TSVIOReaderGet(input_vio), towrite, 0); /* Reenable the output connection so it can read the data we've produced. */ TSVIOReenable(data->output_vio); } if (toconsume > 0) { /* Consume data we've processed an we are no longer interested in */ TSIOBufferReaderConsume(input_reader, toconsume); /* Modify the input VIO to reflect how much data we've completed. */ TSVIONDoneSet(input_vio, TSVIONDoneGet(input_vio) + toconsume); } /* Did we find a psi filename to execute in the data ? */ if (psi) { Job *new_job; /* Add a request to include a file into the jobs queue.. */ /* We'll be called back once it's done with an EVENT_IMMEDIATE */ TSDebug(DBG_TAG, "Psi filename extracted. Adding an include job to thread queue."); data->state = STATE_READ_PSI; /* Create a new job request and add it to the queue */ new_job = job_create(contp, &psi_include, NULL); add_to_queue(&job_queue, new_job); /* Signal to the threads there is a new job */ thread_signal_job(); return 1; } } } /* Wake up upstream and downstream vconnections */ wake_up_streams(contp); return 1; }
/* * * Not all PAMified apps invoke session management modules. So, we supply * * this account management function for such cases. Whenever possible, it * * is still bet to use the session management version. * */ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) { int retcode = PAM_SUCCESS; struct passwd *passwd = NULL; char *username = NULL; char *service = NULL; jid_t jid; parse_args(argc, argv); /* Get the username of the user associated with this job */ retcode = pam_get_item(pamh, PAM_USER, (void *) &username); if (username == NULL || retcode != PAM_SUCCESS) { syslog(LOG_CRIT, "open_session - error recovering username"); return PAM_AUTH_ERR; } /* Get the uid value for the user associated with this job */ passwd = getpwnam(username); if (!passwd) { syslog(LOG_CRIT, "open_session - error getting passwd entry"); return PAM_AUTH_ERR; } /* Get the service used to create this job */ retcode = pam_get_item(pamh, PAM_SERVICE, (void *) &service); if (service == NULL || retcode != PAM_SUCCESS) { syslog(LOG_CRIT, "open_session - error recovering service"); return PAM_AUTH_ERR; } #if 0 /* this allowed root logins without creating jobs */ if (passwd->pw_uid == 0) { vsyslog(LOG_INFO, "(%s) POE(pid=%d): user(uid=%d)," " skipping job creation for superuser\n", service, getpid(), passwd->pw_uid); disabled = 1; return PAM_SUCCESS; } #endif /* Request creation of new job */ jid = job_create(0, passwd->pw_uid, 0 ); if (jid == (jid_t)-1) { /* Record failure to create job & session will fail */ vsyslog(LOG_INFO, "job_create(...): %s", strerror(errno)); #if 0 return PAM_AUTH_ERR; #else disabled = 1; return PAM_SUCCESS; #endif } /* Record status of creating new job */ if (jid == (jid_t)0) { /* Job creation was disabled */ vsyslog(LOG_INFO, "(%s) POE(pid=%d): job creation disabled\n", service, getpid()); disabled = 1; } else { /* New job successfully created */ vsyslog(LOG_INFO, "(%s) POE(pid=%d): job(jid=%0#18Lx) created for user %s(uid=%d) - using account management, no POE exit message will appear\n", service, getpid(), (unsigned long long)jid, username, passwd->pw_uid); } return PAM_SUCCESS; }
/* Collect a job by scanning a source directory */ static JOB * file_collect(SOURCE *me) { JOB *job; ASSET *asset; DIR *dir; struct dirent *de; const char *srcdir; size_t srclen, sl, bl; int r; srcdir = me->incoming; srclen = me->incominglen; dir = opendir(srcdir); if(!dir) { fprintf(stderr, "%s: %s: %s\n", short_program_name, srcdir, strerror(errno)); return NULL; } asset = NULL; job = NULL; for(;;) { de = readdir(dir); if(!de) { break; } if(de->d_name[0] == '.') { continue; } if(asset) { asset_reset(asset); } else { asset = asset_create(); if(!asset) { return NULL; } } asset_set_path_basedir(asset, srcdir, srclen, de->d_name); r = type_identify_asset(asset); if(r < 0) { fprintf(stderr, "%s: failed to identify asset '%s': %s\n", short_program_name, de->d_name, strerror(errno)); asset_free(asset); closedir(dir); return NULL; } if(r == 0) { continue; } if(asset->sidecar) { continue; } job = job_create(de->d_name, me); if(!job) { asset_free(asset); closedir(dir); return NULL; } job_set_source_asset(job, asset); /* Look for a matching sidecar */ asset = asset_create(); if(!asset) { return NULL; } rewinddir(dir); sl = strlen(job->asset->basename); bl = sl - strlen(job->asset->ext); for(;;) { de = readdir(dir); if(!de) { break; } if(de->d_name[0] == '.') { continue; } if(strlen(de->d_name) > sl && !strncmp(de->d_name, job->asset->basename, sl) && de->d_name[sl] == '.') { asset_reset(asset); /* Candidate filename begins with the asset filename */ asset_set_path_basedir(asset, srcdir, srclen, de->d_name); } else if(strlen(de->d_name) > bl && !strncmp(de->d_name, job->asset->basename, bl) && strcmp(de->d_name, job->asset->basename) && de->d_name[bl] == '.') { asset_reset(asset); /* Candidate filename begins with the asset filename */ asset_set_path_basedir(asset, srcdir, srclen, de->d_name); } else { continue; } r = type_identify_asset(asset); if(r < 0) { fprintf(stderr, "%s: failed to identify asset '%s': %s\n", short_program_name, de->d_name, strerror(errno)); asset_free(asset); closedir(dir); return NULL; } if(r == 0) { continue; } if(asset->sidecar) { job_set_sidecar(job, asset); asset = NULL; break; } } break; } closedir(dir); asset_free(asset); return job; }
void strassen_8thread_mult(matrix a, matrix b, matrix c){ matrix quar[12]; matrix m[7]; struct work_struct *jobs[7]; int size = a.size/2; int i, j; if(size==0){ c.rows[0][0] = a.rows[0][0] * b.rows[0][0]; return; } /* if (a.size <= BREAK) { int i, j, k; for (i = 0; i < (a.size); i++) { for (k = 0; k < (a.size); k++) { for (j = 0; j < (a.size); j++) { c.rows[i][j] += a.rows[i][k] * b.rows[k][j]; } } } return; } */ job_init(); quar[0]=get00(a); quar[1]=get01(a); quar[2]=get10(a); quar[3]=get11(a); quar[4]=get00(b); quar[5]=get01(b); quar[6]=get10(b); quar[7]=get11(b); quar[8]=get00(c); quar[9]=get01(c); quar[10]=get10(c); quar[11]=get11(c); for(i=0;i<7;i++){ m[i] = new_matrix(size); } for (i = 0; i < 7; i++) { jobs[i] = malloc(sizeof(struct work_struct)); if (jobs[i] == NULL) { perror(NULL); exit(1); } } jobs[0]->a_1 = quar[0]; jobs[0]->a_2 = quar[3]; jobs[0]->b_1 = quar[4]; jobs[0]->b_2 = quar[7]; jobs[0]->c = m[0]; jobs[0]->tid = 0; job_create(thread_main, jobs[0], 0); jobs[1]->a_1 = quar[2]; jobs[1]->a_2 = quar[3]; jobs[1]->b_1 = quar[4]; jobs[1]->c = m[1]; jobs[1]->tid = 1; job_create(thread_main, jobs[1], 0); jobs[2]->a_1 = quar[0]; jobs[2]->b_1 = quar[5]; jobs[2]->b_2 = quar[7]; jobs[2]->c = m[2]; jobs[2]->tid = 2; job_create(thread_main, jobs[2], 0); jobs[3]->a_1 = quar[3]; jobs[3]->b_1 = quar[6]; jobs[3]->b_2 = quar[4]; jobs[3]->c = m[3]; jobs[3]->tid = 3; job_create(thread_main, jobs[3], 0); jobs[4]->a_1 = quar[0]; jobs[4]->a_2 = quar[1]; jobs[4]->b_1 = quar[7]; jobs[4]->c = m[4]; jobs[4]->tid = 4; job_create(thread_main, jobs[4], 0); jobs[5]->a_1 = quar[2]; jobs[5]->a_2 = quar[0]; jobs[5]->b_1 = quar[4]; jobs[5]->b_2 = quar[5]; jobs[5]->c = m[5]; jobs[5]->tid = 5; job_create(thread_main, jobs[5], 0); jobs[6]->a_1 = quar[1]; jobs[6]->a_2 = quar[3]; jobs[6]->b_1 = quar[6]; jobs[6]->b_2 = quar[7]; jobs[6]->c = m[6]; jobs[6]->tid = 6; job_create(thread_main, jobs[6], 0); for(i=0;i<7;i++){ job_join(jobs[i]); } for(i=0;i<size;i++){ for(j=0;j<size;j++){ quar[8].rows[i][j] = m[0].rows[i][j] + m[3].rows[i][j] - m[4].rows[i][j] + m[6].rows[i][j]; quar[9].rows[i][j] = m[2].rows[i][j] + m[4].rows[i][j]; quar[10].rows[i][j] = m[1].rows[i][j] + m[3].rows[i][j]; quar[11].rows[i][j] = m[0].rows[i][j] - m[1].rows[i][j] + m[2].rows[i][j] + m[5].rows[i][j]; } } for(i=0;i<12;i++){ delete_matrix(quar[i]); } for(i=0;i<7;i++){ delete_matrix(m[i]); } }