1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
6 Project: Project independend shared buffer (linear + circular)
8 Description: Implementation of platform specific part for the
10 (Implementation for Linux KernelSpace)
14 Redistribution and use in source and binary forms, with or without
15 modification, are permitted provided that the following conditions
18 1. Redistributions of source code must retain the above copyright
19 notice, this list of conditions and the following disclaimer.
21 2. Redistributions in binary form must reproduce the above copyright
22 notice, this list of conditions and the following disclaimer in the
23 documentation and/or other materials provided with the distribution.
25 3. Neither the name of SYSTEC electronic GmbH nor the names of its
26 contributors may be used to endorse or promote products derived
27 from this software without prior written permission. For written
28 permission, please contact info@systec-electronic.com.
30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
35 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
36 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
40 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 POSSIBILITY OF SUCH DAMAGE.
45 If a provision of this License is or becomes illegal, invalid or
46 unenforceable in any jurisdiction, that shall not affect:
47 1. the validity or enforceability in that jurisdiction of any other
48 provision of this License; or
49 2. the validity or enforceability in other jurisdictions of that or
50 any other provision of this License.
52 -------------------------------------------------------------------------
54 2006/06/28 -rs: V 1.00 (initial version)
56 ****************************************************************************/
59 #include "SharedBuff.h"
61 #include "ShbLinuxKernel.h"
64 #include <linux/string.h>
65 #include <linux/module.h>
66 #include <asm/processor.h>
67 //#include <linux/vmalloc.h>
68 #include <linux/sched.h>
69 #include <linux/param.h>
70 #include <linux/spinlock.h>
71 #include <linux/wait.h>
72 #include <linux/completion.h>
74 /***************************************************************************/
77 /* G L O B A L D E F I N I T I O N S */
80 /***************************************************************************/
82 //---------------------------------------------------------------------------
84 //---------------------------------------------------------------------------
86 //---------------------------------------------------------------------------
87 // Constant definitions
88 //---------------------------------------------------------------------------
90 #define MAX_LEN_BUFFER_ID 256
92 #define TIMEOUT_ENTER_ATOMIC 1000 // (ms) for debgging: INFINITE
93 #define TIMEOUT_TERM_THREAD 1000
96 #define SBI_MAGIC_ID 0x5342492B // magic ID ("SBI+")
97 #define SBH_MAGIC_ID 0x5342482A // magic ID ("SBH*")
101 #define TABLE_SIZE 10
103 //---------------------------------------------------------------------------
105 //---------------------------------------------------------------------------
107 // This structure is the common header for the shared memory region used
108 // by all processes attached this shared memory. It includes common
109 // information to administrate/manage the shared buffer from a couple of
110 // separated processes (e.g. the refernce counter). This structure is
111 // located at the start of the shared memory region itself and exists
112 // consequently only one times per shared memory instance.
115 unsigned long m_ulShMemSize;
116 unsigned long m_ulRefCount;
118 // int m_iUserSpaceMem; //0 for userspace mem !=0 kernelspace mem
119 spinlock_t m_SpinlockBuffAccess;
122 wait_queue_head_t m_WaitQueueNewData;
123 wait_queue_head_t m_WaitQueueJobReady;
126 unsigned long m_ulOwnerProcID;
131 // This structure is the "external entry point" from a separate process
132 // to get access to a shared buffer. This structure includes all platform
133 // resp. target specific information to administrate/manage the shared
134 // buffer from a separate process. Every process attached to the shared
135 // buffer has its own runtime instance of this structure with its individual
136 // runtime data (e.g. the scope of an event handle is limitted to the
137 // owner process only). The structure member <m_pShbMemHeader> points
138 // to the (process specific) start address of the shared memory region
141 unsigned long m_SbiMagicID; // magic ID ("SBI+")
142 // void* m_pSharedMem;
143 int m_tThreadNewDataId;
144 long m_lThreadNewDataNice; // nice value of the new data thread
145 int m_tThreadJobReadyId;
146 unsigned long m_ulFlagsBuffAccess; // d.k. moved from tShbMemHeader, because each
147 // process needs to store the interrupt flags separately
148 tSigHndlrNewData m_pfnSigHndlrNewData;
149 unsigned long m_ulTimeOutJobReady;
150 tSigHndlrJobReady m_pfnSigHndlrJobReady;
151 tShbMemHeader *m_pShbMemHeader;
152 int m_iThreadTermFlag;
153 struct completion m_CompletionNewData;
155 struct semaphore *m_pSemBuffAccess;
156 struct semaphore *m_pSemNewData;
157 struct semaphore *m_pSemStopSignalingNewData;
158 struct semaphore *m_pSemJobReady;
161 unsigned long m_ulThreadIDNewData;
162 unsigned long m_ulThreadIDJobReady;
166 //---------------------------------------------------------------------------
167 // Prototypes of internal functions
168 //---------------------------------------------------------------------------
170 //tShbMemInst* ShbIpcGetShbMemInst (tShbInstance pShbInstance_p);
171 //tShbMemHeader* ShbIpcGetShbMemHeader (tShbMemInst* pShbMemInst_p);
173 //---------------------------------------------------------------------------
174 // Get pointer to process local information structure
175 //---------------------------------------------------------------------------
177 static inline tShbMemInst *ShbIpcGetShbMemInst(tShbInstance pShbInstance_p)
180 tShbMemInst *pShbMemInst;
182 pShbMemInst = (tShbMemInst *) pShbInstance_p;
184 return (pShbMemInst);
188 //---------------------------------------------------------------------------
189 // Get pointer to shared memory header
190 //---------------------------------------------------------------------------
192 static inline tShbMemHeader *ShbIpcGetShbMemHeader(tShbMemInst * pShbMemInst_p)
195 tShbMemHeader *pShbMemHeader;
197 pShbMemHeader = pShbMemInst_p->m_pShbMemHeader;
199 return (pShbMemHeader);
203 // Get pointer to process local information structure
204 //#define ShbIpcGetShbMemInst(pShbInstance_p) ((tShbMemInst*)pShbInstance_p)
206 // Get pointer to shared memory header
207 //#define ShbIpcGetShbMemHeader(pShbMemInst_p) (pShbMemInst_p->m_pShbMemHeader)
209 // not inlined internal functions
210 int ShbIpcThreadSignalNewData(void *pvThreadParam_p);
211 int ShbIpcThreadSignalJobReady(void *pvThreadParam_p);
213 //---------------------------------------------------------------------------
214 // modul globale vars
215 //---------------------------------------------------------------------------
217 struct sShbMemTable *psMemTableElementFirst_g;
219 static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p);
220 static int ShbIpcFindListElement(int iBufferId,
222 **ppsReturnMemTableElement);
223 static void ShbIpcAppendListElement(struct sShbMemTable *sNewMemTableElement);
224 static void ShbIpcDeleteListElement(int iBufferId);
225 static void ShbIpcCrc32GenTable(unsigned long aulCrcTable[256]);
226 static unsigned long ShbIpcCrc32GetCrc(const char *pcString,
227 unsigned long aulCrcTable[256]);
230 //=========================================================================//
232 // P U B L I C F U N C T I O N S //
234 //=========================================================================//
236 // not inlined external functions
238 //---------------------------------------------------------------------------
239 // Initialize IPC for Shared Buffer Module
240 //---------------------------------------------------------------------------
242 tShbError ShbIpcInit(void)
244 psMemTableElementFirst_g = NULL;
249 //---------------------------------------------------------------------------
250 // Deinitialize IPC for Shared Buffer Module
251 //---------------------------------------------------------------------------
253 tShbError ShbIpcExit(void)
260 //---------------------------------------------------------------------------
261 // Allocate Shared Buffer
262 //---------------------------------------------------------------------------
264 tShbError ShbIpcAllocBuffer(unsigned long ulBufferSize_p,
265 const char *pszBufferID_p,
266 tShbInstance * ppShbInstance_p,
267 unsigned int *pfShbNewCreated_p)
271 unsigned long ulCrc32 = 0;
272 unsigned int uiFirstProcess = 0;
273 unsigned long ulShMemSize;
274 tShbMemHeader *pShbMemHeader;
275 tShbMemInst *pShbMemInst = NULL;
276 tShbInstance pShbInstance;
277 unsigned int fShMemNewCreated = FALSE;
278 void *pSharedMem = NULL;
279 unsigned long aulCrcTable[256];
280 struct sShbMemTable *psMemTableElement;
282 DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer \n");
283 ulShMemSize = ulBufferSize_p + sizeof(tShbMemHeader);
286 ShbIpcCrc32GenTable(aulCrcTable);
287 ulCrc32 = ShbIpcCrc32GetCrc(pszBufferID_p, aulCrcTable);
290 ("ShbIpcAllocBuffer BufferSize:%d sizeof(tShb..):%d\n",
291 ulBufferSize_p, sizeof(tShbMemHeader));
292 DEBUG_LVL_29_TRACE2("ShbIpcAllocBuffer BufferId:%d MemSize:%d\n",
293 iBufferId, ulShMemSize);
294 //---------------------------------------------------------------
295 // (1) open an existing or create a new shared memory
296 //---------------------------------------------------------------
297 //test if buffer already exists
298 if (ShbIpcFindListElement(iBufferId, &psMemTableElement) == 0) {
299 //Buffer already exists
300 fShMemNewCreated = FALSE;
301 pSharedMem = psMemTableElement->m_pBuffer;
303 ("ShbIpcAllocBuffer attach Buffer at:%p Id:%d\n",
308 fShMemNewCreated = TRUE;
310 pSharedMem = kmalloc(ulShMemSize, GFP_KERNEL);
312 ("ShbIpcAllocBuffer Create New Buffer at:%p Id:%d\n",
313 pSharedMem, iBufferId);
314 if (pSharedMem == NULL) {
315 //unable to create mem
316 ShbError = kShbOutOfMem;
319 DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer create semas\n");
320 // append Element to Mem Table
322 kmalloc(sizeof(struct sShbMemTable), GFP_KERNEL);
323 psMemTableElement->m_iBufferId = iBufferId;
324 psMemTableElement->m_pBuffer = pSharedMem;
325 psMemTableElement->m_psNextMemTableElement = NULL;
326 ShbIpcAppendListElement(psMemTableElement);
329 DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer update header\n");
331 pShbMemHeader = (tShbMemHeader *) pSharedMem;
333 ("ShbIpcAllocBuffer 0 pShbMemHeader->m_ulShMemSize: %d\n",
334 pShbMemHeader->m_ulShMemSize);
335 // allocate a memory block from process specific mempool to save
336 // process local information to administrate/manage the shared buffer
337 DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer alloc private mem\n");
339 (tShbMemInst *) ShbIpcAllocPrivateMem(sizeof(tShbMemInst));
340 if (pShbMemInst == NULL) {
341 ShbError = kShbOutOfMem;
344 // reset complete header to default values
345 //pShbMemInst->m_SbiMagicID = SBI_MAGIC_ID;
346 // pShbMemInst->m_pSharedMem = pSharedMem;
347 pShbMemInst->m_tThreadNewDataId = INVALID_ID;
348 pShbMemInst->m_tThreadJobReadyId = INVALID_ID;
349 pShbMemInst->m_pfnSigHndlrNewData = NULL;
350 pShbMemInst->m_ulTimeOutJobReady = 0;
351 pShbMemInst->m_pfnSigHndlrJobReady = NULL;
352 pShbMemInst->m_pShbMemHeader = pShbMemHeader;
353 pShbMemInst->m_iThreadTermFlag = 0;
355 // initialize completion etc.
356 init_completion(&pShbMemInst->m_CompletionNewData);
359 if (fShMemNewCreated) {
360 // this process was the first who wanted to use the shared memory,
361 // so a new shared memory was created
362 // -> setup new header information inside the shared memory region
364 pShbMemHeader->m_ulShMemSize = ulShMemSize;
365 pShbMemHeader->m_ulRefCount = 1;
366 pShbMemHeader->m_iBufferId = iBufferId;
367 // initialize spinlock
368 spin_lock_init(&pShbMemHeader->m_SpinlockBuffAccess);
369 // initialize wait queues
370 init_waitqueue_head(&pShbMemHeader->m_WaitQueueNewData);
371 init_waitqueue_head(&pShbMemHeader->m_WaitQueueJobReady);
373 // any other process has created the shared memory and this
374 // process only has to attach to it
375 // -> check and update existing header information inside the
376 // shared memory region itself
377 if (pShbMemHeader->m_ulShMemSize != ulShMemSize) {
378 ShbError = kShbOpenMismatch;
381 pShbMemHeader->m_ulRefCount++;
385 pShbInstance = (tShbInstance *) pShbMemInst;
386 *pfShbNewCreated_p = fShMemNewCreated;
387 *ppShbInstance_p = pShbInstance;
392 //---------------------------------------------------------------------------
393 // Release Shared Buffer
394 //---------------------------------------------------------------------------
396 tShbError ShbIpcReleaseBuffer(tShbInstance pShbInstance_p)
398 tShbMemInst *pShbMemInst;
399 tShbMemHeader *pShbMemHeader;
403 DEBUG_LVL_26_TRACE1("ShbIpcReleaseBuffer(%p)\n", pShbInstance_p);
404 if (pShbInstance_p == NULL) {
407 pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
408 pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
410 // stop threads in any case, because they are bound to that specific instance
411 ShbError2 = ShbIpcStopSignalingNewData(pShbInstance_p);
412 // d.k.: Whats up with JobReady thread?
413 // Just wake it up, but without setting the semaphore variable
414 wake_up_interruptible(&pShbMemHeader->m_WaitQueueJobReady);
416 if (!--pShbMemHeader->m_ulRefCount) {
418 // delete mem table element
419 ShbIpcDeleteListElement(pShbMemHeader->m_iBufferId);
421 kfree(pShbMemInst->m_pShbMemHeader);
423 ShbError = kShbMemUsedByOtherProcs;
430 //---------------------------------------------------------------------------
431 // Enter atomic section for Shared Buffer access
432 //---------------------------------------------------------------------------
434 tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p)
437 tShbMemInst *pShbMemInst;
438 tShbMemHeader *pShbMemHeader;
439 tShbError ShbError = kShbOk;
441 if (pShbInstance_p == NULL) {
442 ShbError = kShbInvalidArg;
445 DEBUG_LVL_29_TRACE0("enter atomic\n");
446 pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
447 pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
450 spin_lock_irqsave(&pShbMemHeader->m_SpinlockBuffAccess,
451 pShbMemInst->m_ulFlagsBuffAccess);
458 //---------------------------------------------------------------------------
459 // Leave atomic section for Shared Buffer access
460 //---------------------------------------------------------------------------
462 tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p)
465 tShbMemInst *pShbMemInst;
466 tShbMemHeader *pShbMemHeader;
467 tShbError ShbError = kShbOk;
469 if (pShbInstance_p == NULL) {
470 ShbError = kShbInvalidArg;
473 pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
474 pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
476 spin_unlock_irqrestore(&pShbMemHeader->m_SpinlockBuffAccess,
477 pShbMemInst->m_ulFlagsBuffAccess);
480 DEBUG_LVL_29_TRACE0("Leave Atomic \n");
485 //---------------------------------------------------------------------------
486 // Start signaling of new data (called from reading process)
487 //---------------------------------------------------------------------------
489 tShbError ShbIpcStartSignalingNewData(tShbInstance pShbInstance_p,
490 tSigHndlrNewData pfnSignalHandlerNewData_p,
491 tShbPriority ShbPriority_p)
493 tShbMemInst *pShbMemInst;
494 tShbMemHeader *pShbMemHeader;
497 DEBUG_LVL_29_TRACE0("------->ShbIpcStartSignalingNewData\n");
498 if ((pShbInstance_p == NULL) || (pfnSignalHandlerNewData_p == NULL)) {
499 return (kShbInvalidArg);
502 pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
503 pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
506 if ((pShbMemInst->m_tThreadNewDataId != INVALID_ID)
507 || (pShbMemInst->m_pfnSigHndlrNewData != NULL)) {
508 ShbError = kShbAlreadySignaling;
512 ("ShbIpcStartSignalingNewData(%p) m_pfnSigHndlrNewData = %p\n",
513 pShbInstance_p, pfnSignalHandlerNewData_p);
514 pShbMemInst->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p;
515 pShbMemHeader->m_fNewData = FALSE;
516 pShbMemInst->m_iThreadTermFlag = 0;
518 switch (ShbPriority_p) {
519 case kShbPriorityLow:
520 pShbMemInst->m_lThreadNewDataNice = -2;
523 case kShbPriorityNormal:
524 pShbMemInst->m_lThreadNewDataNice = -9;
527 case kshbPriorityHigh:
528 pShbMemInst->m_lThreadNewDataNice = -20;
533 //create thread for signalling new data
534 pShbMemInst->m_tThreadNewDataId =
535 kernel_thread(ShbIpcThreadSignalNewData, pShbInstance_p,
543 //---------------------------------------------------------------------------
544 // Stop signaling of new data (called from reading process)
545 //---------------------------------------------------------------------------
547 tShbError ShbIpcStopSignalingNewData(tShbInstance pShbInstance_p)
549 tShbMemInst *pShbMemInst;
550 tShbMemHeader *pShbMemHeader;
553 DEBUG_LVL_29_TRACE0("------->ShbIpcStopSignalingNewData\n");
554 if (pShbInstance_p == NULL) {
555 return (kShbInvalidArg);
558 pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
559 pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
562 ("ShbIpcStopSignalingNewData(%p) pfnSignHndlrNewData=%p\n",
563 pShbInstance_p, pShbMemInst->m_pfnSigHndlrNewData);
564 if (pShbMemInst->m_pfnSigHndlrNewData != NULL) { // signal handler was set before
566 //set termination flag in mem header
567 pShbMemInst->m_iThreadTermFlag = 1;
569 // check if thread is still running at all by sending the null-signal to this thread
570 /* iErr = kill_proc(pShbMemInst->m_tThreadNewDataId, 0, 1); */
571 iErr = send_sig(0, pShbMemInst->m_tThreadNewDataId, 1);
573 // wake up thread, because it is still running
574 wake_up_interruptible(&pShbMemHeader->
577 //wait for termination of thread
578 wait_for_completion(&pShbMemInst->m_CompletionNewData);
581 pShbMemInst->m_pfnSigHndlrNewData = NULL;
582 pShbMemInst->m_tThreadNewDataId = INVALID_ID;
589 //---------------------------------------------------------------------------
590 // Signal new data (called from writing process)
591 //---------------------------------------------------------------------------
593 tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p)
595 tShbMemHeader *pShbMemHeader;
597 if (pShbInstance_p == NULL) {
598 return (kShbInvalidArg);
601 ShbIpcGetShbMemHeader(ShbIpcGetShbMemInst(pShbInstance_p));
603 pShbMemHeader->m_fNewData = TRUE;
604 DEBUG_LVL_29_TRACE0("ShbIpcSignalNewData set Sem -> New Data\n");
606 wake_up_interruptible(&pShbMemHeader->m_WaitQueueNewData);
610 //---------------------------------------------------------------------------
611 // Start signaling for job ready (called from waiting process)
612 //---------------------------------------------------------------------------
614 tShbError ShbIpcStartSignalingJobReady(tShbInstance pShbInstance_p,
615 unsigned long ulTimeOut_p,
616 tSigHndlrJobReady pfnSignalHandlerJobReady_p)
618 tShbMemInst *pShbMemInst;
619 tShbMemHeader *pShbMemHeader;
622 if ((pShbInstance_p == NULL) || (pfnSignalHandlerJobReady_p == NULL)) {
623 return (kShbInvalidArg);
625 pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
626 pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
629 if ((pShbMemInst->m_tThreadJobReadyId != INVALID_ID)
630 || (pShbMemInst->m_pfnSigHndlrJobReady != NULL)) {
631 ShbError = kShbAlreadySignaling;
634 pShbMemInst->m_ulTimeOutJobReady = ulTimeOut_p;
635 pShbMemInst->m_pfnSigHndlrJobReady = pfnSignalHandlerJobReady_p;
636 pShbMemHeader->m_fJobReady = FALSE;
637 //create thread for signalling new data
638 pShbMemInst->m_tThreadJobReadyId =
639 kernel_thread(ShbIpcThreadSignalJobReady, pShbInstance_p,
645 //---------------------------------------------------------------------------
646 // Signal job ready (called from executing process)
647 //---------------------------------------------------------------------------
649 tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p)
651 tShbMemHeader *pShbMemHeader;
653 DEBUG_LVL_29_TRACE0("ShbIpcSignalJobReady\n");
654 if (pShbInstance_p == NULL) {
655 return (kShbInvalidArg);
658 ShbIpcGetShbMemHeader(ShbIpcGetShbMemInst(pShbInstance_p));
660 pShbMemHeader->m_fJobReady = TRUE;
661 DEBUG_LVL_29_TRACE0("ShbIpcSignalJobReady set Sem -> Job Ready \n");
663 wake_up_interruptible(&pShbMemHeader->m_WaitQueueJobReady);
667 //---------------------------------------------------------------------------
668 // Get pointer to common used share memory area
669 //---------------------------------------------------------------------------
671 void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p)
674 tShbMemHeader *pShbMemHeader;
678 ShbIpcGetShbMemHeader(ShbIpcGetShbMemInst(pShbInstance_p));
679 if (pShbMemHeader != NULL) {
680 pShbShMemPtr = (u8 *) pShbMemHeader + sizeof(tShbMemHeader);
685 return (pShbShMemPtr);
689 //=========================================================================//
691 // P R I V A T E F U N C T I O N S //
693 //=========================================================================//
695 //---------------------------------------------------------------------------
696 // Get pointer to process local information structure
697 //---------------------------------------------------------------------------
699 /*tShbMemInst* ShbIpcGetShbMemInst (
700 tShbInstance pShbInstance_p)
703 tShbMemInst* pShbMemInst;
705 pShbMemInst = (tShbMemInst*)pShbInstance_p;
707 return (pShbMemInst);
712 //---------------------------------------------------------------------------
713 // Get pointer to shared memory header
714 //---------------------------------------------------------------------------
716 /*tShbMemHeader* ShbIpcGetShbMemHeader (
717 tShbMemInst* pShbMemInst_p)
720 tShbMemHeader* pShbMemHeader;
722 pShbMemHeader = pShbMemInst_p->m_pShbMemHeader;
724 return (pShbMemHeader);
729 //---------------------------------------------------------------------------
730 // Allocate a memory block from process specific mempool
731 //---------------------------------------------------------------------------
733 static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p)
738 DEBUG_LVL_29_TRACE0("ShbIpcAllocPrivateMem \n");
740 pMem = kmalloc(ulMemSize_p, GFP_KERNEL);
742 //unable to create mem
743 ShbError = kShbOutOfMem;
751 //---------------------------------------------------------------------------
752 // Thread for new data signaling
753 //---------------------------------------------------------------------------
755 int ShbIpcThreadSignalNewData(void *pvThreadParam_p)
757 tShbInstance pShbInstance;
758 tShbMemInst *pShbMemInst;
759 tShbMemHeader *pShbMemHeader;
763 daemonize("ShbND%p", pvThreadParam_p);
764 allow_signal(SIGTERM);
765 pShbInstance = (tShbMemInst *) pvThreadParam_p;
766 pShbMemInst = ShbIpcGetShbMemInst(pShbInstance);
767 pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
769 DEBUG_LVL_26_TRACE1("ShbIpcThreadSignalNewData(%p)\n", pvThreadParam_p);
771 set_user_nice(current, pShbMemInst->m_lThreadNewDataNice);
773 // DEBUG_LVL_29_TRACE1("ShbIpcThreadSignalNewData wait for New Data Sem %p\n",pShbMemInst->m_pSemNewData);
776 wait_event_interruptible(pShbMemHeader->m_WaitQueueNewData,
777 (pShbMemInst->m_iThreadTermFlag !=
779 || (pShbMemHeader->m_fNewData !=
782 if (iRetVal != 0) { // signal pending
786 if (pShbMemHeader->m_fNewData != FALSE) {
787 pShbMemHeader->m_fNewData = FALSE;
791 m_pfnSigHndlrNewData(pShbInstance);
792 // call scheduler, which will execute any task with higher priority
794 } while (fCallAgain != FALSE);
796 } while (pShbMemInst->m_iThreadTermFlag == 0);
797 DEBUG_LVL_29_TRACE0("ShbIpcThreadSignalNewData terminated \n");
798 //set thread completed
799 complete_and_exit(&pShbMemInst->m_CompletionNewData, 0);
803 //---------------------------------------------------------------------------
804 // Thread for new data Job Ready signaling
805 //---------------------------------------------------------------------------
807 int ShbIpcThreadSignalJobReady(void *pvThreadParam_p)
809 tShbInstance pShbInstance;
810 tShbMemInst *pShbMemInst;
811 tShbMemHeader *pShbMemHeader;
815 daemonize("ShbJR%p", pvThreadParam_p);
816 allow_signal(SIGTERM);
817 pShbInstance = (tShbMemInst *) pvThreadParam_p;
818 pShbMemInst = ShbIpcGetShbMemInst(pShbInstance);
819 pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
822 ("ShbIpcThreadSignalJobReady wait for job ready Sem\n");
823 if (pShbMemInst->m_ulTimeOutJobReady != 0) {
824 lTimeOut = (long)pShbMemInst->m_ulTimeOutJobReady;
825 //wait for job ready semaphore
827 wait_event_interruptible_timeout(pShbMemHeader->
830 m_fJobReady != FALSE),
833 //wait for job ready semaphore
835 wait_event_interruptible(pShbMemHeader->m_WaitQueueJobReady,
836 (pShbMemHeader->m_fJobReady !=
840 if (pShbMemInst->m_pfnSigHndlrJobReady != NULL) {
842 pShbMemInst->m_pfnSigHndlrJobReady(pShbInstance,
843 !pShbMemHeader->m_fJobReady);
846 pShbMemInst->m_pfnSigHndlrJobReady = NULL;
850 //Build the crc table
851 static void ShbIpcCrc32GenTable(unsigned long aulCrcTable[256])
853 unsigned long ulCrc, ulPoly;
854 int iIndexI, iIndexJ;
856 ulPoly = 0xEDB88320L;
857 for (iIndexI = 0; iIndexI < 256; iIndexI++) {
859 for (iIndexJ = 8; iIndexJ > 0; iIndexJ--) {
861 ulCrc = (ulCrc >> 1) ^ ulPoly;
866 aulCrcTable[iIndexI] = ulCrc;
870 //Calculate the crc value
871 static unsigned long ShbIpcCrc32GetCrc(const char *pcString,
872 unsigned long aulCrcTable[256])
878 for (iIndex = 0; iIndex < strlen(pcString); iIndex++) {
880 ((ulCrc >> 8) & 0x00FFFFFF) ^
881 aulCrcTable[(ulCrc ^ pcString[iIndex]) & 0xFF];
883 return (ulCrc ^ 0xFFFFFFFF);
887 static void ShbIpcAppendListElement(struct sShbMemTable *psNewMemTableElement)
889 struct sShbMemTable *psMemTableElement = psMemTableElementFirst_g;
890 psNewMemTableElement->m_psNextMemTableElement = NULL;
892 if (psMemTableElementFirst_g != NULL) { /* sind Elemente vorhanden */
893 while (psMemTableElement->m_psNextMemTableElement != NULL) { /* suche das letzte Element */
895 psMemTableElement->m_psNextMemTableElement;
897 psMemTableElement->m_psNextMemTableElement = psNewMemTableElement; /* Haenge das Element hinten an */
898 } else { /* wenn die liste leer ist, bin ich das erste Element */
899 psMemTableElementFirst_g = psNewMemTableElement;
903 static int ShbIpcFindListElement(int iBufferId,
904 struct sShbMemTable **ppsReturnMemTableElement)
906 struct sShbMemTable *psMemTableElement = psMemTableElementFirst_g;
907 while (psMemTableElement != NULL) {
908 if (psMemTableElement->m_iBufferId == iBufferId) {
909 //printk("ShbIpcFindListElement Buffer at:%p Id:%d\n",psMemTableElement->m_pBuffer,psMemTableElement->m_iBufferId);
910 *ppsReturnMemTableElement = psMemTableElement;
911 //printk("ShbIpcFindListElement Buffer at:%p Id:%d\n",(*ppsReturnMemTableElement)->m_pBuffer,(*ppsReturnMemTableElement)->m_iBufferId);
914 psMemTableElement = psMemTableElement->m_psNextMemTableElement;
919 static void ShbIpcDeleteListElement(int iBufferId)
921 struct sShbMemTable *psMemTableElement = psMemTableElementFirst_g;
922 struct sShbMemTable *psMemTableElementOld = psMemTableElementFirst_g;
923 if (psMemTableElement != NULL) {
924 while ((psMemTableElement != NULL)
925 && (psMemTableElement->m_iBufferId != iBufferId)) {
926 psMemTableElementOld = psMemTableElement;
928 psMemTableElement->m_psNextMemTableElement;
930 if (psMemTableElement != NULL) {
931 if (psMemTableElement != psMemTableElementFirst_g) {
932 psMemTableElementOld->m_psNextMemTableElement =
933 psMemTableElement->m_psNextMemTableElement;
934 kfree(psMemTableElement);
936 kfree(psMemTableElement);
937 psMemTableElementFirst_g = NULL;