//////////////////////////////////////////////////////////////////////////////
// Function :     The Publication part of the APPLICATION_DEMO Task
// Description :  Simulates Publishing , ReadCommand & CommandResponse
//////////////////////////////////////////////////////////////////////////////
void APP_publicationProc( uint8_t p_ucCrtEvent )
{
    int nLen;

#if defined(METER_BOARD)
    if( p_ucCrtEvent & PUBLISH_REQ_EVENT )
    {
        LockSemaphore(&g_stMeterControlLock);
        if (g_stMeterTableToRead.data_length == 0)
        {
            if (meter_last_connect_error_code)
                nLen = sprintf(g_stRspPacket.m_aBuff,"<value at =\'%d\'>C%04X</value>",(int) os_adapt_time(), meter_last_connect_error_code);         // connect error code
            else if (meter_last_periodic_read_error_code)
                nLen = sprintf(g_stRspPacket.m_aBuff,"<value at =\'%d\'>R%04X</value>",(int) os_adapt_time(), meter_last_periodic_read_error_code);   // read error code
            else if (meter_last_disconnect_error_code)
                nLen = sprintf(g_stRspPacket.m_aBuff,"<value at =\'%d\'>D%04X</value>",(int) os_adapt_time(), meter_last_disconnect_error_code);      // disconnect error code                        
            else
                nLen = sprintf(g_stRspPacket.m_aBuff,"<value at =\'%d\'> </value>",(int) os_adapt_time());                                            // nothing
        }
        else
        {
            nLen = sprintf(g_stRspPacket.m_aBuff,"<value at =\'%d\'>", (int) os_adapt_time() );
            for (int i = 0; (i < g_stMeterTableToRead.data_length) && (nLen < (sizeof(g_stRspPacket.m_aBuff) - 16)); i++)
            {
                nLen += sprintf(g_stRspPacket.m_aBuff + nLen, "%02X", g_stMeterTableToRead.table_data[i]);  // hex
            }
            nLen += sprintf(g_stRspPacket.m_aBuff+nLen,"</value>" ); 

            g_stMeterTableToRead.data_length = 0;   
        }
        UnlockSemaphore(&g_stMeterControlLock);

        C_NLOG_INFO(g_stRspPacket.m_aBuff);
        APP_udp_send_to( g_hPubSocket, (const unsigned char*)g_stRspPacket.m_aBuff, nLen,g_stPeristsApp.m_unPublishDstIp6Addr, g_stPeristsApp.m_unPublishDstPort );
    }
#endif   
    if ( (uint32_t)(os_adapt_time() - g_ulLastTime) > (uint32_t)g_nPubTimeAlloc )
    {
        g_TestPub++;          
        // BUILD PACKET

#if defined(MOTION_DETECTION_BOARD)
        nLen = sprintf(g_stRspPacket.m_aBuff,"<value at =\'%d\'>%d</value>",(int) os_adapt_time(), g_ulValue );
        C_NLOG_INFO(g_stRspPacket.m_aBuff);
        APP_udp_send_to( g_hPubSocket, (const unsigned char*)g_stRspPacket.m_aBuff, nLen,g_stPeristsApp.m_unPublishDstIp6Addr, g_stPeristsApp.m_unPublishDstPort );


#elif defined(METER_BOARD)
        APP_readDemandValue();  // will signal meter task to start readings                    
#else                    
        uint32_t nPublishValue = APP_readDemandValue();                    
        nLen = sprintf( g_stRspPacket.m_aBuff, "<value at =\'%d\'>%d</value>", (int) os_adapt_time(), nPublishValue );

        C_NLOG( "APP_node: %s", g_stRspPacket.m_aBuff );
        APP_udp_send_to( g_hPubSocket, (const unsigned char*)g_stRspPacket.m_aBuff, nLen, (const TIpv6Addr*)g_stPeristsApp.m_unPublishDstIp6Addr, g_stPeristsApp.m_unPublishDstPort );
#endif          

        g_ulLastTime = os_adapt_time();
    }
}
	// Working flow of evolution
	void GaMultithreadingAlgorithm::WorkFlow()
	{
		// give ID to worker thread
		int workerId = ATOMIC_INC( _workerIdCounter ) - 1;

		while( 1 )
		{
			// wait for command from control thread
			LockSemaphore( _workerForkSync );

			// stop the thread to apply parameter change
			if( _parametersChange )
				break;

			// execute work step if the algorithm is not stopped
			if( _state == GAS_RUNNING )
				WorkStep( workerId );

			// only the last worker will releast the others to continue
			if( !ATOMIC_DEC( _workersThreadIn ) )
				UnlockSemaphore( _workerJoinSync,  _numberOfThreads - 1 );

			// wait for the last worker to reach this point before notifying control thread
			LockSemaphore( _workerJoinSync );

			// the last worker thread to exit notifies control thread that work step is done
			if( !ATOMIC_DEC( _workersThreadOut ) )
				SignalEvent( _controlSync );

			// algorithm is stopped
			if( _state != GAS_RUNNING )
				break;
		}
	}
Example #3
0
//========================================================================
int main()
{
   pid_t pid;
   int semid;
   semid = CreateSemaphore(1);
  SetSemaphoreValue(semid, 0, 1);

   pid = fork();
   if(pid==0)   //child 1
   {
      sleep(1);
      int res;
      res = LockSemaphore(semid, 0);
/* Try LockSemaphore的用法
  res = EAGAIN;
  while(res== EAGAIN)
{
    res= TryLockSemaphore(semid, 0, 1000);   //设置1000ms超时
  //do something
}
*/
      printf("child 1 set[%d]....\n",res);
      // do critical things
      sleep(10);
      UnlockSemaphore(semid, 0);
      printf("child 1 post[%d]....\n",res);
      return 0;
   }

  int dd;
  dd = LockSemaphore (semid, 0);
   printf("parent set 1[%d]....\n",dd);
   sleep(10);
   dd = UnlockSemaphore(semid, 0);
   //sleep(2);
   printf("parent end: ...[%d]\n",dd);
   //FreeSemaphore(semid);
   UnlockSemaphore(semid, 0);
}
	// Control flow of evolution
	void GaMultithreadingAlgorithm::ControlFlow()
	{
		while( 1 )
		{
			// now parameters and state cannot be changed
			BlockParameterChanges();
			BlockStateChange();

			int count = ( (const GaMultithreadingAlgorithmParams&) GetAlgorithmParameters() ).GetNumberOfWorkers();

			if( _state == GAS_RUNNING )
				// execute control step before workers
					BeforeWorkers();

			// release working threads
			_workersThreadOut = _workersThreadIn = count;
			UnlockSemaphore( _workerForkSync, count );

			// wait for working threads to finish the job
			WaitForEvent( _controlSync );

			// still running?
			if( _state != GAS_RUNNING )
			{
				// stop the threads

				// now it safe to change parameters and state
				ReleaseParameterChanages();
				ReleaseStateChange();

				break;
			}

			// execute control step after workers
			AfterWorkers();

			// stop algorithm is criteria is reached
			CheckStopCriteria();

			// now it safe to change parameters and state
			ReleaseStateChange();
			ReleaseParameterChanages();
		}
	}
Example #5
0
int main(int argc, char *argv[]) {

	int* queuePtr;

	int producersDone = 0, consumersDone = 0;
	int i = 0, j = 0;
	int status;
	int itemsConsumed = 0;
	int* itemsConsumedPtr;

	short sems[3];
	int semid;

	key_t key = 4590;

	int fullSem = 0, emptySem = 0, accessSem = 0;

	struct sembuf arg;

	//assume first argument is the application name
	if (argc < 4) {
		printf("Error: Invalid input");
		exit(0);
	}

	//Gets CLI Values.  Tanks if values not provided.
	for (i = 1; i < argc; i++) {
		//printf("CLI Value:%s\n", argv[i]);

		SetCLIValues(argv[i], i);
	}

	//indicates the total number of items to be created.

	totalItems = producerCount * itemCount;

	printf("Using %d producers to produce %d items\n", producerCount,
			totalItems);

	//gets the requisite set of allocated memory for producers and consumers
	//to pump data into/out of.
	if ((sharedMemId = shmget(IPC_PRIVATE, (queueSize + 2) * sizeof(int), 0660))
			== -1) {
		//implement fallout for shmget failure
	}
	printf("allocating %d ints at shared memory id %d\n", queueSize,
			sharedMemId);

	//gets a pointer to the allocated memory
	if ((sharedMemPtr = (int *) shmat(sharedMemId, (void *) 0, 0))
			== (void *) -1) {
		//implement fallout for shmgat failure
	}

	//sets the queue to point to the shared memory
	queuePtr = sharedMemPtr;

	//initialize queue to -1;
	for (i = 0; i < queueSize; i++) {
		queuePtr[i] = -1;
	}

	//total items consumed
	queuePtr[queueSize] = 0;
	//total items produced
	queuePtr[queueSize + 1] = 0;

	sems[QUEUE_FULL] = 0;
	sems[QUEUE_EMPTY] = 1;
	sems[QUEUE_ACCESS] = 2;

	//Allocate Semaphore.  Gets Semaphore ID
	if ((semid = semget(key, 3, 0600 | IPC_CREAT)) == -1) {
		printf("error getting semaphore\n");
		exit(1);
	} else {
		printf("Allocated 3 Semaphores at semaphore ID:%d\n", semid);
	}

	semctl(semid, 0, SETALL, sems);

	fullSem = sems[QUEUE_FULL];
	emptySem = sems[QUEUE_EMPTY];
	accessSem = sems[QUEUE_ACCESS];

	UnlockSemaphore(semid, emptySem);
	UnlockSemaphore(semid, fullSem);
	UnlockSemaphore(semid, accessSem);

	LockSemaphore(semid, emptySem);
	//generates an array of consumers and producers.
	pid_t prodIds[producerCount];
	pid_t consIds[consumerCount];

	//for producer processes

	for (i = 0; i < producerCount; i++) {
		switch (prodIds[i] = fork()) {
		case -1:

			printf("Error forking producer\n");
			break;
		case 0:

			//printf("producer created with id=%d, pid=%d\n", prodIds[i],
//					getpid());
//			printf("Queue Full Semaphore: %d\n",					semctl(semid, fullSem, GETVAL, arg.sem_num));
			for (i = 0; i < itemCount; i++) {
				int hasAddedToQueue = 0;

				while (hasAddedToQueue == 0) {
					//if queue isn't full, addd something to queue;

					//put something into the queue
					//loop through queue to find an empty spot
					//as indicated by the value = -1

					//check to see if the queue is available
					if (semctl(semid, fullSem, GETVAL, arg.sem_num) > 0) {

						while (semctl(semid, accessSem, GETVAL, arg.sem_num)
								<= 0) {
							usleep(waitTime);
						}

						//lock semaphore
						LockSemaphore(semid, accessSem);
						//if it is, do the do.
						for (j = 0; j < queueSize; j++) {
							if (queuePtr[j] == -1) {
								if (queuePtr[queueSize + 1] >= totalItems) {
//									printf("Completed Producing %d items",
//											totalItems);
//									printf("exiting producer");
									exit(0);
								}

								//do your stuff
								queuePtr[j] = itemsProduced;
								queuePtr[queueSize + 1]++;


								printf(
										"%d\t%d\t%d\t%d\t%d\t%d\t%s\t%d\t%d\t\n",
										getpid(),
										0,
										1,
										semctl(semid, emptySem, GETVAL, arg.sem_num),
										semctl(semid, fullSem, GETVAL, arg.sem_num),
										semctl(semid, accessSem, GETVAL, arg.sem_num),
										"Produce", queuePtr[queueSize+1], queuePtr[queueSize]);
								//unlock it

								itemsProduced++;
								hasAddedToQueue = 1;
								fullCount++;
								emptyCount--;
								j = queueSize;
							}

							if (semctl(semid, emptySem, GETVAL, arg.sem_num)
									<= 0) {
								UnlockSemaphore(semid, emptySem);
							}
						}
						UnlockSemaphore(semid, accessSem);
						//if the queue is full, lock the queue
						if (fullCount == queueSize || hasAddedToQueue == 0) {
							hasAddedToQueue = 1;
							//LockSemaphore(semid, fullSem);
						}
					} else {

						usleep(waitTime);
					}
				}
			}

			//printf("Exiting Producer Process %d\n", getpid());
			exit(EXIT_SUCCESS);
			break;

		case 1:
			printf("producer parent process ID %d\n", getpid());

			//waits around for child processes to get done.
			if ((prodIds[i] = wait(&status)) == -1) {
				perror("error waiting for children to complete.\n");

			} else {
				printf("Child process ended normally.n");
				producersDone = 1;
			}

			break;
		}
	}

	for (i = 0; i < consumerCount; i++) {
		switch (consIds[i] = fork()) {
		case -1:

			printf("Error forking consumer\n");
			break;
		case 0:

			printf("consumer created with id=%d, pid=%d, parent pid=%d\n",
					consIds[i], getpid(), getppid());

			printf("Queue Empty: %d\n",
					semctl(semid, emptySem, GETVAL, arg.sem_num));
			//consume until total number of items have been consumed
			while (queuePtr[queueSize] < totalItems) {

				//if queue is empty, wait around until something comes into it.
				if (semctl(semid, emptySem, GETVAL, arg.sem_num) > 0) {
					//consume item.
					int foundValue = 0;

					while (semctl(semid, accessSem, GETVAL, arg.sem_num) <= 0) {
						usleep(waitTime);
					}
					LockSemaphore(semid, accessSem);

					for (j = 0; j < queueSize; j++) {
						if (queuePtr[j] != -1) {
							//print out consumer

							queuePtr[queueSize]++;


							printf(
									"%d\t%d\t%d\t%d\t%d\t%d\t%s\t%d\t%d\t\n",
									getpid(),
									0,
									1,
									semctl(semid, emptySem, GETVAL, arg.sem_num),
									semctl(semid, fullSem, GETVAL, arg.sem_num),
									semctl(semid, accessSem, GETVAL, arg.sem_num),
									"Consume", queuePtr[queueSize+1], queuePtr[queueSize]);
							queuePtr[j] = -1;
							//increments total items consumed
							emptyCount++;
							foundValue = 1;

							if (semctl(semid, fullSem, GETVAL, arg.sem_num)
									<= 0) {
								UnlockSemaphore(semid, fullSem);
							}

							if (queuePtr[queueSize] >= totalItems) {
								if (queuePtr[queueSize] == totalItems) {
									printf(
											"All consumption has been completed.\n");
								}
								//printf("Exiting Consumer Thread %d", getpid());
								exit(0);
								//all consumption is done.
							}

							j = queueSize;
						}
					}
					UnlockSemaphore(semid, accessSem);

					if (fullCount <= 0 || foundValue == 0) {
						//LockSemaphore(semid, emptySem);

					}
				} else {
					usleep(waitTime);
				}
			}

			printf("Exiting Consumer Process %d\n", getpid());
			break;

		case 1:

			printf("consumer parent process ID %d\n", getpid());

			//waits around for child processes to get done.
			if (waitpid(prodIds[i], &status, WUNTRACED) == -1) {
				perror("error waiting for children to complete.\n");
			} else if (WIFEXITED(status) != 0) {
				printf("Child process ended normally; status = %d.n",
						WEXITSTATUS(status));
				consumersDone = 1;
			}

			break;
		}
	}
//printf("Allocated %d semaphores with id: %d\n", queueSize, semid);

//	printf("press any key to deallocate semaphore\n" );
//	getchar();

//	for (i = 0; i < producerCount; i++) {
//		if (waitpid(prodIds[i], &status, 0) == -1)
//			printf("Error exiting child process");
//
//	}
//	for (i = 0; i < consumerCount; i++) {
//		if (waitpid(consIds[i], &status, 0) == -1)
//			printf("Error exiting child process");
//
//	}

	while (wait(&status) > 0)

//deallocate shared memory

		shmdt(sharedMemPtr);
//delete allocated semaphores
	semctl(semid, 0, IPC_RMID);

//printf("Deallocated Semaphore\n");

	return 0;
}
	// Sets new parameters for algorithm
	void GaMultithreadingAlgorithm::SetAlgorithmParameters(const GaAlgorithmParams& parameters)
	{
		int newCount = ( (const GaMultithreadingAlgorithmParams&)parameters ).GetNumberOfWorkers();

		// state of algorithm couldnot be changed during parameter change
		BlockStateChange();

		int oldCount = _numberOfThreads - 1;

		// nothing changed?
		if( oldCount == newCount )
		{
			// now it safe to change state of algorithm
			ReleaseStateChange();
			return;
		}

		// if algorithm is running - stop all worker threads
		if( _state == GAS_RUNNING )
		{
			_parametersChange = true;

			// release working threads
			_workersThreadOut = _workersThreadIn = oldCount;
			UnlockSemaphore( _workerForkSync, oldCount );

			// wait for working threads to be closed
			for( int i = 1; i <= oldCount; i++ )
				_threads[ i ]->Join();

			_parametersChange = false;
		}

		// remove synchronization objects
		DeleteSemaphore( _workerForkSync );
		DeleteSemaphore( _workerJoinSync );

		// make new synchronization object
		MakeSemaphore( _workerForkSync, newCount, 0 );
		MakeSemaphore( _workerJoinSync, newCount, 0 );

		// new thread pool
		GaThread** newThreads = new GaThread*[ newCount + 1 ];

		// copy old needed threads
		int lim = min( oldCount, newCount ) + 1;
		for( int i = 0; i < lim; i++ )
			newThreads[ i ] = _threads[ i ];

		if( oldCount < newCount )
		{
			// new threads should be added

			// new worker threads' parameters
			GaThreadParameter p;
			p._functionPointer = WorkFlowWrapper;
			p._functionParameters = this;

			// make new threads
			for( int i = newCount - oldCount + 1; i < newCount; i++ )
				newThreads[ i ] = new GaThread( p, false );
		}
		else
		{
			// threads should be remove

			// free old threads
			for( int i = oldCount - newCount + 1; i < oldCount; i++ )
				delete _threads[ i ];
		}

		// swap pool of threads
		delete[] _threads;
		_threads = newThreads;
		_numberOfThreads = newCount + 1;

		// restart working threads if they were running
		if( _state == GAS_RUNNING )
		{
			for( int i = 1; i <= newCount; i++ )
				_threads[ i ]->Start();
		}

		// now it safe to change state of algorithm
		ReleaseStateChange();
	}