Exemplo n.º 1
0
/*
 * thread_DispatchCommand is the thread proc used to dispatch the command to one or more of the qExecs.
 *
 * NOTE: This function MUST NOT contain elog or ereport statements. (or most any other backend code)
 *		 elog is NOT thread-safe.  Developers should instead use something like:
 *
 *	if (DEBUG3 >= log_min_messages)
 *			write_log("my brilliant log statement here.");
 *
 * NOTE: In threads, we cannot use palloc, because it's not thread safe.
 */
static void *
thread_DispatchCommand(void *arg)
{
	DispatchCommandParms *pParms = (DispatchCommandParms *) arg;

	gp_set_thread_sigmasks();

	/*
	 * Mark that we are runnig a new thread.  The main thread will check
	 * it to see if there is still alive one.  Let's do this after we block
	 * signals so that nobody will intervent and mess up the value.
	 * (should we actually block signals before spawning a thread, as much
	 * like we do in fork??)
	 */
	pg_atomic_add_fetch_u32((pg_atomic_uint32 *) &RunningThreadCount, 1);

	/*
	 * We need to make sure the value will be decremented once the thread
	 * finishes.  Currently there is not such case but potentially we could
	 * have pthread_exit or thread cancellation in the middle of code, in
	 * which case we would miss to decrement value if we tried to do this
	 * without the cleanup callback facility.
	 */
	pthread_cleanup_push(DecrementRunningCount, NULL);
	{
		thread_DispatchOut(pParms);
		/*
		 * thread_DispatchWaitSingle might have a problem with interupts
		 */
		if (pParms->db_count == 1 && false)
			thread_DispatchWaitSingle(pParms);
		else
			thread_DispatchWait(pParms);
	}
	pthread_cleanup_pop(1);

	return (NULL);
}
Exemplo n.º 2
0
void *cgroupService(void *arg)
{
	int res	= FUNC_RETURN_OK;

	gp_set_thread_sigmasks();

	res = CleanUpCGroupAtStartup("cpu");
	if (res != FUNC_RETURN_OK)
	{
		write_log("%s Function CleanUpCGroupAtStartup failed, "
				  "cgroupService thread will quit",
				  ENFORCER_MESSAGE_HEAD);
		return NULL;
	}

	g_ghash_cgroup = createGHash(GHASH_SLOT_VOLUME_DEFAULT,
								 GHASH_SLOT_VOLUME_DEFAULT_MAX,
								 GHASH_KEYTYPE_SIMPSTR,
								 NULL);
	if (g_ghash_cgroup == NULL)
	{
		write_log("%s Function createGHash failed with out of memory, "
				  "cgroupService thread will quit",
				  ENFORCER_MESSAGE_HEAD);
		return NULL;
	}

    while (true)
    {
    	/* Timeout in 1 second (1000 ms) */
    	ResourceEnforcementRequest *task = NULL;
		task = (ResourceEnforcementRequest *)dequeue(g_queue_cgroup, 1*1000);

    	if (!task)
    	{
			CleanUpCGroupAtRuntime();
			continue;
    	}

    	if (task->type == MOVETO)
    	{
    		res = MoveToCGroup(task->pid, task->cgroup_name);

    		if (res != FUNC_RETURN_OK)
    		{
    			write_log("%s Move PID %d to CGroup %s failed with error %d",
    					  ENFORCER_MESSAGE_HEAD,
    					  task->pid,
    					  task->cgroup_name,
    					  res);
    			free(task);
    			break;
    		}
    	}
    	else if (task->type == MOVEOUT)
    	{
    		res = MoveOutCGroup(task->pid, task->cgroup_name);

    		if (res != FUNC_RETURN_OK)
			{
				write_log("%s Move PID %d out from CGroup %s failed with error %d",
						  ENFORCER_MESSAGE_HEAD,
						  task->pid,
						  task->cgroup_name,
						  res);
				free(task);
				break;
			}
    	}
    	else if (task->type == SETWEIGHT)
    	{
    		res = SetupWeightCGroup(task->pid, task->cgroup_name, &(task->query_resource));

    		if (res != FUNC_RETURN_OK)
			{
				write_log("%s Set weight %lf for CGroup %s failed with error %d",
						  ENFORCER_MESSAGE_HEAD,
						  task->query_resource.vcore,
						  task->cgroup_name,
						  res);
				free(task);
				break;
			}
    	}
    	else
    	{
    		write_log("%s WARNING :: invalid CGroup task type",
					  ENFORCER_MESSAGE_HEAD);
    		free(task);
    		break;
    	}

    	free(task);

    	CleanUpCGroupAtRuntime();
    }

	write_log("%s Worker thread will quit", ENFORCER_MESSAGE_HEAD);

	g_enforcement_thread_quited = true;

    return NULL;
}