/* * Check last against our ulog and determine whether it is up to date * (UPDATE_NIL), so far out of date that a full dump is required * (UPDATE_FULL_RESYNC_NEEDED), or okay to update with ulog entries * (UPDATE_OK). */ static update_status_t get_sno_status(kdb_log_context *log_ctx, const kdb_last_t *last) { kdb_hlog_t *ulog = log_ctx->ulog; /* If last matches the ulog's last serial number and time exactly, it are * up to date even if the ulog is empty. */ if (last->last_sno == ulog->kdb_last_sno && time_equal(&last->last_time, &ulog->kdb_last_time)) return UPDATE_NIL; /* If our ulog is empty or does not contain last_sno, a full resync is * required. */ if (ulog->kdb_num == 0 || last->last_sno > ulog->kdb_last_sno || last->last_sno < ulog->kdb_first_sno) return UPDATE_FULL_RESYNC_NEEDED; /* If the timestamp in our ulog entry does not match last, then sno was * reused and a full resync is required. */ if (!check_sno(log_ctx, last->last_sno, &last->last_time)) return UPDATE_FULL_RESYNC_NEEDED; /* last is not fully up to date, but can be updated using our ulog. */ return UPDATE_OK; }
/* Return true if the ulog entry for sno matches sno and timestamp. */ static krb5_boolean check_sno(kdb_log_context *log_ctx, kdb_sno_t sno, const kdbe_time_t *timestamp) { unsigned int indx = (sno - 1) % log_ctx->ulogentries; kdb_ent_header_t *ent = INDEX(log_ctx->ulog, indx); return ent->kdb_entry_sno == sno && time_equal(&ent->kdb_time, timestamp); }
int main() { struct rwlock m; int i; int children[N_THREADS]; char *stacks[N_THREADS]; int start = uptime(); for (i = 0; i < N_THREADS; i++) stacks[i] = malloc(STACK_SIZE); rwlock(&m, OP_INIT); for (i = 0; i < N_THREADS; i++) { children[i] = tfork(child_main, &m, stacks[i] + STACK_SIZE); if (children[i] < 0) handle_error("error on tfork()"); } for (i = 0; i < N_THREADS; i++) { if (twait(children[i]) < 0) handle_error("error on twait()"); } rwlock(&m, OP_DESTROY); printf(stderr, "Program finished in %d tick(s).\n", uptime() - start); if (!time_equal(uptime() - start, ONE_SEC * N_THREADS)) handle_error("Did not finish in a correct time."); for (i = 0; i < N_THREADS; i++) free(stacks[i]); printf(stdout, "hw3-test-writelock succeeded\n"); exit(); }
/* Get the last set of updates seen, (last+1) to n is returned. */ krb5_error_code ulog_get_entries(krb5_context context, const kdb_last_t *last, kdb_incr_result_t *ulog_handle) { XDR xdrs; kdb_ent_header_t *indx_log; kdb_incr_update_t *upd; unsigned int indx, count; uint32_t sno; krb5_error_code retval; kdb_log_context *log_ctx; kdb_hlog_t *ulog = NULL; uint32_t ulogentries; INIT_ULOG(context); ulogentries = log_ctx->ulogentries; retval = ulog_lock(context, KRB5_LOCKMODE_SHARED); if (retval) return retval; /* If another process terminated mid-update, reset the ulog and force full * resyncs. */ if (ulog->kdb_state != KDB_STABLE) reset_header(ulog); /* If we have the same sno and timestamp, return a nil update. If a * different timestamp, the sno was reused and we need a full resync. */ if (last->last_sno == ulog->kdb_last_sno) { ulog_handle->ret = time_equal(&last->last_time, &ulog->kdb_last_time) ? UPDATE_NIL : UPDATE_FULL_RESYNC_NEEDED; goto cleanup; } /* We may have overflowed the update log or shrunk the log, or the client * may have created its ulog. */ if (last->last_sno > ulog->kdb_last_sno || last->last_sno < ulog->kdb_first_sno) { ulog_handle->lastentry.last_sno = ulog->kdb_last_sno; ulog_handle->ret = UPDATE_FULL_RESYNC_NEEDED; goto cleanup; } sno = last->last_sno; indx = (sno - 1) % ulogentries; indx_log = INDEX(ulog, indx); if (!time_equal(&indx_log->kdb_time, &last->last_time)) { /* We have time stamp mismatch or we no longer have the slave's last * sno, so we brute force it. */ ulog_handle->ret = UPDATE_FULL_RESYNC_NEEDED; goto cleanup; } count = ulog->kdb_last_sno - sno; upd = calloc(count, sizeof(kdb_incr_update_t)); if (upd == NULL) { ulog_handle->ret = UPDATE_ERROR; retval = ENOMEM; goto cleanup; } ulog_handle->updates.kdb_ulog_t_val = upd; for (; sno < ulog->kdb_last_sno; sno++) { indx = sno % ulogentries; indx_log = INDEX(ulog, indx); memset(upd, 0, sizeof(kdb_incr_update_t)); xdrmem_create(&xdrs, (char *)indx_log->entry_data, indx_log->kdb_entry_size, XDR_DECODE); if (!xdr_kdb_incr_update_t(&xdrs, upd)) { ulog_handle->ret = UPDATE_ERROR; retval = KRB5_LOG_CONV; goto cleanup; } /* Mark commitment since we didn't want to decode and encode the incr * update record the first time. */ upd->kdb_commit = indx_log->kdb_commit; upd++; } ulog_handle->updates.kdb_ulog_t_len = count; ulog_handle->lastentry.last_sno = ulog->kdb_last_sno; ulog_handle->lastentry.last_time.seconds = ulog->kdb_last_time.seconds; ulog_handle->lastentry.last_time.useconds = ulog->kdb_last_time.useconds; ulog_handle->ret = UPDATE_OK; cleanup: (void)ulog_lock(context, KRB5_LOCKMODE_UNLOCK); return retval; }
/** * Execute the action command "DIVF". This command divides a set of * files into data in memory. * * @param nerr * Error Return Flag * - 0 on Success * - ERROR_OPERATION_ON_SPECTRAL_FILE * - ERROR_OPERATION_ON_UNEVEN_FILE * - ERROR_HEADER_FILE_MISMATCH * * @date 881130: Fixed bug in begin time error checking. * @date 850730: Changes due to new memory manager. * @date 820809: Changed to newest set of parsing and checking functions. * @date 820331: Combined "parse" and "control" modules. * @date 810224: Original version. * */ void xdivf(int *nerr) { int jdx, jbfl, jdfl, n1zdtm[6]; int ndx1, ndx1b, ndx2, ndx2b, nlen, nlenb, npts1; int lnewhdr ; /* let header data come from new file */ float begin1, delta1, delta2, divsor; float *Sacmem1, *Sacmem2; string_list *list; *nerr = 0; list = NULL; while ( lcmore( nerr ) ){ /* -- NEWHDR: take the header from the new file being merged in.*/ if ( lklog ( "NEWHDR" , 7 , &lnewhdr ) ) { cmbom.lnewhdr = lnewhdr ; } /* -- "filelist': define a new binop filelist. */ if( ( list = lcdfl() ) ){ cmbom.ibflc = 0; } else{ cfmt( "ILLEGAL OPTION:",17 ); cresp(); } } if( *nerr != 0 ) goto L_8888; /* CHECKING PHASE: */ /* - Check for null data file list. */ vflist( nerr ); if( *nerr != 0 ) goto L_8888; /* - Check to make sure all files are evenly * spaced time series files. */ vfeven( nerr ); if( *nerr != 0 ) goto L_8888; /* - Check for a null binop file list. */ if(!list || string_list_length(list) <= 0) { *nerr = ERROR_BINOP_FILE_LIST_EMPTY; error(*nerr,""); goto L_8888; } /* - Make sure each file in BFL are of the proper type. */ for( jdfl = 1; jdfl <= cmdfm.ndfl; jdfl++ ){ getfil( jdfl, FALSE, &nlen, &ndx1, &ndx2, nerr ); if( *nerr != 0 ) goto L_8888; npts1 = *npts; delta1 = *delta; copyi( nzdttm, n1zdtm, 6 ); begin1 = *begin; jbfl = min( jdfl, string_list_length(list)); getbfl( list, jbfl, FALSE, &nlen, &ndx1, &ndx2, nerr ); if( *nerr != 0 ) goto L_8888; if((*nerr = vbeven()) != 0) { error(*nerr, "%s", string_list_get(list, jbfl-1)); goto L_8888; } if((*nerr = delta_equal(delta1, *delta, datafiles, list, jdfl, jbfl)) != 0) { goto L_8888; } if((*nerr = npts_equal(npts1, *npts, datafiles, list, jdfl, jbfl)) != 0) { goto L_8888; } if((*nerr = time_equal(n1zdtm, nzdttm, begin1, *begin, datafiles, list, jdfl, jbfl)) != 0) { goto L_8888; } } /* - Release last binop file. */ relbfl( nerr ); if( *nerr != 0 ) goto L_8888; /* EXECUTION PHASE: */ /* - Perform the file division on each file in DFL. */ for( jdfl = 1; jdfl <= cmdfm.ndfl; jdfl++ ){ /* -- Get the next file in DFL, moving header to CMHDR. */ getfil( jdfl, TRUE, &nlen, &ndx1, &ndx2, nerr ); if( *nerr != 0 ) goto L_8888; delta2 = *delta; /* -- Get the next file in the BFL, moving header to CMHDR. */ jbfl = min( jdfl, string_list_length(list)); getbfl( list, jbfl, TRUE, &nlenb, &ndx1b, &ndx2b, nerr ); if( *nerr != 0 ) goto L_8888; *delta = delta2; /* -- Output file is the shorter of two input files. */ npts1 = min( nlen, nlenb ); Nlndta[jdfl] = npts1; /* -- Perform file division on these two files. */ Sacmem1 = cmmem.sacmem[ndx1b]; Sacmem2 = cmmem.sacmem[ndx1]; for( jdx = 0; jdx <= (npts1 - 1); jdx++, Sacmem1++, Sacmem2++ ){ divsor = *Sacmem1; if( fabs( divsor ) <= VSMALL ){ *Sacmem2 = sign( VLARGE, *Sacmem2 * divsor ); } else{ *Sacmem2 = *Sacmem2/divsor; } } /* -- Adjust header of file in DFL. */ if ( !cmbom.lnewhdr ) getfil ( jdfl , FALSE , &nlen , &ndx1 , &ndx2 , nerr ) ; *npts = npts1 ; extrma( cmmem.sacmem[ndx1], 1, *npts, depmin, depmax, depmen ); /* -- Return file in DFL to memory manager. */ putfil( jdfl, nerr ); if( *nerr != 0 ) goto L_8888; } /* - Release last binop file. */ relbfl( nerr ); if( *nerr != 0 ) goto L_8888; /* - Calculate and set new range of dependent variable. */ setrng(); L_8888: return; }