QNX: Shmemallocator: Fix Compilation Warnings
[ipc/ipcdev.git] / qnx / src / ipc3x_dev / sharedmemallocator / resmgr / SharedMemoryAllocator.c
1 /*
2  *  @file       SharedMemoryAllocator.c
3  *
4  *  ============================================================================
5  *
6  */
7 /*
8  *  Copyright (c) 2012, Texas Instruments Incorporated
9  *
10  *  Redistribution and use in source and binary forms, with or without
11  *  modification, are permitted provided that the following conditions
12  *  are met:
13  *
14  *  *  Redistributions of source code must retain the above copyright
15  *     notice, this list of conditions and the following disclaimer.
16  *
17  *  *  Redistributions in binary form must reproduce the above copyright
18  *     notice, this list of conditions and the following disclaimer in the
19  *     documentation and/or other materials provided with the distribution.
20  *
21  *  *  Neither the name of Texas Instruments Incorporated nor the names of
22  *     its contributors may be used to endorse or promote products derived
23  *     from this software without specific prior written permission.
24  *
25  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
27  *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29  *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30  *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
32  *  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33  *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34  *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
35  *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *  Contact information for paper mail:
37  *  Texas Instruments
38  *  Post Office Box 655303
39  *  Dallas, Texas 75265
40  *  Contact information:
41  *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
42  *  DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
43  *  ============================================================================
44  *
45  */
47 #define SH_MEM_BLOCK1_START 0xBA300000
48 #define SH_MEM_BLOCK1_SIZE  0x5A00000
50 #define SH_MEM_BLOCK2_START 0x9DB00000
51 #define SH_MEM_BLOCK2_SIZE  0x1000000
53 #define SHM_PAGE_SIZE       0x1000
54 struct _iofunc_attr;
55 #define RESMGR_HANDLE_T struct _iofunc_attr
56 #define THREAD_POOL_PARAM_T dispatch_context_t
58 /*QNX specific header include */
59 #include <errno.h>
60 #include <unistd.h>
61 #include <stdio.h>
62 #include <malloc.h>
63 #include <devctl.h>
64 #include <sys/iofunc.h>
65 #include <sys/dispatch.h>
66 #include <sys/mman.h>
67 #include <sys/select.h>
68 #include <sys/procmgr.h>
69 #include <sys/slog.h>
71 /* Module headers */
72 #include <ti/shmemallocator/SharedMemoryAllocator.h>
73 #include <pthread.h>
75 /** ============================================================================
76  *  Structs
77  *  ============================================================================
78  */
79 struct sharedMemobj{
80     void *pa_shm;
81     void *va_shm;
82     int  size;
83     int  pid;
84     int blockID;
85     struct sharedMemobj *prev;
86     struct sharedMemobj *next;
87 };
88 typedef struct sharedMemobj SharedMem_Obj;
90 struct {
91     ulong addr;
92     uint len;
93 }blocks[MAX_BLOCKS_IDX+1] = {
94     {SH_MEM_BLOCK1_START, SH_MEM_BLOCK1_SIZE},
95     {SH_MEM_BLOCK2_START, SH_MEM_BLOCK2_SIZE}
96 };
98 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
100 /** ============================================================================
101  *  Globals
102  *  ============================================================================
103  */
104 static SharedMem_Obj *allocListHdr_blk[MAX_BLOCKS_IDX+1];
105 static SharedMem_Obj *freeListHdr_blk[MAX_BLOCKS_IDX+1];
106 static SharedMem_Obj *lastNode;
108 /** ============================================================================
109  *  Function prototypes
110  *  ============================================================================
111  */
112 void initSHM(void);
113 void modifyFreeList(SharedMem_Obj *node, void *dstPtr, int size);
114 void removeFromFreeList(SharedMem_Obj *node, int del);
115 void addTofreeList(SharedMem_Obj *node);
116 void addToAllocList(SharedMem_Obj *node);
118 int removeFromAllocList(SharedMem_Obj *node, int unmap);
119 int alloc_shm(int size, int blockID, uint alignment, int pid);
120 void *getVAforPID(void *dstPtr, int size, int pid);
121 int free_shm(void* argPtr, int blockID, uint pid, int unmap);
122 void checkIntegrity(int blockID);
123 void releaseSHMforPID(int pid);
125 extern void * mmap_peer(pid_t pid, void *addr, size_t len, int prot, int flags, int fd, off_t off);
126 extern int munmap_peer(pid_t pid, void *addr, size_t len);
128 /** ============================================================================
129  *  Functions
130  *  ============================================================================
131  */
133 void releaseSHMforPID(int pid)
135     pthread_mutex_lock(&lock);
137     int i;
138     SharedMem_Obj *temp;
139     void* addr;
140     int blockID;
142     for(i=0; i<=MAX_BLOCKS_IDX; i++) {
143         temp = allocListHdr_blk[i];
144         while(temp) {
145             if(temp->pid == pid) {
146                 addr = temp->va_shm;
147                 blockID = temp->blockID;
148                 temp = temp->next;
149                 free_shm(addr, blockID, pid, 0);
150             }
151             else {
152                 temp = temp->next;
153             }
154         }
155     }
156     pthread_mutex_unlock(&lock);
159 void *getVAforPID(void *dstPtr, int size, int pid)
161     void *vaPTR = mmap_peer(pid, NULL, size, PROT_NOCACHE|PROT_READ|PROT_WRITE,
162                             MAP_SHARED|MAP_PHYS,
163                             NOFD,
164                             (off_t)dstPtr);
165     if(vaPTR == MAP_FAILED){
166         slogf (42, _SLOG_DEBUG1, "Mapping VA PTR failed %p\n",vaPTR);
167     }
169     return vaPTR;
172 void initSHM(void)
174     int i;
175     for(i=0; i<=MAX_BLOCKS_IDX; i++) {
176         if(!freeListHdr_blk[i]) {
177             freeListHdr_blk[i]= malloc(sizeof(SharedMem_Obj));
178             freeListHdr_blk[i]->pa_shm = (void *)blocks[i].addr;
179             freeListHdr_blk[i]->va_shm = NULL;
180             freeListHdr_blk[i]->size = blocks[i].len;
181             freeListHdr_blk[i]->blockID = i;
182             freeListHdr_blk[i]->next = NULL;
183             freeListHdr_blk[i]->prev = NULL;
184             allocListHdr_blk[i] = NULL;
185         }
186     }
189 void deinitSHM(void)
191     int i;
192     SharedMem_Obj *temp, *temp1;
194     for(i=0; i<MAX_BLOCKS_IDX; i++) {
195         if(freeListHdr_blk[i]) {
196             temp = freeListHdr_blk[i];
197             temp1 = freeListHdr_blk[i]->next;
198             while(temp1) {
199                 free(temp);
200                 temp = temp1;
201                 temp1 = temp1->next;
202             }
203             free(temp);
204             freeListHdr_blk[i] = NULL;
205         }
206     }
207     for(i=0; i<MAX_BLOCKS_IDX; i++) {
208         if(allocListHdr_blk[i]) {
209             temp = allocListHdr_blk[i];
210             temp1 = allocListHdr_blk[i]->next;
211             while(temp1) {
212                 free(temp);
213                 temp = temp1;
214                 temp1 = temp1->next;
215             }
216             free(temp);
217             allocListHdr_blk[i] = NULL;
218         }
219     }
222 void modifyFreeList(SharedMem_Obj *node, void *dstPtr, int size)
224     SharedMem_Obj *newNode1 = NULL;
225     SharedMem_Obj *newNode2 = NULL;
227     if(dstPtr > node->pa_shm) {
228         newNode1 = malloc(sizeof(SharedMem_Obj));
229         newNode1->size = (dstPtr - node->pa_shm);
230         newNode1->pa_shm = node->pa_shm;
231         newNode1->blockID = node->blockID;
232     }
233     if((dstPtr - node->pa_shm)+size < node->size) {
234         newNode2 = malloc(sizeof(SharedMem_Obj));
235         newNode2->pa_shm = dstPtr+size;
236         newNode2->size = node->size - size - (dstPtr - node->pa_shm);
237         newNode2->blockID = node->blockID;
238     }
239     removeFromFreeList(node, 1);
240     if(newNode1)
241         addTofreeList(newNode1);
242     if(newNode2)
243         addTofreeList(newNode2);
246 void removeFromFreeList(SharedMem_Obj *node, int del)
248     if(node == freeListHdr_blk[node->blockID]) {
249         freeListHdr_blk[node->blockID] = freeListHdr_blk[node->blockID]->next;
250         if(freeListHdr_blk[node->blockID])
251             freeListHdr_blk[node->blockID]->prev = NULL;
252     } else {
253         if(node->next) {
254             node->next->prev = node->prev;
255         }
256         node->prev->next = node->next;
257     }
258     if(del)
259         free(node);
260     return;
263 void addToAllocList(SharedMem_Obj *node)
265     SharedMem_Obj *temp = allocListHdr_blk[node->blockID];
266     if(!temp) {
267         node->next = NULL;
268         node->prev = NULL;
269         allocListHdr_blk[node->blockID] = node;
270     } else {
271         while(temp->next) {
272             temp = temp->next;
273         }
274         temp->next = node;
275         node->next = NULL;
276         node->prev = temp;
277     }
278     lastNode = node;
280     return;
283 int removeFromAllocList(SharedMem_Obj *node, int unmap)
285     int status = 0;
286     if(unmap) {
287         status = munmap_peer(node->pid, node->va_shm, node->size);
288         if(status < 0) {
289             slogf (42, _SLOG_DEBUG1, "##unmapping VA for PID failed, process %u alive?\n", node->pid);
290             return -1;
291         }
292     }
293     if(node->prev) {
294        node->prev->next = node->next;
295     }
296     if(node->next) {
297         node->next->prev = node->prev;
298     }
299     if(node == allocListHdr_blk[node->blockID]) {
300         allocListHdr_blk[node->blockID] = node->next;
301         if(allocListHdr_blk[node->blockID])
302             allocListHdr_blk[node->blockID]->prev = NULL;
303     }
304     addTofreeList(node);
306     return 0;
309 void addTofreeList(SharedMem_Obj *node)
311     SharedMem_Obj* temp = freeListHdr_blk[node->blockID];
312     SharedMem_Obj* temp1 = NULL;
313     int added = 0;
315     if(!freeListHdr_blk[node->blockID]) {
316         freeListHdr_blk[node->blockID] = node;
317         freeListHdr_blk[node->blockID]->prev = NULL;
318         freeListHdr_blk[node->blockID]->next = NULL;
319         return;
320     }
321     if(node->pa_shm < freeListHdr_blk[node->blockID]->pa_shm) {
322         if((node->pa_shm + node->size) == freeListHdr_blk[node->blockID]->pa_shm) {
323             node->size = node->size + freeListHdr_blk[node->blockID]->size;
324             node->next = freeListHdr_blk[node->blockID]->next;
325             if(freeListHdr_blk[node->blockID]->next)
326                freeListHdr_blk[node->blockID]->next->prev = node;
327             free(freeListHdr_blk[node->blockID]);
328         }
329         else {
330             node->next = freeListHdr_blk[node->blockID];
331             freeListHdr_blk[node->blockID]->prev = node;
332         }
333         freeListHdr_blk[node->blockID] = node;
334         freeListHdr_blk[node->blockID]->prev = NULL;
335         return;
336     }
337     while(temp->next) {
338         if((temp->pa_shm + temp->size == node->pa_shm) && (temp->pa_shm + temp->size + node->size == temp->next->pa_shm)) {
339             temp1 = temp->next;
340             temp->size += (temp1->size + node->size);
341             temp->next = temp1->next;
342             if(temp1->next)
343                 temp1->next->prev = temp;
344             free(node);
345             free (temp1);
346             return;
347         }
349         if(node->pa_shm < temp->next->pa_shm) {
350             if(temp->pa_shm + temp->size == node->pa_shm) {
351                 added = 1;
352                 temp->size = temp->size + node->size;
353             }
354             else if(node->pa_shm + node->size == temp->next->pa_shm) {
355                 temp->next->pa_shm = node->pa_shm;
356                 temp->next->size = temp->next->size + node->size;
357                 added = 1;
358             }
359             if(added) {
360                 free(node);
361             }
362             else {
363                 temp->next->prev = node;
364                 node->next = temp->next;
365                 temp->next = node;
366                 node->prev = temp;
367             }
368             return;
369         }
370         temp = temp->next;
371     }
372     if(temp->pa_shm + temp->size == node->pa_shm) {
373         temp->size += node->size;
374         free(node);
375     }
376     else {
377         temp->next = node;
378         node->prev = temp;
379         node->next = NULL;
380     }
383 int alloc_shm(int size, int blockID, uint alignment, int pid)
385     void *phy_addr = NULL;
386     void *vir_addr = NULL;
387     SharedMem_Obj* temp = NULL;
388     SharedMem_Obj* node = NULL;
389     SharedMem_Obj* newNode = NULL;
391     if(!freeListHdr_blk[blockID]) {
392         slogf (42, _SLOG_DEBUG1, "\nalloc_shm failed:No free mem available in block{%d} !!!\n", blockID);
393         return -1;
394     }
396     temp  = freeListHdr_blk[blockID];
397     if(size%SHM_PAGE_SIZE)
398         size += (SHM_PAGE_SIZE - (size%SHM_PAGE_SIZE));
399     while (temp) {
400         if(alignment) {
401             phy_addr = (void*)(((uint)((temp->pa_shm + alignment-1))/alignment)*alignment);
402             if((phy_addr + size) == (temp->pa_shm + temp->size))
403                 break;
404             else {
405                 if((phy_addr + size) < (temp->pa_shm + temp->size)){
406                     if(!node || (node->size < temp->size)) {
407                         node = temp;
408                     }
409                 }
410                 phy_addr = NULL;
411             }
412         }
413         else if(temp->size == size) {
414             phy_addr = temp->pa_shm;
415             break;
416         }
417         else if(temp->size > size) {
418             if(!node || (node->size < temp->size)) {
419                 node = temp;
420             }
421         }
422         temp = temp->next;
423     }
424     if(phy_addr) {
425         vir_addr = getVAforPID(phy_addr, size, pid);
426         if(vir_addr == MAP_FAILED)
427             return -1;
428         removeFromFreeList(temp, 0);
429         temp->va_shm = vir_addr;
430         temp->pid = pid;
431         addToAllocList(temp);
432         return 0;
434     }
435     else if(node){
436         if(alignment)
437             phy_addr = (void*)(((uint)((node->pa_shm + alignment-1))/alignment)*alignment);
438         else
439             phy_addr = node->pa_shm;
441         vir_addr = getVAforPID(phy_addr, size, pid);
442         if(vir_addr == MAP_FAILED)
443             return -1;
444         modifyFreeList(node, phy_addr, size);
445         newNode = malloc(sizeof(SharedMem_Obj));
446         newNode->va_shm = vir_addr;
447         newNode->pa_shm = phy_addr;
448         newNode->pid = pid;
449         newNode->blockID = blockID;
450         newNode->size = size;
451         addToAllocList(newNode);
453         return 0;
454     }
455     else {
456         slogf (42, _SLOG_DEBUG1, "\nalloc_shm failed:buf of size(%d) not available !!!\n", size);
457         return -1;
458     }
461 int free_shm(void* argPtr, int blockId, uint pid, int unmap)
463     int ret = 0;
464     SharedMem_Obj* temp = allocListHdr_blk[blockId];
466     while(temp) {
467         if((temp->va_shm == argPtr) && temp->pid == pid) {
468             ret = removeFromAllocList(temp, unmap);
469             if(ret < 0)
470                 return -1;
471             break;
472         }
473         temp = temp->next;
474     }
475     if(temp == NULL)
476         ret = -1;
478     return ret;
481 void checkIntegrity(int blockID)
483     SharedMem_Obj *t_alloc = allocListHdr_blk[blockID];
484     SharedMem_Obj *t_free = freeListHdr_blk[blockID];
485     int size = blocks[blockID].len;
487     slogf (42, _SLOG_DEBUG1, "\n## checkIntegrity ##\n");
488     while(t_alloc && t_free) {
489         if(t_alloc->pa_shm > t_free->pa_shm) {
490             while(t_free && t_free->pa_shm < t_alloc->pa_shm) {
491                 slogf (42, _SLOG_DEBUG1, "## FL(0x%0x - 0x%0x)\n",
492                        (unsigned int)t_free->pa_shm,
493                        t_free->size);
495                 size -= t_free->size;
496                 t_free = t_free->next;
497             }
498         }
499         else {
500             while(t_alloc && t_alloc->pa_shm < t_free->pa_shm) {
501                 slogf (42, _SLOG_DEBUG1, "## AL(0x%0x - 0x%0x)\n",
502                        (unsigned int)t_alloc->pa_shm,
503                        t_alloc->size);
505                 size -= t_alloc->size;
506                 t_alloc = t_alloc->next;
507             }
508         }
509     }
510     while(t_alloc) {
511         slogf (42, _SLOG_DEBUG1, "## AL(0x%0x - 0x%0x)\n",
512                (unsigned int)t_alloc->pa_shm,
513                t_alloc->size);
515         size -= t_alloc->size;
516         t_alloc = t_alloc->next;
517     }
518     while(t_free) {
519         slogf (42, _SLOG_DEBUG1, "## FL(0x%0x - 0x%0x)\n",
520                (unsigned int)t_free->pa_shm,
521                t_free->size);
523         size -= t_free->size;
524         t_free = t_free->next;
525     }
526     slogf (42, _SLOG_DEBUG1, "##checkIntegrity - size = 0x%0x\n", size);
529 typedef struct shmem_ocb {
530     iofunc_ocb_t       ocb;
531     pid_t              pid;
532 } shmem_ocb_t;
534 IOFUNC_OCB_T *
535 ocb_calloc (resmgr_context_t * ctp, IOFUNC_ATTR_T * device)
537     shmem_ocb_t *ocb = NULL;
539     /* Allocate the OCB */
540     ocb = (shmem_ocb_t *) calloc (1, sizeof (shmem_ocb_t));
541     if (ocb == NULL){
542         errno = ENOMEM;
543         return (NULL);
544     }
546     ocb->pid = ctp->info.pid;
548     return (IOFUNC_OCB_T *)(ocb);
551 void
552 ocb_free (IOFUNC_OCB_T * i_ocb)
554     shmem_ocb_t * ocb = (shmem_ocb_t *)i_ocb;
556     if (ocb) {
557         releaseSHMforPID(ocb->pid);
558         free (ocb);
559     }
562 int
563 SharedMemAllDrv_devctl(resmgr_context_t * ctp, io_devctl_t * msg,
564                         iofunc_ocb_t * ocb)
566     pthread_mutex_lock(&lock);
568     int status = _RESMGR_ERRNO (EOK);
569     int dcmd = msg->i.dcmd;
570     msg->o.ret_val = EOK;
571     SHMAllocatorDrv_CmdArgs *cargs       =
572                              (SHMAllocatorDrv_CmdArgs *)(_DEVCTL_DATA (msg->i));
573     SHMAllocatorDrv_CmdArgs *output      =
574                              (SHMAllocatorDrv_CmdArgs *)(_DEVCTL_DATA (msg->o));
575     switch (dcmd)
576     {
577         case CMD_SHMALLOCATOR_ALLOC:
578         {
579             status = alloc_shm(cargs->size, cargs->blockID, cargs->alignment, ctp->info.pid);
581             if(status == -1) {
582                 output->result.blockID = -1;
583                 output->result.phy_addr = 0;
584                 output->result.vir_addr = 0;
585                 output->apiStatus = -1;
586             }
587             else {
588                 output->result.blockID = cargs->blockID;
589                 output->result.phy_addr = (unsigned long)lastNode->pa_shm;
590                 output->result.vir_addr = (unsigned long)lastNode->va_shm;
591                 output->result.size = lastNode->size;
592                 output->apiStatus = 0;
593             }
594         }
595         break;
596         case CMD_SHMALLOCATOR_RELEASE:
597         {
598             status = free_shm((void *)cargs->result.vir_addr, cargs->blockID,
599                               ctp->info.pid, 1);
600             if(status == 0) {
601                 output->apiStatus = 0;
602             }
603             else {
604                 output->apiStatus = -1;
605             }
607             break;
608         }
609         default:
610         {
611             slogf (42, _SLOG_DEBUG1, "SharedMemAllDrv_devctl: Bad request!!\n");
612             status = -1;
613         }
614         break;
615     }
616 #ifdef DEBUG_SHM
617             checkIntegrity(cargs->blockID);
618 #endif
620     pthread_mutex_unlock(&lock);
621     return (_RESMGR_PTR (ctp, &msg->o,
622                          sizeof (msg->o) + sizeof(SHMAllocatorDrv_CmdArgs)));
625 static resmgr_connect_funcs_t    connect_funcs;
626 static resmgr_io_funcs_t         io_funcs;
627 static iofunc_mount_t            mattr;
628 static iofunc_funcs_t            ocb_funcs;
629 static iofunc_attr_t             attr;
631 int
632 main(int argc, char *const argv[])
634     /* declare variables we'll be using */
635     resmgr_attr_t        resmgr_attr;
636     dispatch_t           *dpp;
637     int                  id;
638     int                  ret = 0;
639     struct stat          sbuf;
640     thread_pool_attr_t   tattr;
641     thread_pool_t        *tpool;
642     sigset_t             set;
644     /* Obtain I/O privity */
645     ret = ThreadCtl_r (_NTO_TCTL_IO, 0);
646     if (ret)
647     {
648         fprintf(stderr, "Unable to obtain I/O privity");
649         return -1;
650     }
652     /* Only let one run. */
653     if (-1 != stat("/dev/shmemallocator", &sbuf)) {
654         return -1;
655     }
657     initSHM();
659     /* initialize dispatch interface */
660     if((dpp = dispatch_create()) == NULL) {
661         fprintf(stderr,
662                 "%s: Unable to allocate dispatch handle.\n",
663                 argv[0]);
664         return -1;
665     }
667     /* Initialize the thread pool */
668     memset (&tattr, 0x00, sizeof (thread_pool_attr_t));
669     tattr.handle = dpp;
670     tattr.context_alloc = dispatch_context_alloc;
671     tattr.context_free = dispatch_context_free;
672     tattr.block_func = dispatch_block;
673     tattr.unblock_func = dispatch_unblock;
674     tattr.handler_func = dispatch_handler;
675     tattr.lo_water = 2;
676     tattr.hi_water = 8;
677     tattr.increment = 1;
678     tattr.maximum = 50;
680     /* initialize resource manager attributes */
681     memset(&resmgr_attr, 0, sizeof resmgr_attr);
682     resmgr_attr.nparts_max = 10;
683     resmgr_attr.msg_max_size = 16384;
684     memset(&mattr, 0, sizeof(iofunc_mount_t));
685     mattr.flags = 0;
686     mattr.conf = IOFUNC_PC_CHOWN_RESTRICTED | IOFUNC_PC_NO_TRUNC | IOFUNC_PC_SYNC_IO;
687     mattr.dev = 0;
688     mattr.blocksize=0;
689     mattr.funcs = &ocb_funcs;
690     memset(&ocb_funcs, 0, sizeof(iofunc_funcs_t));
691     ocb_funcs.nfuncs = _IOFUNC_NFUNCS;
692     ocb_funcs.ocb_calloc = ocb_calloc;
693     ocb_funcs.ocb_free = ocb_free;
694     memset(&io_funcs, 0, sizeof(resmgr_io_funcs_t));
695     iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs, _RESMGR_IO_NFUNCS, &io_funcs);
696     io_funcs.devctl = SharedMemAllDrv_devctl;
698     iofunc_attr_init(&attr, S_IFNAM | 0777 , 0, 0);
699     attr.mount = &mattr;
701     if ( ( tpool = thread_pool_create(&tattr,0) ) == NULL )
702         return -1;
704     if (-1 != stat("/dev/shmemallocator", &sbuf)) {
705         return -1;
706     }
708     /* attach our device name */
709     id = resmgr_attach(
710             dpp,            /* dispatch handle        */
711             &resmgr_attr,   /* resource manager attrs */
712             "/dev/shmemallocator",   /* device name            */
713             _FTYPE_ANY,     /* open type              */
714             0,              /* flags                  */
715             &connect_funcs, /* connect routines       */
716             &io_funcs,      /* I/O routines           */
717             &attr);         /* handle                 */
718     if(id == -1) {
719         fprintf(stderr, "%s: Unable to attach name.\n", argv[0]);
720         return -1;
721     }
723     /* background the process */
724     procmgr_daemon(0, PROCMGR_DAEMON_NOCLOSE|PROCMGR_DAEMON_NODEVNULL);
725     thread_pool_start( tpool );
727     /* Mask out unecessary signals */
728     sigfillset (&set);
729     sigdelset (&set, SIGINT);
730     sigdelset (&set, SIGTERM);
731     pthread_sigmask (SIG_BLOCK, &set, NULL);
733     /* Wait for one of these signals */
734     sigemptyset (&set);
735     sigaddset (&set, SIGINT);
736     sigaddset (&set, SIGQUIT);
737     sigaddset (&set, SIGTERM);
739     /* Wait for a signal */
740     while (1)
741     {
742         switch (SignalWaitinfo (&set, NULL))
743         {
744             case SIGTERM:
745             case SIGQUIT:
746             case SIGINT:
747                 goto done;
748             default:
749                 break;
750         }
751     }
753 done:
754     /* Received SIGTERM: clean up */
755     resmgr_detach(dpp, id, _RESMGR_DETACH_ALL);
757     deinitSHM();
759     return 0;