job *find_job_by_array( all_jobs *aj, const char *job_id, int get_subjob, bool locked) { job *pj = NULL; if (aj == NULL) { log_err(PBSE_BAD_PARAMETER, __func__, "null struct all_jobs pointer fail"); return(NULL); } if (job_id == NULL) { log_err(PBSE_BAD_PARAMETER, __func__, "null job_id pointer fail"); return(NULL); } if (locked == false) aj->lock(); pj = aj->find(job_id); if (pj != NULL) lock_ji_mutex(pj, __func__, NULL, LOGLEVEL); if (locked == false) aj->unlock(); if (pj != NULL) { if (get_subjob == TRUE) { if (pj->ji_cray_clone != NULL) { pj = pj->ji_cray_clone; unlock_ji_mutex(pj->ji_parent_job, __func__, NULL, LOGLEVEL); lock_ji_mutex(pj, __func__, NULL, LOGLEVEL); } } if (pj->ji_being_recycled == TRUE) { unlock_ji_mutex(pj, __func__, "1", LOGLEVEL); pj = NULL; } } return(pj); } /* END find_job_by_array() */
job *find_job_by_array( struct all_jobs *aj, char *job_id, int get_subjob) { job *pj = NULL; int i; if (aj == NULL) { log_err(PBSE_BAD_PARAMETER, __func__, "null struct all_jobs pointer fail"); return(NULL); } if (job_id == NULL) { log_err(PBSE_BAD_PARAMETER, __func__, "null job_id pointer fail"); return(NULL); } pthread_mutex_lock(aj->alljobs_mutex); i = get_value_hash(aj->ht, job_id); if (i >= 0) pj = (job *)aj->ra->slots[i].item; if (pj != NULL) lock_ji_mutex(pj, __func__, NULL, LOGLEVEL); pthread_mutex_unlock(aj->alljobs_mutex); if (pj != NULL) { if (get_subjob == TRUE) { if (pj->ji_cray_clone != NULL) { pj = pj->ji_cray_clone; unlock_ji_mutex(pj->ji_parent_job, __func__, NULL, LOGLEVEL); lock_ji_mutex(pj, __func__, NULL, LOGLEVEL); } } if (pj->ji_being_recycled == TRUE) { unlock_ji_mutex(pj, __func__, "1", LOGLEVEL); pj = NULL; } } return(pj); } /* END find_job_by_array() */
job *next_job_from_back( struct all_jobs *aj, int *iter) { job *pjob; pthread_mutex_lock(aj->alljobs_mutex); pjob = (job *)next_thing_from_back(aj->ra,iter); if (pjob != NULL) lock_ji_mutex(pjob, __func__, NULL, LOGLEVEL); pthread_mutex_unlock(aj->alljobs_mutex); if (pjob != NULL) { if (pjob->ji_being_recycled == TRUE) { unlock_ji_mutex(pjob, __func__, "1", LOGLEVEL); pjob = next_job_from_back(aj,iter); } } return(pjob); } /* END next_job_from_back() */
int get_jobs_index( struct all_jobs *aj, job *pjob) { int index; if (pthread_mutex_trylock(aj->alljobs_mutex)) { unlock_ji_mutex(pjob, __func__, "1", LOGLEVEL); pthread_mutex_lock(aj->alljobs_mutex); lock_ji_mutex(pjob, __func__, NULL, LOGLEVEL); if (pjob->ji_being_recycled == TRUE) { pthread_mutex_unlock(aj->alljobs_mutex); unlock_ji_mutex(pjob, __func__, "2", LOGLEVEL); return(-1); } } index = get_value_hash(aj->ht, pjob->ji_qs.ji_jobid); pthread_mutex_unlock(aj->alljobs_mutex); return(index); } /* END get_jobs_index() */
int has_job( struct all_jobs *aj, job *pjob) { int rc; char jobid[PBS_MAXSVRJOBID + 1]; strcpy(jobid, pjob->ji_qs.ji_jobid); if (pthread_mutex_trylock(aj->alljobs_mutex)) { unlock_ji_mutex(pjob, __func__, "1", LOGLEVEL); pthread_mutex_lock(aj->alljobs_mutex); lock_ji_mutex(pjob, __func__, NULL, LOGLEVEL); if (pjob->ji_being_recycled == TRUE) { pthread_mutex_unlock(aj->alljobs_mutex); unlock_ji_mutex(pjob, __func__, "1", LOGLEVEL); return(PBSE_JOB_RECYCLED); } } if (get_value_hash(aj->ht, pjob->ji_qs.ji_jobid) < 0) rc = FALSE; else rc = TRUE; pthread_mutex_unlock(aj->alljobs_mutex); return(rc); } /* END has_job() */
int remove_job( all_jobs *aj, job *pjob, bool force_lock) { int rc = PBSE_NONE; if (pjob == NULL) { rc = PBSE_BAD_PARAMETER; log_err(rc,__func__,"null input job pointer fail"); return(rc); } if (aj == NULL) { rc = PBSE_BAD_PARAMETER; log_err(rc,__func__,"null input array pointer fail"); return(rc); } if (LOGLEVEL >= 10) log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, __func__, pjob->ji_qs.ji_jobid); if (aj->trylock()) { char jobid[PBS_MAXSVRJOBID+1]; if (force_lock == false) snprintf(jobid, sizeof(jobid), "%s", pjob->ji_qs.ji_jobid); unlock_ji_mutex(pjob, __func__, "1", LOGLEVEL); aj->lock(); if (force_lock == true) lock_ji_mutex(pjob, __func__, NULL, LOGLEVEL); else { if ((pjob = find_job_by_array(aj, jobid, TRUE, true)) == NULL) { rc = PBSE_JOBNOTFOUND; } } } if (rc == PBSE_NONE) { if (!aj->remove(pjob->ji_qs.ji_jobid)) rc = THING_NOT_FOUND; } aj->unlock(); return(rc); } /* END remove_job() */
void job::free_job_allocation() { if (this->ji_cray_clone != NULL) { lock_ji_mutex(this->ji_cray_clone, __func__, NULL, LOGLEVEL); delete this->ji_cray_clone; } if (this->ji_external_clone != NULL) { lock_ji_mutex(this->ji_external_clone, __func__, NULL, LOGLEVEL); delete this->ji_external_clone; } /* remove any calloc working pbs_attribute space */ for (int i = 0;i < JOB_ATR_LAST;i++) job_attr_def[i].at_free(&this->ji_wattr[i]); } // END free_job_allocation()
job *find_job_by_array( struct all_jobs *aj, char *job_id, int get_subjob) { job *pj = NULL; int i; pthread_mutex_lock(aj->alljobs_mutex); i = get_value_hash(aj->ht, job_id); if (i >= 0) pj = (job *)aj->ra->slots[i].item; if (pj != NULL) lock_ji_mutex(pj, __func__, (char *)NULL, LOGLEVEL); pthread_mutex_unlock(aj->alljobs_mutex); if (pj != NULL) { if (get_subjob == TRUE) { if (pj->ji_cray_clone != NULL) { pj = pj->ji_cray_clone; unlock_ji_mutex(pj->ji_parent_job, __func__, (char *)NULL, LOGLEVEL); lock_ji_mutex(pj, __func__, (char *)NULL, LOGLEVEL); } } if (pj->ji_being_recycled == TRUE) { unlock_ji_mutex(pj, __func__, (char *)"1", LOGLEVEL); pj = NULL; } } return(pj); } /* END find_job_by_array() */
int remove_job( struct all_jobs *aj, job *pjob) { int rc = PBSE_NONE; int index; if (pjob == NULL) { rc = PBSE_BAD_PARAMETER; log_err(rc,__func__,"null input job pointer fail"); return(rc); } if (aj == NULL) { rc = PBSE_BAD_PARAMETER; log_err(rc,__func__,"null input array pointer fail"); return(rc); } if (LOGLEVEL >= 10) LOG_EVENT(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, __func__, pjob->ji_qs.ji_jobid); if (pthread_mutex_trylock(aj->alljobs_mutex)) { unlock_ji_mutex(pjob, __func__, "1", LOGLEVEL); pthread_mutex_lock(aj->alljobs_mutex); lock_ji_mutex(pjob, __func__, NULL, LOGLEVEL); if (pjob->ji_being_recycled == TRUE) { pthread_mutex_unlock(aj->alljobs_mutex); unlock_ji_mutex(pjob, __func__, "1", LOGLEVEL); return(PBSE_JOB_RECYCLED); } } if ((index = get_value_hash(aj->ht,pjob->ji_qs.ji_jobid)) < 0) rc = THING_NOT_FOUND; else { remove_thing_from_index(aj->ra,index); remove_hash(aj->ht,pjob->ji_qs.ji_jobid); } pthread_mutex_unlock(aj->alljobs_mutex); return(rc); } /* END remove_job() */
int has_job( all_jobs *aj, job *pjob) { int rc = -1; char jobid[PBS_MAXSVRJOBID + 1]; if (aj == NULL) { rc = PBSE_BAD_PARAMETER; log_err(rc,__func__,"null job array input"); return(rc); } if (pjob == NULL) { rc = PBSE_BAD_PARAMETER; log_err(rc,__func__,"null job input"); return(rc); } strcpy(jobid, pjob->ji_qs.ji_jobid); if (aj->trylock()) { unlock_ji_mutex(pjob, __func__, "1", LOGLEVEL); aj->lock(); lock_ji_mutex(pjob, __func__, NULL, LOGLEVEL); if (pjob->ji_being_recycled == TRUE) { aj->unlock(); unlock_ji_mutex(pjob, __func__, "1", LOGLEVEL); return(PBSE_JOB_RECYCLED); } } if (aj->find(pjob->ji_qs.ji_jobid) == NULL) rc = FALSE; else rc = TRUE; aj->unlock(); return(rc); } /* END has_job() */
job *next_job_from_recycler( struct all_jobs *aj, int *iter) { job *pjob; pthread_mutex_lock(aj->alljobs_mutex); pjob = next_thing(aj->ra, iter); pthread_mutex_unlock(aj->alljobs_mutex); if (pjob != NULL) lock_ji_mutex(pjob, __func__, (char *)NULL, LOGLEVEL); return(pjob); } /* END next_job_from_recycler() */
job *next_job_from_recycler( all_jobs *aj, all_jobs_iterator *iter) { job *pjob; aj->lock(); pjob = iter->get_next_item(); aj->unlock(); if (pjob != NULL) lock_ji_mutex(pjob, __func__, NULL, LOGLEVEL); return(pjob); } /* END next_job_from_recycler() */
job *pop_job_from_recycler( all_jobs *aj) { job *pjob; aj->lock(); pjob = aj->pop(); if (pjob != NULL) lock_ji_mutex(pjob, __func__, NULL, LOGLEVEL); aj->unlock(); return(pjob); } /* END pop_job_from_recycler() */
job *next_job_from_recycler( struct all_jobs *aj, int *iter) { job *pjob; lock_alljobs_mutex(aj, __func__, NULL, LOGLEVEL); pjob = next_thing(aj->ra, iter); unlock_alljobs_mutex(aj, __func__, NULL, LOGLEVEL); if (pjob != NULL) lock_ji_mutex(pjob, __func__, NULL, LOGLEVEL); return(pjob); } /* END next_job_from_recycler() */
END_TEST START_TEST(lock_ji_mutex_test) { int rc; job pjob; const char *id; const char *msg; int logging; pjob.ji_mutex = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t)); pthread_mutex_init(pjob.ji_mutex, NULL); id = "lock unit test"; msg = "locking"; logging = 10; rc = lock_ji_mutex(&pjob, id, msg, logging); fail_unless(rc == 0, "did not lock mutex"); }
job::job() : ji_momstat(0), ji_modified(0), ji_momhandle(-1), ji_radix(0), ji_has_delete_nanny(false), ji_qhdr(NULL), ji_lastdest(0), ji_retryok(0), ji_rejectdest(), ji_is_array_template(false), ji_have_nodes_request(false), ji_external_clone(NULL), ji_cray_clone(NULL), ji_parent_job(NULL), ji_internal_id(-1), ji_being_recycled(false), ji_last_reported_time(0), ji_mod_time(0), ji_queue_counted(0), ji_being_deleted(false), ji_commit_done(false) { memset(this->ji_arraystructid, 0, sizeof(ji_arraystructid)); memset(&this->ji_qs, 0, sizeof(this->ji_qs)); this->ji_mutex = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t)); pthread_mutex_init(this->ji_mutex,NULL); lock_ji_mutex(this, __func__, NULL, LOGLEVEL); this->ji_qs.qs_version = PBS_QS_VERSION; /* set the working attributes to "unspecified" */ job_init_wattr(); } // END constructor()
job *job_alloc(void) { job *pj = (job *)calloc(1, sizeof(job)); if (pj == NULL) { return(NULL); } pj->ji_mutex = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t)); pthread_mutex_init(pj->ji_mutex,NULL); lock_ji_mutex(pj, __func__, NULL, LOGLEVEL); pj->ji_qs.qs_version = PBS_QS_VERSION; pj->ji_is_array_template = FALSE; pj->ji_momhandle = -1; return(pj); }
job *next_job_from_back( struct all_jobs *aj, int *iter) { job *pjob; if (aj == NULL) { log_err(PBSE_BAD_PARAMETER, __func__, "null input pointer to all_jobs struct"); return(NULL); } if (iter == NULL) { log_err(PBSE_BAD_PARAMETER, __func__, "null input iterator"); return(NULL); } pthread_mutex_lock(aj->alljobs_mutex); pjob = (job *)next_thing_from_back(aj->ra,iter); if (pjob != NULL) lock_ji_mutex(pjob, __func__, NULL, LOGLEVEL); pthread_mutex_unlock(aj->alljobs_mutex); if (pjob != NULL) { if (pjob->ji_being_recycled == TRUE) { unlock_ji_mutex(pjob, __func__, "1", LOGLEVEL); pjob = next_job_from_back(aj,iter); } } return(pjob); } /* END next_job_from_back() */
job *next_job( all_jobs *aj, all_jobs_iterator *iter) { job *pjob; if (aj == NULL) { log_err(PBSE_BAD_PARAMETER, __func__, "null input pointer to all_jobs struct"); return(NULL); } if (iter == NULL) { log_err(PBSE_BAD_PARAMETER, __func__, "null input iterator"); return(NULL); } aj->lock(); pjob = iter->get_next_item(); aj->unlock(); if (pjob != NULL) { lock_ji_mutex(pjob, __func__, NULL, LOGLEVEL); if (pjob->ji_being_recycled == TRUE) { unlock_ji_mutex(pjob, __func__, "1", LOGLEVEL); pjob = next_job(aj,iter); } } return(pjob); } /* END next_job() */
int get_jobs_index( struct all_jobs *aj, job *pjob) { int index = -1; if (aj == NULL) { log_err(PBSE_BAD_PARAMETER, __func__, "null job array input"); return(PBSE_BAD_PARAMETER); } if (pjob == NULL) { log_err(PBSE_BAD_PARAMETER, __func__, "null job input"); return(PBSE_BAD_PARAMETER); } if (pthread_mutex_trylock(aj->alljobs_mutex)) { unlock_ji_mutex(pjob, __func__, "1", LOGLEVEL); pthread_mutex_lock(aj->alljobs_mutex); lock_ji_mutex(pjob, __func__, NULL, LOGLEVEL); if (pjob->ji_being_recycled == TRUE) { pthread_mutex_unlock(aj->alljobs_mutex); unlock_ji_mutex(pjob, __func__, "2", LOGLEVEL); return(-1); } } index = get_value_hash(aj->ht, pjob->ji_qs.ji_jobid); pthread_mutex_unlock(aj->alljobs_mutex); return(index); } /* END get_jobs_index() */
job *svr_find_job( const char *jobid, /* I */ int get_subjob) /* I */ { char *at; char *comp = NULL; int different = FALSE; char *dash = NULL; char *dot = NULL; char without_dash[PBS_MAXSVRJOBID + 1]; char work_jobid[PBS_MAXSVRJOBID + 1]; char *jid_ptr = NULL; job *pj = NULL; if (NULL == jobid) { log_err(-1,__func__,"jobid is null"); return NULL; } if (LOGLEVEL >= 10) LOG_EVENT(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, __func__, jobid); snprintf(work_jobid, sizeof(work_jobid), "%s", jobid); if ((at = strchr(work_jobid, '@')) != NULL) *at = '\0'; /* strip off @server_name */ /* jobid-0.server indicates the external sub-job of a heterogeneous * job. For this case we want to get jobid.server, find that, and * the get the external sub-job */ if (get_subjob == TRUE) { dot = strchr(work_jobid, '.'); if (((dash = strchr(work_jobid, '-')) != NULL) && (dot != NULL) && (dash < dot)) { *dash = '\0'; snprintf(without_dash, sizeof(without_dash), "%s%s", work_jobid, dash + 2); jid_ptr = without_dash; } else { dash = NULL; jid_ptr = work_jobid; } } else jid_ptr = work_jobid; if ((is_svr_attr_set(SRV_ATR_display_job_server_suffix)) || (is_svr_attr_set(SRV_ATR_job_suffix_alias))) { comp = get_correct_jobname(jid_ptr); different = TRUE; if (comp == NULL) return(NULL); } else { comp = jid_ptr; } if (strstr(jid_ptr,"[]") == NULL) { /* if we're searching for the external we want find_job_by_array to * return the parent, but if we're searching for the cray subjob then * we want find_job_by_array to return the sub job */ pj = find_job_by_array(&alljobs, comp, (dash != NULL) ? FALSE : get_subjob, false); } /* when remotely routing jobs, they are removed from the * regular job list first and the array summary after. * Attempt to find them there if NULL * OR it's an array, try to find the job */ if (pj == NULL) { /* see the comment on the above call to find_job_by_array() */ pj = find_job_by_array(&array_summary, comp, (dash != NULL) ? FALSE : get_subjob, false); } if (at) *at = '@'; /* restore @server_name */ if ((get_subjob == TRUE) && (pj != NULL)) { if (dash != NULL) { *dash = '-'; if (pj->ji_external_clone != NULL) { pj = pj->ji_external_clone; lock_ji_mutex(pj, __func__, NULL, LOGLEVEL); unlock_ji_mutex(pj->ji_parent_job, __func__, NULL, LOGLEVEL); if (pj->ji_being_recycled == TRUE) { unlock_ji_mutex(pj, __func__, NULL, LOGLEVEL); pj = NULL; } } else { unlock_ji_mutex(pj, __func__, NULL, LOGLEVEL); pj = NULL; } } } if (different) free(comp); return(pj); /* may be NULL */ } /* END svr_find_job() */