예제 #1
0
파일: ng_lbr.cpp 프로젝트: 0x4e38/hyperscan
template <class LbrStruct> static
void fillNfa(NFA *nfa, lbr_common *c, ReportID report, const depth &repeatMin,
             const depth &repeatMax, u32 minPeriod, enum RepeatType rtype) {
    assert(nfa);

    RepeatStateInfo rsi(rtype, repeatMin, repeatMax, minPeriod);

    DEBUG_PRINTF("selected %s model for {%s,%s} repeat\n",
                 repeatTypeName(rtype), repeatMin.str().c_str(),
                 repeatMax.str().c_str());

    // Fill the lbr_common structure first. Note that the RepeatInfo structure
    // directly follows the LbrStruct.
    const u32 info_offset = sizeof(LbrStruct);
    c->repeatInfoOffset = info_offset;
    c->report = report;

    RepeatInfo *info = (RepeatInfo *)((char *)c + info_offset);
    info->type = verify_u8(rtype);
    info->repeatMin = depth_to_u32(repeatMin);
    info->repeatMax = depth_to_u32(repeatMax);
    info->stateSize = rsi.stateSize;
    info->packedCtrlSize = rsi.packedCtrlSize;
    info->horizon = rsi.horizon;
    info->minPeriod = minPeriod;
    copy_bytes(&info->packedFieldSizes, rsi.packedFieldSizes);
    info->patchCount = rsi.patchCount;
    info->patchSize = rsi.patchSize;
    info->encodingSize = rsi.encodingSize;
    info->patchesOffset = rsi.patchesOffset;

    // Fill the NFA structure.
    nfa->nPositions = repeatMin;
    nfa->streamStateSize = verify_u32(rsi.packedCtrlSize + rsi.stateSize);
    nfa->scratchStateSize = (u32)sizeof(lbr_state);
    nfa->minWidth = verify_u32(repeatMin);
    nfa->maxWidth = repeatMax.is_finite() ? verify_u32(repeatMax) : 0;

    // Fill the lbr table for sparse lbr model.
    if (rtype == REPEAT_SPARSE_OPTIMAL_P) {
        u64a *table = getTable<LbrStruct>(nfa);
        // Adjust table length according to the optimal patch length.
        size_t len = nfa->length;
        assert((u32)repeatMax >= rsi.patchSize);
        len -= sizeof(u64a) * ((u32)repeatMax - rsi.patchSize);
        nfa->length = verify_u32(len);
        info->length = verify_u32(sizeof(RepeatInfo)
                                  + sizeof(u64a) * (rsi.patchSize + 1));
        copy_bytes(table, rsi.table);
    }
}
예제 #2
0
// The 'self' parameter is for keeping the current Group object alive while this thread is running.
void
Group::finalizeRestart(GroupPtr self, Options options, RestartMethod method,
	SpawnerFactoryPtr spawnerFactory, unsigned int restartsInitiated,
	vector<Callback> postLockActions)
{
	TRACE_POINT();

	Pool::runAllActions(postLockActions);
	postLockActions.clear();

	this_thread::disable_interruption di;
	this_thread::disable_syscall_interruption dsi;

	// Create a new spawner.
	SpawnerPtr newSpawner = spawnerFactory->create(options);
	SpawnerPtr oldSpawner;

	UPDATE_TRACE_POINT();
	PoolPtr pool = getPool();

	Pool::DebugSupportPtr debug = pool->debugSupport;
	if (debug != NULL && debug->restarting) {
		this_thread::restore_interruption ri(di);
		this_thread::restore_syscall_interruption rsi(dsi);
		this_thread::interruption_point();
		debug->debugger->send("About to end restarting");
		debug->messages->recv("Finish restarting");
	}

	ScopedLock l(pool->syncher);
	if (!isAlive()) {
		P_DEBUG("Group " << name << " is shutting down, so aborting restart");
		return;
	}
	if (restartsInitiated != this->restartsInitiated) {
		// Before this restart could be finalized, another restart command was given.
		// The spawner we just created might be out of date now so we abort.
		P_DEBUG("Restart of group " << name << " aborted because a new restart was initiated concurrently");
		if (debug != NULL && debug->restarting) {
			debug->debugger->send("Restarting aborted");
		}
		return;
	}

	// Run some sanity checks.
	pool->fullVerifyInvariants();
	assert(m_restarting);
	UPDATE_TRACE_POINT();
	
	// Atomically swap the new spawner with the old one.
	resetOptions(options);
	oldSpawner = spawner;
	spawner    = newSpawner;

	m_restarting = false;
	if (shouldSpawn()) {
		spawn();
	} else if (isWaitingForCapacity()) {
		P_INFO("Group " << name << " is waiting for capacity to become available. "
			"Trying to shutdown another idle process to free capacity...");
		if (pool->forceFreeCapacity(this, postLockActions) != NULL) {
			spawn();
		} else {
			P_INFO("There are no processes right now that are eligible "
				"for shutdown. Will try again later.");
		}
	}
	verifyInvariants();

	l.unlock();
	oldSpawner.reset();
	Pool::runAllActions(postLockActions);
	P_DEBUG("Restart of group " << name << " done");
	if (debug != NULL && debug->restarting) {
		debug->debugger->send("Restarting done");
	}
}
예제 #3
0
void
Group::spawnThreadRealMain(const SpawnerPtr &spawner, const Options &options, unsigned int restartsInitiated) {
	TRACE_POINT();
	this_thread::disable_interruption di;
	this_thread::disable_syscall_interruption dsi;

	PoolPtr pool = getPool();
	Pool::DebugSupportPtr debug = pool->debugSupport;
	
	bool done = false;
	while (!done) {
		bool shouldFail = false;
		if (debug != NULL && debug->spawning) {
			UPDATE_TRACE_POINT();
			this_thread::restore_interruption ri(di);
			this_thread::restore_syscall_interruption rsi(dsi);
			this_thread::interruption_point();
			string iteration;
			{
				LockGuard g(debug->syncher);
				debug->spawnLoopIteration++;
				iteration = toString(debug->spawnLoopIteration);
			}
			P_DEBUG("Begin spawn loop iteration " << iteration);
			debug->debugger->send("Begin spawn loop iteration " +
				iteration);
			
			vector<string> cases;
			cases.push_back("Proceed with spawn loop iteration " + iteration);
			cases.push_back("Fail spawn loop iteration " + iteration);
			MessagePtr message = debug->messages->recvAny(cases);
			shouldFail = message->name == "Fail spawn loop iteration " + iteration;
		}

		ProcessPtr process;
		ExceptionPtr exception;
		try {
			UPDATE_TRACE_POINT();
			this_thread::restore_interruption ri(di);
			this_thread::restore_syscall_interruption rsi(dsi);
			if (shouldFail) {
				throw SpawnException("Simulated failure");
			} else {
				process = spawner->spawn(options);
				process->setGroup(shared_from_this());
			}
		} catch (const thread_interrupted &) {
			break;
		} catch (const tracable_exception &e) {
			exception = copyException(e);
			// Let other (unexpected) exceptions crash the program so
			// gdb can generate a backtrace.
		}

		UPDATE_TRACE_POINT();
		ScopeGuard guard(boost::bind(Process::forceTriggerShutdownAndCleanup, process));
		boost::unique_lock<boost::mutex> lock(pool->syncher);

		if (!isAlive()) {
			if (process != NULL) {
				P_DEBUG("Group is being shut down so dropping process " <<
					process->inspect() << " which we just spawned and exiting spawn loop");
			} else {
				P_DEBUG("The group is being shut down. A process failed "
					"to be spawned anyway, so ignoring this error and exiting "
					"spawn loop");
			}
			// We stop immediately because any previously assumed invariants
			// may have been violated.
			break;
		} else if (restartsInitiated != this->restartsInitiated) {
			if (process != NULL) {
				P_DEBUG("A restart was issued for the group, so dropping process " <<
					process->inspect() << " which we just spawned and exiting spawn loop");
			} else {
				P_DEBUG("A restart was issued for the group. A process failed "
					"to be spawned anyway, so ignoring this error and exiting "
					"spawn loop");
			}
			// We stop immediately because any previously assumed invariants
			// may have been violated.
			break;
		}

		verifyInvariants();
		assert(m_spawning);
		assert(processesBeingSpawned > 0);

		processesBeingSpawned--;
		assert(processesBeingSpawned == 0);

		UPDATE_TRACE_POINT();
		vector<Callback> actions;
		if (process != NULL) {
			AttachResult result = attach(process, actions);
			if (result == AR_OK) {
				guard.clear();
				if (getWaitlist.empty()) {
					pool->assignSessionsToGetWaiters(actions);
				} else {
					assignSessionsToGetWaiters(actions);
				}
				P_DEBUG("New process count = " << enabledCount <<
					", remaining get waiters = " << getWaitlist.size());
			} else {
				done = true;
				P_DEBUG("Unable to attach spawned process " << process->inspect());
				if (result == AR_ANOTHER_GROUP_IS_WAITING_FOR_CAPACITY) {
					pool->possiblySpawnMoreProcessesForExistingGroups();
				}
			}
		} else {
			// TODO: sure this is the best thing? if there are
			// processes currently alive we should just use them.
			P_ERROR("Could not spawn process for group " << name <<
				": " << exception->what() << "\n" <<
				exception->backtrace());
			if (enabledCount == 0) {
				enableAllDisablingProcesses(actions);
			}
			Pool::assignExceptionToGetWaiters(getWaitlist, exception, actions);
			pool->assignSessionsToGetWaiters(actions);
			done = true;
		}

		done = done
			|| (processLowerLimitsSatisfied() && getWaitlist.empty())
			|| processUpperLimitsReached()
			|| pool->atFullCapacity(false);
		m_spawning = !done;
		if (done) {
			P_DEBUG("Spawn loop done");
		} else {
			processesBeingSpawned++;
			P_DEBUG("Continue spawning");
		}

		UPDATE_TRACE_POINT();
		pool->fullVerifyInvariants();
		lock.unlock();
		UPDATE_TRACE_POINT();
		runAllActions(actions);
		UPDATE_TRACE_POINT();
	}

	if (debug != NULL && debug->spawning) {
		debug->debugger->send("Spawn loop done");
	}
}
예제 #4
0
// The 'self' parameter is for keeping the current Group object alive while this thread is running.
void
Group::spawnThreadOOBWRequest(GroupPtr self, ProcessPtr process) {
	TRACE_POINT();
	this_thread::disable_interruption di;
	this_thread::disable_syscall_interruption dsi;

	Socket *socket;
	Connection connection;
	PoolPtr pool = getPool();
	Pool::DebugSupportPtr debug = pool->debugSupport;

	UPDATE_TRACE_POINT();
	P_DEBUG("Performing OOBW request for process " << process->inspect());
	if (debug != NULL && debug->oobw) {
		debug->debugger->send("OOBW request about to start");
		debug->messages->recv("Proceed with OOBW request");
	}
	
	UPDATE_TRACE_POINT();
	{
		// Standard resource management boilerplate stuff...
		boost::unique_lock<boost::mutex> lock(pool->syncher);
		if (OXT_UNLIKELY(!process->isAlive()
			|| process->enabled == Process::DETACHED
			|| !isAlive()))
		{
			return;
		}

		if (process->enabled != Process::DISABLED) {
			UPDATE_TRACE_POINT();
			P_INFO("Out-of-Band Work canceled: process " << process->inspect() <<
				" was concurrently re-enabled.");
			if (debug != NULL && debug->oobw) {
				debug->debugger->send("OOBW request canceled");
			}
			return;
		}
		
		assert(process->oobwStatus == Process::OOBW_IN_PROGRESS);
		assert(process->sessions == 0);
		socket = process->sessionSockets.top();
		assert(socket != NULL);
	}
	
	UPDATE_TRACE_POINT();
	unsigned long long timeout = 1000 * 1000 * 60; // 1 min
	try {
		this_thread::restore_interruption ri(di);
		this_thread::restore_syscall_interruption rsi(dsi);

		// Grab a connection. The connection is marked as fail in order to
		// ensure it is closed / recycled after this request (otherwise we'd
		// need to completely read the response).
		connection = socket->checkoutConnection();
		connection.fail = true;
		ScopeGuard guard(boost::bind(&Socket::checkinConnection, socket, connection));
		
		// This is copied from RequestHandler when it is sending data using the
		// "session" protocol.
		char sizeField[sizeof(uint32_t)];
		SmallVector<StaticString, 10> data;

		data.push_back(StaticString(sizeField, sizeof(uint32_t)));
		data.push_back(makeStaticStringWithNull("REQUEST_METHOD"));
		data.push_back(makeStaticStringWithNull("OOBW"));

		data.push_back(makeStaticStringWithNull("PASSENGER_CONNECT_PASSWORD"));
		data.push_back(makeStaticStringWithNull(process->connectPassword));

		uint32_t dataSize = 0;
		for (unsigned int i = 1; i < data.size(); i++) {
			dataSize += (uint32_t) data[i].size();
		}
		Uint32Message::generate(sizeField, dataSize);

		gatheredWrite(connection.fd, &data[0], data.size(), &timeout);

		// We do not care what the actual response is ... just wait for it.
		UPDATE_TRACE_POINT();
		waitUntilReadable(connection.fd, &timeout);
	} catch (const SystemException &e) {
		P_ERROR("*** ERROR: " << e.what() << "\n" << e.backtrace());
	} catch (const TimeoutException &e) {
		P_ERROR("*** ERROR: " << e.what() << "\n" << e.backtrace());
	}
	
	UPDATE_TRACE_POINT();
	vector<Callback> actions;
	{
		// Standard resource management boilerplate stuff...
		PoolPtr pool = getPool();
		boost::unique_lock<boost::mutex> lock(pool->syncher);
		if (OXT_UNLIKELY(!process->isAlive() || !isAlive())) {
			return;
		}
		
		process->oobwStatus = Process::OOBW_NOT_ACTIVE;
		if (process->enabled == Process::DISABLED) {
			enable(process, actions);
			assignSessionsToGetWaiters(actions);
		}

		pool->fullVerifyInvariants();

		initiateNextOobwRequest();
	}
	UPDATE_TRACE_POINT();
	runAllActions(actions);
	actions.clear();

	UPDATE_TRACE_POINT();
	P_DEBUG("Finished OOBW request for process " << process->inspect());
	if (debug != NULL && debug->oobw) {
		debug->debugger->send("OOBW request finished");
	}
}
예제 #5
0
	void
	threadMain() {
		while (!boost::this_thread::interruption_requested()) {
			syscalls::sleep(60 * 60);

			begin_touch:

			boost::this_thread::disable_interruption di;
			boost::this_thread::disable_syscall_interruption dsi;
			// Fork a process which touches everything in the server instance dir.
			pid_t pid = syscalls::fork();
			if (pid == 0) {
				// Child
				int prio, ret, e;

				closeAllFileDescriptors(2);

				// Make process nicer.
				do {
					prio = getpriority(PRIO_PROCESS, getpid());
				} while (prio == -1 && errno == EINTR);
				if (prio != -1) {
					prio++;
					if (prio > 20) {
						prio = 20;
					}
					do {
						ret = setpriority(PRIO_PROCESS, getpid(), prio);
					} while (ret == -1 && errno == EINTR);
				} else {
					perror("getpriority");
				}

				do {
					ret = chdir(wo->instanceDir->getPath().c_str());
				} while (ret == -1 && errno == EINTR);
				if (ret == -1) {
					e = errno;
					fprintf(stderr, "chdir(\"%s\") failed: %s (%d)\n",
						wo->instanceDir->getPath().c_str(),
						strerror(e), e);
					fflush(stderr);
					_exit(1);
				}
				restoreOomScore(agentsOptions);

				execlp("/bin/sh", "/bin/sh", "-c", "find . | xargs touch", (char *) 0);
				e = errno;
				fprintf(stderr, "Cannot execute 'find . | xargs touch': %s (%d)\n",
					strerror(e), e);
				fflush(stderr);
				_exit(1);
			} else if (pid == -1) {
				// Error
				P_WARN("Could not touch the server instance directory because "
					"fork() failed. Retrying in 2 minutes...");
				boost::this_thread::restore_interruption si(di);
				boost::this_thread::restore_syscall_interruption rsi(dsi);
				syscalls::sleep(60 * 2);
				goto begin_touch;
			} else {
				syscalls::waitpid(pid, NULL, 0);
			}
		}
	}
예제 #6
0
    /**
     * Starts the agent process. May throw arbitrary exceptions.
     */
    virtual pid_t start() {
        this_thread::disable_interruption di;
        this_thread::disable_syscall_interruption dsi;
        string exeFilename = getExeFilename();
        SocketPair fds;
        int e, ret;
        pid_t pid;

        /* Create feedback fd for this agent process. We'll send some startup
         * arguments to this agent process through this fd, and we'll receive
         * startup information through it as well.
         */
        fds = createUnixSocketPair();

        pid = syscalls::fork();
        if (pid == 0) {
            // Child

            /* Make sure file descriptor FEEDBACK_FD refers to the newly created
             * feedback fd (fds[1]) and close all other file descriptors.
             * In this child process we don't care about the original FEEDBACK_FD
             * (which is the Watchdog's communication channel to the agents starter.)
             *
             * fds[1] is guaranteed to be != FEEDBACK_FD because the watchdog
             * is started with FEEDBACK_FD already assigned.
             */
            syscalls::close(fds[0]);

            if (syscalls::dup2(fds[1], FEEDBACK_FD) == -1) {
                /* Something went wrong, report error through feedback fd. */
                e = errno;
                try {
                    writeArrayMessage(fds[1],
                                      "system error before exec",
                                      "dup2() failed",
                                      toString(e).c_str(),
                                      NULL);
                    _exit(1);
                } catch (...) {
                    fprintf(stderr, "Passenger Watchdog: dup2() failed: %s (%d)\n",
                            strerror(e), e);
                    fflush(stderr);
                    _exit(1);
                }
            }

            closeAllFileDescriptors(FEEDBACK_FD);

            /* Become the process group leader so that the watchdog can kill the
             * agent as well as all its descendant processes. */
            setpgid(getpid(), getpid());

            setOomScore(oldOomScore);

            try {
                execProgram();
            } catch (...) {
                fprintf(stderr, "PassengerWatchdog: execProgram() threw an exception\n");
                fflush(stderr);
                _exit(1);
            }
            e = errno;
            try {
                writeArrayMessage(FEEDBACK_FD,
                                  "exec error",
                                  toString(e).c_str(),
                                  NULL);
            } catch (...) {
                fprintf(stderr, "Passenger Watchdog: could not execute %s: %s (%d)\n",
                        exeFilename.c_str(), strerror(e), e);
                fflush(stderr);
            }
            _exit(1);
        } else if (pid == -1) {
            // Error
            e = errno;
            throw SystemException("Cannot fork a new process", e);
        } else {
            // Parent
            FileDescriptor feedbackFd = fds[0];
            vector<string> args;

            fds[1].close();
            this_thread::restore_interruption ri(di);
            this_thread::restore_syscall_interruption rsi(dsi);
            ScopeGuard failGuard(boost::bind(killAndWait, pid));

            /* Send startup arguments. Ignore EPIPE and ECONNRESET here
             * because the child process might have sent an feedback message
             * without reading startup arguments.
             */
            try {
                sendStartupArguments(pid, feedbackFd);
            } catch (const SystemException &ex) {
                if (ex.code() != EPIPE && ex.code() != ECONNRESET) {
                    throw SystemException(string("Unable to start the ") + name() +
                                          ": an error occurred while sending startup arguments",
                                          ex.code());
                }
            }

            // Now read its feedback.
            try {
                ret = readArrayMessage(feedbackFd, args);
            } catch (const SystemException &e) {
                if (e.code() == ECONNRESET) {
                    ret = false;
                } else {
                    throw SystemException(string("Unable to start the ") + name() +
                                          ": unable to read its startup information",
                                          e.code());
                }
            }
            if (!ret) {
                this_thread::disable_interruption di2;
                this_thread::disable_syscall_interruption dsi2;
                int status;

                /* The feedback fd was prematurely closed for an unknown reason.
                 * Did the agent process crash?
                 *
                 * We use timedWaitPid() here because if the process crashed
                 * because of an uncaught exception, the file descriptor
                 * might be closed before the process has printed an error
                 * message, so we give it some time to print the error
                 * before we kill it.
                 */
                ret = timedWaitPid(pid, &status, 5000);
                if (ret == 0) {
                    /* Doesn't look like it; it seems it's still running.
                     * We can't do anything without proper feedback so kill
                     * the agent process and throw an exception.
                     */
                    failGuard.runNow();
                    throw RuntimeException(string("Unable to start the ") + name() +
                                           ": it froze and reported an unknown error during its startup");
                } else if (ret != -1 && WIFSIGNALED(status)) {
                    /* Looks like a crash which caused a signal. */
                    throw RuntimeException(string("Unable to start the ") + name() +
                                           ": it seems to have been killed with signal " +
                                           getSignalName(WTERMSIG(status)) + " during startup");
                } else if (ret == -1) {
                    /* Looks like it exited after detecting an error. */
                    throw RuntimeException(string("Unable to start the ") + name() +
                                           ": it seems to have crashed during startup for an unknown reason");
                } else {
                    /* Looks like it exited after detecting an error, but has an exit code. */
                    throw RuntimeException(string("Unable to start the ") + name() +
                                           ": it seems to have crashed during startup for an unknown reason, "
                                           "with exit code " + toString(WEXITSTATUS(status)));
                }
            }

            if (args[0] == "system error before exec") {
                throw SystemException(string("Unable to start the ") + name() +
                                      ": " + args[1], atoi(args[2]));
            } else if (args[0] == "exec error") {
                e = atoi(args[1]);
                if (e == ENOENT) {
                    throw RuntimeException(string("Unable to start the ") + name() +
                                           " because its executable (" + getExeFilename() + ") "
                                           "doesn't exist. This probably means that your "
                                           "Phusion Passenger installation is broken or "
                                           "incomplete. Please reinstall Phusion Passenger");
                } else {
                    throw SystemException(string("Unable to start the ") + name() +
                                          " because exec(\"" + getExeFilename() + "\") failed",
                                          atoi(args[1]));
                }
            } else if (!processStartupInfo(pid, feedbackFd, args)) {
                throw RuntimeException(string("The ") + name() +
                                       " sent an unknown startup info message '" +
                                       args[0] + "'");
            }

            lock_guard<boost::mutex> l(lock);
            this->feedbackFd = feedbackFd;
            this->pid = pid;
            failGuard.clear();
            return pid;
        }
    }
예제 #7
0
ErrorCode WriteDamsel::write_file(const char *file_name, 
                                  const bool /* overwrite */,
                                  const FileOptions& opts,
                                  const EntityHandle *meshset_list,
                                  const int num_sets,
                                  const std::vector<std::string>& /* qa_records */,
                                  const Tag* /* tag_list */,
                                  int /* num_tags */,
                                  int /* requested_output_dimension */)
{
    // gather all entities into one big range
  Range all_ents;
  ErrorCode rval;
  damsel_err_t err;

  dU.dmslLib = DMSLlib_init();

    // create a damsel model
  dU.dmslModel = DMSLmodel_create(sizeof(EntityHandle) == 8 ? DAMSEL_HANDLE_TYPE_HANDLE64 : 
                               DAMSEL_HANDLE_TYPE_HANDLE32);
  
    // attach to a file, since we need it for creating containers
  MPI_Comm comm = MPI_COMM_WORLD;
  unlink(file_name);
  err = DMSLmodel_attach(dU.dmslModel, file_name, comm, NULL);
  CHK_DMSL_ERR(err, "DMSLmodel_attach failed.");
  
  rval = mWriteIface->gather_entities(all_ents, meshset_list, num_sets);
  CHK_MB_ERR(rval, "Gather entities failed in WriteDamsel.");

  if (all_ents.empty()) return MB_SUCCESS;

    // create damsel tags for MOAB dense, sparse, and conventional tags
  rval = init_tag_info();
  CHK_MB_ERR(rval, NULL);

    // iterate through the groups of contiguous sequences of handles
  RangeSeqIntersectIter rsi(sequenceManager);
  rval = rsi.init(all_ents.begin(), all_ents.end());
  
  while (rval == MB_SUCCESS) {
      // write subrange of things to damsel: map handles, map entity definition data (connectivity/coords/set contents),
      // map dense tags
    rval = write_subrange(rsi);
    CHK_MB_ERR(rval, "Failed to write subrange.");
    
    rval = rsi.step();
    while (MB_ENTITY_NOT_FOUND == rval)
      rval = rsi.step();
  }

    // write sparse tags
  rval = map_sparse_tags();
  CHK_MB_ERR(rval, "Failed to write sparse tags.");

    //damsel_request_t request;
    //err = DMSLmodel_transfer_async(dU.dmslModel, DAMSEL_TRANSFER_TYPE_WRITE, &request);
  err = DMSLmodel_transfer_sync(dU.dmslModel, DAMSEL_TRANSFER_TYPE_WRITE);
  CHK_DMSL_ERR(err, "DMSLmodel_transfer_asynch failed.");
  
    //damsel_status_t status;
    //err = DMSLmodel_wait(request, &status);
  CHK_DMSL_ERR(err, "DMSLmodel_wait failed.");

  DMSLmodel_close(dU.dmslModel);

  DMSLlib_finalize(dU.dmslLib);
  
    // we should be done
  return MB_SUCCESS;
}
예제 #8
0
/** \brief Returns the stream state size in bytes for a given bounded
 * repeat. */
static
u32 streamStateSize(enum RepeatType type, const depth &repeatMin,
                    const depth &repeatMax, u32 minPeriod) {
    RepeatStateInfo rsi(type, repeatMin, repeatMax, minPeriod);
    return rsi.stateSize;
}
예제 #9
0
/** \brief Returns the packed control block size in bytes for a given bounded
 * repeat. */
static
u32 packedSize(enum RepeatType type, const depth &repeatMin,
               const depth &repeatMax, u32 minPeriod) {
    RepeatStateInfo rsi(type, repeatMin, repeatMax, minPeriod);
    return rsi.packedCtrlSize;
}