Here is my code.
package main

/*
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
static void memcpy_c(char *dest, int offs1, char *src, int offs2, int cnt) {
if (src == 0 || dest == 0) {
printf("a null ptr.\n");
return;
}
int a = 0;
long i = 0;
memcpy(dest + offs1, src+offs2, cnt);
while (1){
if (i >= cnt) {
break;
}
i++;
}
char tmp[] = "yesss";
printf("a null ptr.%d, %d,%ld,%ld\n", offs1, offs2, dest, src);
}
static void set_int32(char *addr, int offset, int num) {
int* d = (int *)(addr + 4 * offset);
*d = num;
}
static int get_int32(char *addr, int offset) {
int *d = (int *)(addr + 4 * offset);
return *d;
}
static void get_data(char *addr, int offset, int cnt) {
char tmp[cnt];
memcpy(tmp, addr+offset, cnt);
printf("get data%s", tmp);
}
*/
import "C"
import (
"fmt"
"github.com/go-ini/ini"
"math/rand"
"strconv"
"syscall"
"unsafe"
)

//memcpy(dest + offs1, tmp, 5);
//printf("%d, %d\n", *(dest + offs1+i), *(src+offs2+i));
const (
// IpcCreate create if key nonexistent
IpcCreate = 00001000
)

type MemPoolMng struct {
data_start_ptr uintptr
offs_start_ptr uintptr
offs_key       uintptr
data_key       uintptr
data_cnt       int
mem_helper     unsafe.Pointer
}

func NewMemPoolMng() *MemPoolMng {
return &MemPoolMng{}
}

func (mp_mgr *MemPoolMng) Init() bool {
cfg, err := ini.Load("./cfg.ini")
if err != nil {
return false
}

tmp_offs_key, err1 := 
strconv.Atoi(cfg.Section("mempool").Key("offs_key").String())
tmp_data_key, err2 := 
strconv.Atoi(cfg.Section("mempool").Key("data_key").String())
if err1 != nil {
return false
}
if err2 != nil {
return false
}

//get share memory from shmid.
offs_id, _, err3 := syscall.Syscall(syscall.SYS_SHMGET, 
uintptr(tmp_offs_key), 1<<32, IpcCreate|0600)
data_id, _, err4 := syscall.Syscall(syscall.SYS_SHMGET, 
uintptr(tmp_data_key), 1<<15, IpcCreate|0600)
if err3 != 0 {
return false
}
if err4 != 0 {
return false
}
mp_mgr.offs_key = offs_id
mp_mgr.data_key = data_id
mp_mgr.mem_helper = C.malloc(1 << 32)

// Share memory struct: |data_size(4)| offset1 | offset2 | offset3 |...
offs_shmaddr, _, err5 := syscall.Syscall(syscall.SYS_SHMAT, offs_id, 0, 0)
if err5 != 0 {
return false
}
defer syscall.Syscall(syscall.SYS_SHMDT, offs_shmaddr, 0, 0)
mp_mgr.data_cnt = *(*int)(unsafe.Pointer(uintptr(offs_shmaddr)))

fmt.Printf("MemPoolMng init success(%d).\n", mp_mgr.data_cnt)
return true
}

//  Save the offset of each data with a contiguous address. 
|data_cnt|0|offsset1|offset2|......|
func (mp_mgr *MemPoolMng) PutData(data *[]byte) bool {
if mp_mgr.data_cnt >= 1024 || len(*data) == 0 {
return false
}
offs_shmaddr, _, _ := syscall.Syscall(syscall.SYS_SHMAT, mp_mgr.offs_key, 
0, 0)
//data_shmaddr, _, _ := syscall.Syscall(syscall.SYS_SHMAT, mp_mgr.data_key, 
uintptr(mp_mgr.mem_helper), 0)
data_shmaddr, _, _ := syscall.Syscall(syscall.SYS_SHMAT, mp_mgr.data_key, 
0, 0)
defer syscall.Syscall(syscall.SYS_SHMDT, offs_shmaddr, 0, 0)
defer syscall.Syscall(syscall.SYS_SHMDT, data_shmaddr, 0, 0)
data_cnt := *(*int)(unsafe.Pointer(uintptr(offs_shmaddr)))
per_offs := C.get_int32((*C.char)(unsafe.Pointer(offs_shmaddr)), 
C.int(data_cnt+1))

// step 1: Put data.
//C.memcpy_c((*C.char)(mp_mgr.mem_helper), per_offs, 
(C.CString)(string(*data)), 0, C.int(len(*data)))
C.memcpy_c((*C.char)(unsafe.Pointer(data_shmaddr)), per_offs, 
(C.CString)(string(*data)), 0, C.int(len(*data)))
//C.memcpy(unsafe.Pointer(data_shmaddr+uintptr(per_offs)), 
unsafe.Pointer((C.CString)(string(*data))), C.ulong(len(*data)))
//C.memcpy(unsafe.Pointer(data_shmaddr), 
unsafe.Pointer((C.CString)(string(*data))), 48000)

// step 2: Modify offset.
cur_offs := int(per_offs) + len(*data)
C.set_int32((*C.char)(unsafe.Pointer(offs_shmaddr)), C.int(data_cnt+2), 
C.int(cur_offs))

// step 3: Modify data_cnt
data_cnt += 1
*(*int)(unsafe.Pointer(uintptr(offs_shmaddr))) = data_cnt

//C.memcpy_c((*C.char)(unsafe.Pointer(data_shmaddr)), 
(*C.char)(unsafe.Pointer(offs_shmaddr)), 4)

//for i := 0; i <= data_cnt+2; i++ {
for i := 0; i <= -1; i++ {
fmt.Printf("%d ", C.get_int32((*C.char)(unsafe.Pointer(offs_shmaddr)), 
C.int(i)))
}
for i := 0; i < 10; i++ {
// 
fmt.Println(C.get_int32((*C.char)(unsafe.Pointer(offs_shmaddr+uintptr(data_cnt-i))),
 
0))
}
return true
}

func (mp_mgr *MemPoolMng) GetData() []byte {
offs_shmaddr, _, _ := syscall.Syscall(syscall.SYS_SHMAT, mp_mgr.offs_key, 
0, 0)
syscall.Syscall(syscall.SYS_SHMAT, mp_mgr.data_key, 0, 0)
data_shmaddr, _, _ := syscall.Syscall(syscall.SYS_SHMAT, mp_mgr.data_key, 
0, 0)
//data_shmaddr, _, _ := syscall.Syscall(syscall.SYS_SHMAT, mp_mgr.data_key, 
uintptr(mp_mgr.mem_helper), 0)
data_cnt := *(*int)(unsafe.Pointer(uintptr(offs_shmaddr)))
if data_cnt == 0 {
return []byte{}
}

// Generate a probability based on the insertion time of the data. The last 
one has probability n/(1+2+...+n).
total := data_cnt * (data_cnt + 1) / 2
random := rand.Intn(total) + 1
data_i := 0
for i := 1; i <= data_cnt; i++ {
a := i * (i - 1) / 2
b := i * (i + 1) / 2
if random > a && random <= b {
data_i = i
break
}
}

per_offs := C.get_int32((*C.char)(unsafe.Pointer(uintptr(offs_shmaddr))), 
C.int(data_i))
cur_offs := C.get_int32((*C.char)(unsafe.Pointer(uintptr(offs_shmaddr))), 
C.int(data_i+1))
if cur_offs <= per_offs {
return []byte{}
}

record := C.GoBytes(unsafe.Pointer(data_shmaddr+uintptr(per_offs)), 
cur_offs-per_offs)
//record := 
C.GoBytes(unsafe.Pointer(uintptr(mp_mgr.mem_helper)+uintptr(per_offs)), 
cur_offs-per_offs)
fmt.Println(cur_offs-per_offs, len(record))
if len(record) > 10 {
return record[:10]
}
return record
}




在 2019年3月19日星期二 UTC+8上午11:51:48,Ian Lance Taylor写道:
>
> On Mon, Mar 18, 2019 at 8:17 PM <6159...@qq.com <javascript:>> wrote: 
> > 
> > shmid, _, err := syscall.Syscall(syscall.SYS_SHMGET, uintptr(10001), 
> 1<<32, IpcCreate|0600) 
> > data_shmaddr, _, _ := syscall.Syscall(syscall.SYS_SHMAT, shmid, 0, 0) 
> > C.memcpy(unsafe.Pointer(data_shmaddr+uintptr(per_offs)), 
> unsafe.Pointer((C.CString)(string(*data))), C.ulong(len(*data))) 
> > 
> > I'm trying to use syscall shmat/shmget, but it seems like i can't map 
> all the address that i wanted. 
> > 'per_offs' is a int value far less than 1<<32, below is what i got. 
> > 
> > fatal error: unexpected signal during runtime execution 
> > [signal SIGSEGV: segmentation violation code=0x1 addr=0x7fe3502cca80 
> pc=0x7fe34d9320b4] 
> > 
> > runtime stack: 
> > runtime.throw(0x552be5, 0x2a) 
> > /data1/user1/go_env/go/src/runtime/panic.go:619 +0x81 
> > runtime.sigpanic() 
> > /data1/user1/go_env/go/src/runtime/signal_unix.go:372 +0x28e 
> > 
> > goroutine 1 [syscall]: 
> > runtime.cgocall(0x4fe960, 0xc4200edd40, 0x29) 
> > /data1/user1/go_env/go/src/runtime/cgocall.go:128 +0x64 fp=0xc4200edd00 
> sp=0xc4200edcc8 pc=0x403034 
> > main._Cfunc_memcpy(0x7fe3502cca80, 0x7fe3440008c0, 0x1, 0x0) 
> > _cgo_gotypes.go:78 +0x4e fp=0xc4200edd40 sp=0xc4200edd00 pc=0x4fdb7e 
> > main.(*MemPoolMng).PutData.func1(0x7fe3502cca80, 0x7fe3440008c0, 0x1, 
> 0x1) 
> > /data1/user2/GoServer/mempool_go/mempool_mgr.go:107 +0x99 
> fp=0xc4200edd78 sp=0xc4200edd40 pc=0x4fe7a9 
> > main.(*MemPoolMng).PutData(0xc4200182d0, 0xc420158000, 0xf4240) 
> > /data1/user2/GoServer/mempool_go/mempool_mgr.go:107 +0x1da 
> fp=0xc4200ede58 sp=0xc4200edd78 pc=0x4fe37a 
> > main.handleProtoClient(0x565720, 0xc42000e060) 
> > /data1/user2/GoServer/mempool_go/server.go:58 +0x16f fp=0xc4200eded0 
> sp=0xc4200ede58 pc=0x4fcf8f 
> > main.main() 
> > /data1/user2/GoServer/mempool_go/server.go:39 +0x261 fp=0xc4200edf88 
> sp=0xc4200eded0 pc=0x4fcca1 
> > runtime.main() 
> > /data1/user1/go_env/go/src/runtime/proc.go:198 +0x212 fp=0xc4200edfe0 
> sp=0xc4200edf88 pc=0x42b772 
> > runtime.goexit() 
> > /data1/user1/go_env/go/src/runtime/asm_amd64.s:2361 +0x1 fp=0xc4200edfe8 
> sp=0xc4200edfe0 pc=0x455601 
> > exit status 2 
>
>
> 1) Always check the returned error value. 
>
> 2) Show us a complete, standalone, program. 
>
> Ian 
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to