/** * Creates and starts n worker thread */ WorkQueue * WKQ_CreatePool(int n) { size_t size = sizeof(WorkQueue) + sizeof(ThrID)*(MAX(n,1)-1); WorkQueue * q = MEM_Alloc(size); if (q) { ASSERT(WKQ.initcount > 0); if (WKQ.initcount == 0) WKQ_InitModule(); memset(q, 0, size); q->nthreads = n; if (MUTEX_Init(&q->mutex)) { if (EVENT_Init(&q->event)) { if (EVENT_Init(&q->stopEvent)) { if (EVENT_Reset(&q->stopEvent)) { int i; q->flags = WKQ_ACTIVE; QUEUE_Init(&q->items); QUEUE_Init(&q->submit); for (i=0; i<n; i++) { if (!THREAD_Create(q->threads+i, WKQ_Thread, q)) { WKQ_Delete(q); return NULL; } } return q; } EVENT_Destroy(&q->stopEvent); } EVENT_Destroy(&q->event); } MUTEX_Destroy(&q->mutex); } MEM_Free(q); } return NULL; }
/** * Returns a wait context from the pool, or allocates a new one */ STATIC Waiter * WKQ_GetWaiter(WorkQueueModule * module) { Waiter * waiter = NULL; ASSERT(module->initcount > 0); if (module->waitpool) { MUTEX_Lock(&module->mutex); if (module->waitpool) { waiter = module->waitpool; module->waitpool = waiter->next; waiter->next = NULL; module->nwait--; ASSERT(module->nwait >= 0); ASSERT(module->nwait || !module->waitpool); } MUTEX_Unlock(&module->mutex); } if (!waiter) { waiter = MEM_New(Waiter); if (waiter) { if (!EVENT_Init(&waiter->event)) { MEM_Free(waiter); waiter = NULL; } } } if (waiter) { EVENT_Reset(&waiter->event); } return waiter; }
/** * Allocates a new event and initializes it */ Event * EVENT_Create() { Event * e = MEM_New(Event); if (e) { if (EVENT_Init(e)) { return e; } MEM_Free(e); } return NULL; }
/** * Initialize the lock. */ Bool RWLOCK_Init(RWLock * lock) { LOCK_InitCheck(); memset(lock, 0, sizeof(*lock)); if (MUTEX_Init(&lock->mutex)) { if (EVENT_Init(&lock->shareEvent)) { if (EVENT_Init(&lock->exclusiveEvent)) { QUEUE_Init(&lock->shareWaiters); QUEUE_Init(&lock->exclusiveWaiters); QUEUE_Init(&lock->waiterCache); lock->numEntries = COUNT(lock->staticEntries); lock->lock.type = &LockType_RWLock; return True; } EVENT_Destroy(&lock->shareEvent); } MUTEX_Destroy(&lock->mutex); } return False; }
/** * Create a new thread, returning True on success */ Bool THREAD_Create(ThrID* id, ThrProc proc, void * arg) { ThrData * thr = NULL; ASSERT(THREAD_IsInited()); if (id) *id = NULL; if (!THREAD_IsInited()) return False; /* allocate thread data */ thr = MEM_New(ThrData); if (thr) { memset(thr, 0, sizeof(*thr)); if (EVENT_Init(&thr->exitEvent)) { InterlockedIncrement(&WIN32_ThreadCount); thr->signature = ThrData_Signature; thr->refCount = 2; thr->proc = proc; thr->arg = arg; /* create Win32 thread */ thr->handle = CreateThread(NULL, 0, WIN32_ThreadProc, thr, CREATE_SUSPENDED, &thr->thrid); ASSERT(thr->handle); if (thr->handle) { if (ResumeThread(thr->handle) != (DWORD)-1) { if (id) *id = thr; return True; } else { WIN32_FAILURE(ResumeThread); VERIFY(CloseHandle(thr->handle)); } } else { WIN32_FAILURE(CreateThread); } EVENT_Destroy(&thr->exitEvent); InterlockedDecrement(&WIN32_ThreadCount); } MEM_Free(thr); } return False; }
void PL_INIT(void) { #if PL_HAS_LED LED_INIT(); #endif #if PL_HAS_RTOS RTOS_Init(); #endif #if PL_HAS_EVENTS EVENT_Init(); #endif #if PL_HAS_KEYS KEY_Init(); #endif #if PL_HAS_TRIGGER TRG_Init(); #endif #if PL_HAS_DEBOUNCE DBNC_Init(); #endif #if PL_HAS_MEALY MEALY_Init(); #endif #if PL_HAS_BUZZER BUZ_Init(); #endif #if PL_HAS_SHELL SHELL_Init(); #endif }
/** * The program entry point */ int main(int argc, char * argv[]) { int mask = ECMTGW_LISTEN_DEFAULT_MASK; Bool traceReceive = False; Bool traceSend = False; Str host = NULL; Str file = NULL; CmdLine* c; GwTrace trace; XRpcRegistry * r; /* Initialize the XRPC library */ XRPC_Init(); /* First step of initializing GwTrace context */ memset(&trace, 0, sizeof(trace)); VECTOR_Init(&trace.includeUid, 0, NULL, NULL); VECTOR_Init(&trace.excludeUid, 0, NULL, NULL); /* Parse command line */ c = CMDLINE_Create(pname); if (c) { CmdOpt* includeOpt; CmdOpt* excludeOpt; Bool done = False; Bool help = False; CMDLINE_SetMaxArgs(c, 1); CMDLINE_AddTrueOpt(c,'h',"help", "print this help and exit",&help); CMDLINE_AddTrueOpt(c,'s',"sent", "trace packets sent to the handset",&traceSend); CMDLINE_AddTrueOpt(c,'r',"receive", "trace packets received from the handset",&traceReceive); includeOpt = CMDLINE_AddOpt(c,'u',"include", "include this UID in the trace (repeatable)", GWTRACE_ParseUidOpt, &trace.includeUid, "UID"); excludeOpt = CMDLINE_AddOpt(c,'x',"exclude", "exclude this UID from the trace (repeatable)", GWTRACE_ParseUidOpt, &trace.excludeUid, "UID"); CMDLINE_SetParamName(CMDLINE_AddStrOpt(c,'o',"output", "write binary Ecmt messages into a file",&file),"FILE"); CMDLINE_SetRepeatable(includeOpt); CMDLINE_SetRepeatable(excludeOpt); CMDLINE_Exclude(includeOpt, excludeOpt); if (!CMDLINE_Parse1(c,argv+1,argc-1,0,&host) || help) { CMDLINE_Usage(c, "[HOST]", 0); CMDLINE_Delete(c); VECTOR_Destroy(&trace.includeUid); VECTOR_Destroy(&trace.excludeUid); XRPC_Deinit(); return 0; } CMDLINE_Delete(c); } if (traceReceive || traceSend) { mask = 0; if (traceReceive) mask |= ECMTGW_LISTEN_MASK_RECEIVE; if (traceSend) mask |= ECMTGW_LISTEN_MASK_SEND; } /* connect to the registry */ r = XREG_ConnectRegistry(host, XREG_DEFAULT_PORT); if (r) { /* find the server port */ XRpcPort gwPort = 0; XREG_List(r, ECMTGW_PROTOCOL, GWTRACE_ListCB, &gwPort); XREG_FreeRegistry(r); if (gwPort) { if (EVENT_Init(&exitEvent)) { if (GWTRACE_Init(&trace, host, gwPort, file)) { /* Install signal handlers */ #ifndef _WIN32 signal(SIGPIPE, GWTRACE_Interrupt); #endif /* _WIN32 */ signal(SIGINT, GWTRACE_Interrupt); /* Enable notifications */ XRPC_FormatNotify(XRPC_GetClient(trace.session), ECMTGW_PROTOCOL, ECMTGW_REGISTER_LISTENER_METHOD,"%" ECMTGW_LISTENER_PROTOCOL_PARAM"!s%" ECMTGW_LISTENER_MASK_PARAM"!i", ECMTGW_LISTENER_PROTOCOL, mask); /* Wait */ EVENT_Wait(&exitEvent); /* cleanup */ XRPC_FreeSession(trace.session); XRPC_FreeServer(trace.server); if (trace.file) FILE_Close(trace.file); } EVENT_Destroy(&exitEvent); } } else { PRINT_Error("%s: Ecmt Gateway is not running.\n",pname); } } else if (host) { PRINT_Verbose("%s: XRPC registry is not running on %s\n",pname,host); PRINT_Error("%s: Ecmt Gateway is not running on %s.\n",pname,host); } else { PRINT_Verbose("%s: XRPC registry is not running\n",pname); PRINT_Error("%s: Ecmt Gateway is not running.\n",pname); } VECTOR_Destroy(&trace.includeUid); VECTOR_Destroy(&trace.excludeUid); /* Deinitialize the XRPC library */ XRPC_Deinit(); return 0; }